From 9c3db613842212aa1d1e5d85cb9cdfffa31ef085 Mon Sep 17 00:00:00 2001 From: Iustin Pop Date: Wed, 3 Mar 2010 00:33:52 +0100 Subject: [PATCH] Imported Upstream version 0.5.0 --- Makefile | 8 +- NEWS | 5 + PKG-INFO | 4 +- README | 6 +- acl.c | 174 ++++++++++++++------ pylibacl.egg-info/PKG-INFO | 4 +- pylibacl.egg-info/SOURCES.txt | 3 +- setup.py | 6 +- test/test_acls.py | 289 ---------------------------------- 9 files changed, 151 insertions(+), 348 deletions(-) delete mode 100644 test/test_acls.py diff --git a/Makefile b/Makefile index 354046f..20029f4 100644 --- a/Makefile +++ b/Makefile @@ -14,5 +14,9 @@ doc: posix1e.so posix1e test: - python2.4 ./setup.py test - python2.5 ./setup.py test + for ver in 2.4 2.5 2.6 3.0 3.1; do \ + if type python$$ver >/dev/null; then \ + echo Testing with python$$ver; \ + python$$ver ./setup.py test; \ + fi; \ + done diff --git a/NEWS b/NEWS index e018bbd..b14b96c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Version 0.5 +=========== + +Added support for Python 3.x and improved support for Unicode filenames. + Version 0.4 =========== diff --git a/PKG-INFO b/PKG-INFO index 0bf4e63..4ba298e 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,8 +1,8 @@ Metadata-Version: 1.0 Name: pylibacl -Version: 0.4.0 +Version: 0.5.0 Summary: POSIX.1e ACLs for python -Home-page: http://pylibacl.sourceforge.net +Home-page: http://pylibacl.sourceforge.net/ Author: Iustin Pop Author-email: iusty@k1024.org License: LGPL diff --git a/README b/README index 992ad2b..7bba91e 100644 --- a/README +++ b/README @@ -13,11 +13,11 @@ A few internal details are in the file IMPLEMENTATION. License ------- +pylibacl is Copyright (C) 2002-2009 Iustin Pop. + pylibacl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any -later version. - -See the COPYING file for the full license terms. +later version. See the COPYING file for the full license terms. Iustin Pop, diff --git a/acl.c b/acl.c index d22af08..d8bbee5 100644 --- a/acl.c +++ b/acl.c @@ -1,7 +1,7 @@ /* posix1e - a python module exposing the posix acl functions - Copyright (C) 2002-2008 Iustin Pop + Copyright (C) 2002-2009 Iustin Pop This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -32,7 +32,34 @@ #define get_perm acl_get_perm_np #endif -staticforward PyTypeObject ACL_Type; +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#define PyInt_Check(op) PyLong_Check(op) +#define PyInt_FromString PyLong_FromString +#define PyInt_FromUnicode PyLong_FromUnicode +#define PyInt_FromLong PyLong_FromLong +#define PyInt_FromSize_t PyLong_FromSize_t +#define PyInt_FromSsize_t PyLong_FromSsize_t +#define PyInt_AsLong PyLong_AsLong +#define PyInt_AsSsize_t PyLong_AsSsize_t +#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask +#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask +#define PyInt_AS_LONG PyLong_AS_LONG +#else +#define PyBytes_Check PyString_Check +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_FromString PyString_FromString +#define PyBytes_FromFormat PyString_FromFormat +#define PyBytes_ConcatAndDel PyString_ConcatAndDel + +/* Python 2.6 already defines Py_TYPE */ +#ifndef Py_TYPE +#define Py_TYPE(o) (((PyObject*)(o))->ob_type) +#endif +#endif + +static PyTypeObject ACL_Type; static PyObject* ACL_applyto(PyObject* obj, PyObject* args); static PyObject* ACL_valid(PyObject* obj, PyObject* args); @@ -42,8 +69,8 @@ static PyObject* ACL_set_state(PyObject *obj, PyObject* args); #endif #ifdef HAVE_LEVEL2 -staticforward PyTypeObject Entry_Type; -staticforward PyTypeObject Permset_Type; +static PyTypeObject Entry_Type; +static PyTypeObject Permset_Type; static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds); #endif @@ -99,11 +126,11 @@ static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) { #ifdef HAVE_LINUX static char *kwlist[] = { "file", "fd", "text", "acl", "filedef", "mode", NULL }; - char *format = "|sisO!sH"; + char *format = "|etisO!sH"; mode_t mode = 0; #else static char *kwlist[] = { "file", "fd", "text", "acl", "filedef", NULL }; - char *format = "|sisO!s"; + char *format = "|etisO!s"; #endif char *file = NULL; char *filedef = NULL; @@ -118,7 +145,7 @@ static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) { return -1; } if(!PyArg_ParseTupleAndKeywords(args, keywds, format, kwlist, - &file, &fd, &text, &ACL_Type, + NULL, &file, &fd, &text, &ACL_Type, &thesrc, &filedef #ifdef HAVE_LINUX , &mode @@ -181,7 +208,7 @@ static PyObject* ACL_str(PyObject *obj) { if(text == NULL) { return PyErr_SetFromErrno(PyExc_IOError); } - ret = PyString_FromString(text); + ret = PyBytes_FromString(text); if(acl_free(text) != 0) { Py_DECREF(ret); return PyErr_SetFromErrno(PyExc_IOError); @@ -235,7 +262,7 @@ static PyObject* ACL_to_any_text(PyObject *obj, PyObject *args, if(text == NULL) { return PyErr_SetFromErrno(PyExc_IOError); } - ret = PyString_FromString(text); + ret = PyBytes_FromString(text); if(acl_free(text) != 0) { Py_DECREF(ret); return PyErr_SetFromErrno(PyExc_IOError); @@ -361,9 +388,18 @@ static PyObject* ACL_applyto(PyObject* obj, PyObject* args) { if (!PyArg_ParseTuple(args, "O|i", &myarg, &type)) return NULL; - if(PyString_Check(myarg)) { - char *filename = PyString_AS_STRING(myarg); + if(PyBytes_Check(myarg)) { + char *filename = PyBytes_AS_STRING(myarg); nret = acl_set_file(filename, type, self->acl); + } else if (PyUnicode_Check(myarg)) { + PyObject *o = + PyUnicode_AsEncodedString(myarg, + Py_FileSystemDefaultEncoding, "strict"); + if (o == NULL) + return NULL; + const char *filename = PyBytes_AS_STRING(o); + nret = acl_set_file(filename, type, self->acl); + Py_DECREF(o); } else if((fd = PyObject_AsFileDescriptor(myarg)) != -1) { nret = acl_set_fd(fd, self->acl); } else { @@ -429,9 +465,9 @@ static PyObject* ACL_get_state(PyObject *obj, PyObject* args) { if(size == -1) return PyErr_SetFromErrno(PyExc_IOError); - if((ret = PyString_FromStringAndSize(NULL, size)) == NULL) + if((ret = PyBytes_FromStringAndSize(NULL, size)) == NULL) return NULL; - buf = PyString_AsString(ret); + buf = PyBytes_AsString(ret); if((nsize = acl_copy_ext(buf, self->acl, size)) == -1) { Py_DECREF(ret); @@ -666,8 +702,7 @@ static PyObject* Entry_str(PyObject *obj) { acl_tag_t tag; uid_t qualifier; void *p; - PyObject *ret; - PyObject *format, *list; + PyObject *format, *kind; Entry_Object *self = (Entry_Object*) obj; if(acl_get_tag_type(self->entry, &tag) == -1) { @@ -685,33 +720,31 @@ static PyObject* Entry_str(PyObject *obj) { qualifier = 0; } - format = PyString_FromString("ACL entry for %s"); + format = PyBytes_FromString("ACL entry for "); if(format == NULL) return NULL; - list = PyTuple_New(1); if(tag == ACL_UNDEFINED_TAG) { - PyTuple_SetItem(list, 0, PyString_FromString("undefined type")); + kind = PyBytes_FromString("undefined type"); } else if(tag == ACL_USER_OBJ) { - PyTuple_SetItem(list, 0, PyString_FromString("the owner")); + kind = PyBytes_FromString("the owner"); } else if(tag == ACL_GROUP_OBJ) { - PyTuple_SetItem(list, 0, PyString_FromString("the group")); + kind = PyBytes_FromString("the group"); } else if(tag == ACL_OTHER) { - PyTuple_SetItem(list, 0, PyString_FromString("the others")); + kind = PyBytes_FromString("the others"); } else if(tag == ACL_USER) { - PyTuple_SetItem(list, 0, PyString_FromFormat("user with uid %d", - qualifier)); + kind = PyBytes_FromFormat("user with uid %d", qualifier); } else if(tag == ACL_GROUP) { - PyTuple_SetItem(list, 0, PyString_FromFormat("group with gid %d", - qualifier)); + kind = PyBytes_FromFormat("group with gid %d", qualifier); } else if(tag == ACL_MASK) { - PyTuple_SetItem(list, 0, PyString_FromString("the mask")); + kind = PyBytes_FromString("the mask"); } else { - PyTuple_SetItem(list, 0, PyString_FromString("UNKNOWN_TAG_TYPE!")); + kind = PyBytes_FromString("UNKNOWN_TAG_TYPE!"); } - ret = PyString_Format(format, list); + if (kind == NULL) + return NULL; + PyBytes_ConcatAndDel(&format, kind); Py_DECREF(format); - Py_DECREF(list); - return ret; + return format; } /* Sets the tag type of the entry */ @@ -934,7 +967,7 @@ static PyObject* Permset_str(PyObject *obj) { pstr[0] = get_perm(self->permset, ACL_READ) ? 'r' : '-'; pstr[1] = get_perm(self->permset, ACL_WRITE) ? 'w' : '-'; pstr[2] = get_perm(self->permset, ACL_EXECUTE) ? 'x' : '-'; - return PyString_FromStringAndSize(pstr, 3); + return PyBytes_FromStringAndSize(pstr, 3); } static char __Permset_clear_doc__[] = @@ -1132,8 +1165,12 @@ static PyMethodDef ACL_methods[] = { /* The definition of the ACL Type */ static PyTypeObject ACL_Type = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) +#else PyObject_HEAD_INIT(NULL) 0, +#endif "posix1e.ACL", sizeof(ACL_Object), 0, @@ -1249,8 +1286,12 @@ static char __Entry_Type_doc__[] = ; /* The definition of the Entry Type */ static PyTypeObject Entry_Type = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) +#else PyObject_HEAD_INIT(NULL) 0, +#endif "posix1e.Entry", sizeof(Entry_Object), 0, @@ -1354,8 +1395,12 @@ static char __Permset_Type_doc__[] = /* The definition of the Permset Type */ static PyTypeObject Permset_Type = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) +#else PyObject_HEAD_INIT(NULL) 0, +#endif "posix1e.Permset", sizeof(Permset_Object), 0, @@ -1415,7 +1460,7 @@ static PyObject* aclmodule_delete_default(PyObject* obj, PyObject* args) { char *filename; /* Parse the arguments */ - if (!PyArg_ParseTuple(args, "s", &filename)) + if (!PyArg_ParseTuple(args, "et", NULL, &filename)) return NULL; if(acl_delete_def_file(filename) == -1) { @@ -1445,9 +1490,18 @@ static PyObject* aclmodule_has_extended(PyObject* obj, PyObject* args) { if (!PyArg_ParseTuple(args, "O", &myarg)) return NULL; - if(PyString_Check(myarg)) { - const char *filename = PyString_AS_STRING(myarg); + if(PyBytes_Check(myarg)) { + const char *filename = PyBytes_AS_STRING(myarg); nret = acl_extended_file(filename); + } else if (PyUnicode_Check(myarg)) { + PyObject *o = + PyUnicode_AsEncodedString(myarg, + Py_FileSystemDefaultEncoding, "strict"); + if (o == NULL) + return NULL; + const char *filename = PyBytes_AS_STRING(o); + nret = acl_extended_file(filename); + Py_DECREF(o); } else if((fd = PyObject_AsFileDescriptor(myarg)) != -1) { nret = acl_extended_fd(fd); } else { @@ -1523,33 +1577,59 @@ static char __posix1e_doc__[] = "\n" ; -void initposix1e(void) { +#ifdef IS_PY3K + +static struct PyModuleDef posix1emodule = { + PyModuleDef_HEAD_INIT, + "posix1e", + __posix1e_doc__, + 0, + aclmodule_methods, +}; + +#define INITERROR return NULL + +PyMODINIT_FUNC +PyInit_posix1e(void) + +#else +#define INITERROR return + +void initposix1e(void) +#endif +{ PyObject *m, *d; - ACL_Type.ob_type = &PyType_Type; + Py_TYPE(&ACL_Type) = &PyType_Type; if(PyType_Ready(&ACL_Type) < 0) - return; + INITERROR; #ifdef HAVE_LEVEL2 - Entry_Type.ob_type = &PyType_Type; + Py_TYPE(&Entry_Type) = &PyType_Type; if(PyType_Ready(&Entry_Type) < 0) - return; + INITERROR; - Permset_Type.ob_type = &PyType_Type; + Py_TYPE(&Permset_Type) = &PyType_Type; if(PyType_Ready(&Permset_Type) < 0) - return; + INITERROR; #endif +#ifdef IS_PY3K + m = PyModule_Create(&posix1emodule); +#else m = Py_InitModule3("posix1e", aclmodule_methods, __posix1e_doc__); +#endif + if (m==NULL) + INITERROR; d = PyModule_GetDict(m); if (d == NULL) - return; + INITERROR; Py_INCREF(&ACL_Type); if (PyDict_SetItemString(d, "ACL", (PyObject *) &ACL_Type) < 0) - return; + INITERROR; /* 23.3.6 acl_type_t values */ PyModule_AddIntConstant(m, "ACL_TYPE_ACCESS", ACL_TYPE_ACCESS); @@ -1560,12 +1640,12 @@ void initposix1e(void) { Py_INCREF(&Entry_Type); if (PyDict_SetItemString(d, "Entry", (PyObject *) &Entry_Type) < 0) - return; + INITERROR; Py_INCREF(&Permset_Type); if (PyDict_SetItemString(d, "Permset", (PyObject *) &Permset_Type) < 0) - return; + INITERROR; /* 23.2.2 acl_perm_t values */ PyModule_AddIntConstant(m, "ACL_READ", ACL_READ); @@ -1612,4 +1692,8 @@ void initposix1e(void) { PyModule_AddIntConstant(m, "HAS_EXTENDED_CHECK", 0); PyModule_AddIntConstant(m, "HAS_EQUIV_MODE", 0); #endif + +#ifdef IS_PY3K + return m; +#endif } diff --git a/pylibacl.egg-info/PKG-INFO b/pylibacl.egg-info/PKG-INFO index 0bf4e63..4ba298e 100644 --- a/pylibacl.egg-info/PKG-INFO +++ b/pylibacl.egg-info/PKG-INFO @@ -1,8 +1,8 @@ Metadata-Version: 1.0 Name: pylibacl -Version: 0.4.0 +Version: 0.5.0 Summary: POSIX.1e ACLs for python -Home-page: http://pylibacl.sourceforge.net +Home-page: http://pylibacl.sourceforge.net/ Author: Iustin Pop Author-email: iusty@k1024.org License: LGPL diff --git a/pylibacl.egg-info/SOURCES.txt b/pylibacl.egg-info/SOURCES.txt index f2bca42..7d46ac4 100644 --- a/pylibacl.egg-info/SOURCES.txt +++ b/pylibacl.egg-info/SOURCES.txt @@ -11,5 +11,4 @@ setup.py pylibacl.egg-info/PKG-INFO pylibacl.egg-info/SOURCES.txt pylibacl.egg-info/dependency_links.txt -pylibacl.egg-info/top_level.txt -test/test_acls.py \ No newline at end of file +pylibacl.egg-info/top_level.txt \ No newline at end of file diff --git a/setup.py b/setup.py index e3c895b..8cf37a2 100755 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ long_desc = """This is a C extension module for Python which implements POSIX ACLs manipulation. It is a wrapper on top of the systems's acl C library - see acl(5).""" -version = "0.4.0" +version = "0.5.0" setup(name="pylibacl", version=version, @@ -38,11 +38,11 @@ setup(name="pylibacl", long_description=long_desc, author="Iustin Pop", author_email="iusty@k1024.org", - url="http://pylibacl.sourceforge.net", + url="http://pylibacl.sourceforge.net/", license="LGPL", ext_modules=[Extension("posix1e", ["acl.c"], libraries=libs, define_macros=macros, )], - test_suite="test/test_acls", + test_suite="tests", ) diff --git a/test/test_acls.py b/test/test_acls.py deleted file mode 100644 index 68cd432..0000000 --- a/test/test_acls.py +++ /dev/null @@ -1,289 +0,0 @@ -# -# - -"""Unittests for the posix1e module""" - -# Copyright (C) 2002-2008 Iustin Pop -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 USA - - -import unittest -import os -import tempfile - -import posix1e -from posix1e import * - -TEST_DIR = os.environ.get("TESTDIR", ".") - -BASIC_ACL_TEXT = "u::rw,g::r,o::-" - -def _skip_test(fn): - """Wrapper to skip a test""" - new_fn = lambda x: None - new_fn.__doc__ = "SKIPPED %s" % fn.__doc__ - return new_fn - - -def has_ext(extension): - """Decorator to skip tests based on platform support""" - if not extension: - return _skip_test - else: - return lambda x: x - - -class aclTest: - """Support functions ACLs""" - - def setUp(self): - """set up function""" - self.rmfiles = [] - self.rmdirs = [] - - def tearDown(self): - """tear down function""" - for fname in self.rmfiles: - os.unlink(fname) - for dname in self.rmdirs: - os.rmdir(dname) - - def _getfile(self): - """create a temp file""" - fh, fname = tempfile.mkstemp(".test", "xattr-", TEST_DIR) - self.rmfiles.append(fname) - return fh, fname - - def _getdir(self): - """create a temp dir""" - dname = tempfile.mkdtemp(".test", "xattr-", TEST_DIR) - self.rmdirs.append(dname) - return dname - - def _getsymlink(self): - """create a symlink""" - fh, fname = self._getfile() - os.close(fh) - os.unlink(fname) - os.symlink(fname + ".non-existent", fname) - return fname - - -class LoadTests(aclTest, unittest.TestCase): - """Load/create tests""" - def testFromFile(self): - """Test loading ACLs from a file""" - _, fname = self._getfile() - acl1 = posix1e.ACL(file=fname) - self.failUnless(acl1.valid(), "ACL read from file should be valid") - - def testFromDir(self): - """Test loading ACLs from a directory""" - dname = self._getdir() - acl1 = posix1e.ACL(file=dname) - acl2 = posix1e.ACL(filedef=dname) - self.failUnless(acl1.valid(), - "ACL read from directory should be valid") - # default ACLs might or might not be valid; missing ones are - # not valid, so we don't test acl2 for validity - - def testFromFd(self): - """Test loading ACLs from a file descriptor""" - fd, _ = self._getfile() - acl1 = posix1e.ACL(fd=fd) - self.failUnless(acl1.valid(), "ACL read from fd should be valid") - - def testFromEmpty(self): - """Test creating an empty ACL""" - acl1 = posix1e.ACL() - self.failIf(acl1.valid(), "Empty ACL should not be valid") - - def testFromText(self): - """Test creating an ACL from text""" - acl1 = posix1e.ACL(text=BASIC_ACL_TEXT) - self.failUnless(acl1.valid(), - "ACL based on standard description should be valid") - -class AclExtensions(aclTest, unittest.TestCase): - """ACL extensions checks""" - - @has_ext(HAS_ACL_FROM_MODE) - def testFromMode(self): - """Test loading ACLs from an octal mode""" - acl1 = posix1e.ACL(mode=0644) - self.failUnless(acl1.valid(), - "ACL created via octal mode shoule be valid") - - @has_ext(HAS_ACL_CHECK) - def testAclCheck(self): - """Test the acl_check method""" - acl1 = posix1e.ACL(text=BASIC_ACL_TEXT) - self.failIf(acl1.check(), "ACL is not valid") - acl2 = posix1e.ACL() - self.failUnless(acl2.check(), "Empty ACL should not be valid") - - @has_ext(HAS_EXTENDED_CHECK) - def testExtended(self): - """Test the acl_extended function""" - fd, fname = self._getfile() - basic_acl = posix1e.ACL(text=BASIC_ACL_TEXT) - basic_acl.applyto(fd) - for item in fd, fname: - self.failIf(has_extended(item), - "A simple ACL should not be reported as extended") - enhanced_acl = posix1e.ACL(text="u::rw,g::-,o::-,u:root:rw,mask::r") - self.failUnless(enhanced_acl.valid(), - "Failure to build an extended ACL") - enhanced_acl.applyto(fd) - for item in fd, fname: - self.failUnless(has_extended(item), - "An extended ACL should be reported as such") - - @has_ext(HAS_EQUIV_MODE) - def testEquivMode(self): - """Test the equiv_mode function""" - if HAS_ACL_FROM_MODE: - for mode in 0644, 0755: - acl = posix1e.ACL(mode=mode) - self.failUnlessEqual(acl.equiv_mode(), mode) - acl = posix1e.ACL(text="u::rw,g::r,o::r") - self.failUnlessEqual(acl.equiv_mode(), 0644) - acl = posix1e.ACL(text="u::rx,g::-,o::-") - self.failUnlessEqual(acl.equiv_mode(), 0500) - - -class WriteTests(aclTest, unittest.TestCase): - """Write tests""" - - def testDeleteDefault(self): - """Test removing the default ACL""" - dname = self._getdir() - posix1e.delete_default(dname) - - def testReapply(self): - """Test re-applying an ACL""" - fd, fname = self._getfile() - acl1 = posix1e.ACL(fd=fd) - acl1.applyto(fd) - acl1.applyto(fname) - dname = self._getdir() - acl2 = posix1e.ACL(file=fname) - acl2.applyto(dname) - - -class ModificationTests(aclTest, unittest.TestCase): - """ACL modification tests""" - - @has_ext(HAS_ACL_ENTRY) - def testAppend(self): - """Test append a new Entry to the ACL""" - acl = posix1e.ACL() - e = acl.append() - e.tag_type = posix1e.ACL_OTHER - acl.calc_mask() - - @has_ext(HAS_ACL_ENTRY) - def testDelete(self): - """Test delete Entry from the ACL""" - acl = posix1e.ACL() - e = acl.append() - e.tag_type = posix1e.ACL_OTHER - acl.calc_mask() - acl.delete_entry(e) - acl.calc_mask() - - @has_ext(HAS_ACL_ENTRY) - def testDoubleEntries(self): - """Test double entries""" - acl = posix1e.ACL(text=BASIC_ACL_TEXT) - self.failUnless(acl.valid(), "ACL is not valid") - for tag_type in (posix1e.ACL_USER_OBJ, posix1e.ACL_GROUP_OBJ, - posix1e.ACL_OTHER): - e = acl.append() - e.tag_type = tag_type - e.permset.clear() - self.failIf(acl.valid(), - "ACL containing duplicate entries should not be valid") - acl.delete_entry(e) - - @has_ext(HAS_ACL_ENTRY) - def testMultipleGoodEntries(self): - """Test multiple valid entries""" - acl = posix1e.ACL(text=BASIC_ACL_TEXT) - self.failUnless(acl.valid(), "ACL is not valid") - for tag_type in (posix1e.ACL_USER, - posix1e.ACL_GROUP): - for obj_id in range(5): - e = acl.append() - e.tag_type = tag_type - e.qualifier = obj_id - e.permset.clear() - acl.calc_mask() - self.failUnless(acl.valid(), - "ACL should be able to hold multiple" - " user/group entries") - - @has_ext(HAS_ACL_ENTRY) - def testMultipleBadEntries(self): - """Test multiple invalid entries""" - acl = posix1e.ACL(text=BASIC_ACL_TEXT) - self.failUnless(acl.valid(), "ACL built from standard description" - " should be valid") - for tag_type in (posix1e.ACL_USER, - posix1e.ACL_GROUP): - e1 = acl.append() - e1.tag_type = tag_type - e1.qualifier = 0 - e1.permset.clear() - acl.calc_mask() - self.failUnless(acl.valid(), "ACL should be able to add a" - " user/group entry") - e2 = acl.append() - e2.tag_type = tag_type - e2.qualifier = 0 - e2.permset.clear() - acl.calc_mask() - self.failIf(acl.valid(), "ACL should not validate when" - " containing two duplicate entries") - acl.delete_entry(e1) - acl.delete_entry(e2) - - @has_ext(HAS_ACL_ENTRY) - def testPermset(self): - """Test permissions""" - acl = posix1e.ACL() - e = acl.append() - ps = e.permset - ps.clear() - pmap = { - posix1e.ACL_READ: "read", - posix1e.ACL_WRITE: "write", - posix1e.ACL_EXECUTE: "execute", - } - for perm in pmap: - self.failIf(ps.test(perm), "Empty permission set should not" - " have permission '%s'" % pmap[perm]) - ps.add(perm) - self.failUnless(ps.test(perm), "Permission '%s' should exist" - " after addition" % pmap[perm]) - ps.delete(perm) - self.failIf(ps.test(perm), "Permission '%s' should not exist" - " after deletion" % pmap[perm]) - - -if __name__ == "__main__": - unittest.main() -- 2.39.2