Log message for revision 40458: Rip out the C version of 'checkPermisison' altogether It was only about 11 microseconds faster than the Python version on my machine, and doesn't get called automagically the way 'validate' does.
Changed: U Zope/branches/tseaver-collector_1774/doc/CHANGES.txt U Zope/branches/tseaver-collector_1774/lib/python/AccessControl/ImplC.py U Zope/branches/tseaver-collector_1774/lib/python/AccessControl/cAccessControl.c U Zope/branches/tseaver-collector_1774/lib/python/AccessControl/tests/testZopeSecurityPolicy.py -=- Modified: Zope/branches/tseaver-collector_1774/doc/CHANGES.txt =================================================================== --- Zope/branches/tseaver-collector_1774/doc/CHANGES.txt 2005-12-01 19:47:51 UTC (rev 40457) +++ Zope/branches/tseaver-collector_1774/doc/CHANGES.txt 2005-12-01 22:21:57 UTC (rev 40458) @@ -26,6 +26,10 @@ Bugs Fixed + - AccessControl.ZopeSecurityPolicy: harmonize 'checkPermission' + with 'validate', checking ownership and proxy roles if an + executable object is on the stack. + - AccessControl.SecurityInfo: Fixed problem with setPermissionDefault when the permission wasn't used anywhere else in the class to protect methods. Modified: Zope/branches/tseaver-collector_1774/lib/python/AccessControl/ImplC.py =================================================================== --- Zope/branches/tseaver-collector_1774/lib/python/AccessControl/ImplC.py 2005-12-01 19:47:51 UTC (rev 40457) +++ Zope/branches/tseaver-collector_1774/lib/python/AccessControl/ImplC.py 2005-12-01 22:21:57 UTC (rev 40458) @@ -18,7 +18,8 @@ from cAccessControl import rolesForPermissionOn, \ PermissionRole, imPermissionRole, _what_not_even_god_should_do, \ RestrictedDTMLMixin, aq_validate, guarded_getattr, \ - ZopeSecurityPolicy, setDefaultBehaviors + setDefaultBehaviors + from cAccessControl import ZopeSecurityPolicy as cZopeSecurityPolicy from cAccessControl import SecurityManager as cSecurityManager except ImportError: import sys @@ -26,12 +27,17 @@ del sys.modules[__name__] -from ImplPython import RestrictedDTML, SecurityManager +from ImplPython import RestrictedDTML, SecurityManager, ZopeSecurityPolicy class RestrictedDTML(RestrictedDTMLMixin, RestrictedDTML): """A mix-in for derivatives of DT_String.String that adds Zope security.""" +class ZopeSecurityPolicy(cZopeSecurityPolicy, ZopeSecurityPolicy): + """A security manager provides methods for checking access and managing + executable context and policies + """ + class SecurityManager(cSecurityManager, SecurityManager): """A security manager provides methods for checking access and managing executable context and policies Modified: Zope/branches/tseaver-collector_1774/lib/python/AccessControl/cAccessControl.c =================================================================== --- Zope/branches/tseaver-collector_1774/lib/python/AccessControl/cAccessControl.c 2005-12-01 19:47:51 UTC (rev 40457) +++ Zope/branches/tseaver-collector_1774/lib/python/AccessControl/cAccessControl.c 2005-12-01 22:21:57 UTC (rev 40458) @@ -337,8 +337,6 @@ */ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args); -static PyObject *ZopeSecurityPolicy_checkPermission(PyObject *self, - PyObject *args); static void ZopeSecurityPolicy_dealloc(ZopeSecurityPolicy *self); @@ -418,11 +416,6 @@ METH_VARARGS, "" }, - {"checkPermission", - (PyCFunction)ZopeSecurityPolicy_checkPermission, - METH_VARARGS, - "" - }, { NULL, NULL } }; @@ -1287,215 +1280,6 @@ /* -** ZopeSecurityPolicy_checkPermission -** -*/ - -static PyObject *ZopeSecurityPolicy_checkPermission(PyObject *self, - PyObject *args) { - - /* return value */ - PyObject *result = NULL; - - /* arguments, not increfe'd */ - PyObject *permission = NULL; - PyObject *object = NULL; - PyObject *context = NULL; - - /* locals, XDECREF at exit */ - PyObject *roles = NULL; - PyObject *user = NULL; - PyObject *stack = NULL; - PyObject *eo = NULL; - PyObject *owner = NULL; - PyObject *proxy_roles = NULL; - PyObject *method = NULL; - PyObject *wrappedowner = NULL; - PyObject *objectbase = NULL; - PyObject *incontext = NULL; - - int contains = 0; - int iRole; - int length; - - /*| def checkPermission(self, permission, object, context) - */ - - if (unpacktuple3(args, "checkPermission", 3, - &permission, &object, &context) < 0) - return NULL; - - /*| roles = rolesForPermissionOn(permission, object) - */ - - roles = c_rolesForPermissionOn(permission, object, NULL, NULL); - if (roles == NULL) - return NULL; - - /*| if type(roles) in (StringType, UnicodeType): - **| roles = [roles] - */ - - if ( PyString_Check(roles) || PyUnicode_Check(roles) ) { - PyObject *role_list; - - role_list = PyList_New(1); - if (role_list == NULL) goto cP_done; - /* Note: ref to roles is passed to the list object. */ - PyList_SET_ITEM(role_list, 0, roles); - roles = role_list; - } - - - /*| # Check executable security - **| stack = context.stack - **| if stack: - */ - - stack = PyObject_GetAttr(context, stack_str); - if (stack == NULL) goto cP_done; - - if (PyObject_IsTrue(stack)) { - - /*| eo = stack[-1] - **| # If the executable had an owner, can it execute? - **| owner = eo.getOwner() - **| if (owner is not None) and not owner.allowed(object, roles) - **| # We don't want someone to acquire if they can't - **| # get an unacquired! - **| return 0 - */ - - eo = PySequence_GetItem(stack, -1); - if (eo == NULL) goto cP_done; - - if (ownerous) { - owner = PyObject_GetAttr(eo, getOwner_str); - if (owner) ASSIGN(owner, PyObject_CallObject(owner, NULL)); - if (owner == NULL) goto cP_done; - - if (owner != Py_None) { - ASSIGN(owner, PyObject_GetAttr(owner, allowed_str)); - if (owner) ASSIGN(owner, callfunction2(owner, object, roles)); - if (owner == NULL) goto cP_done; - - if (! PyObject_IsTrue(owner)) { - result = PyInt_FromLong(0); - goto cP_done; - } - } - } - - /*| # Proxy roles, which are a lot safer now - **| proxy_roles = getattr(eo, "_proxy_roles", None) - **| if proxy_roles: - **| # Verify that the owner actually can state the proxy role - **| # in the context of the accessed item; users in subfolders - **| # should not be able to use proxy roles to access items - **| # above their subfolder! - **| owner = eo.getWrappedOwner() - **| if owner is not None: - **| if object is not aq_base(object): - **| if not owner._check_context(object): - **| # object is higher up than the owner, - **| # deny access - **| return 0 - **| - **| for r in proxy_roles: - **| if r in roles: - **| return 1 - **| return 0 - */ - proxy_roles = PyObject_GetAttr(eo, _proxy_roles_str); - - if (proxy_roles == NULL) { - PyErr_Clear(); - goto cP_check_user; - } - - if (PyObject_IsTrue(proxy_roles)) { - method = PyObject_GetAttr(eo, getWrappedOwner_str); - if (method == NULL) goto cP_done; - - wrappedowner = PyObject_CallObject(method, NULL); - if (wrappedowner == NULL) goto cP_done; - - if (wrappedowner != Py_None) { - objectbase = aq_base(object); - - if (object != objectbase) { - - incontext = callmethod1(wrappedowner, - _check_context_str, object); - if (incontext == NULL) goto cP_done; - - if ( ! PyObject_IsTrue(incontext)) { - ASSIGN(result, PyInt_FromLong(0)); - goto cP_done; - } - } - } - } - - if (PyTuple_Check(proxy_roles)) { - PyObject *proxy_role; - length = PyTuple_GET_SIZE(proxy_roles); - for (iRole=0; iRole < length; iRole++) { - proxy_role = PyTuple_GET_ITEM(proxy_roles, iRole); - /* proxy_role is not increfed */ - if ((contains = PySequence_Contains(roles, proxy_role))) - break; - } - } else { - PyObject *proxy_role; - length = PySequence_Size(proxy_roles); - if (length < 0) goto cP_done; - for (iRole=0; contains == 0 && iRole < length; iRole++) { - proxy_role = PySequence_GetItem(proxy_roles, iRole); - if (proxy_role == NULL) goto cP_done; - /* proxy_role is increfed */ - contains = PySequence_Contains(roles, proxy_role); - Py_DECREF(proxy_role); - } - } - - /* If we have proxy roles, and they don't match, then lose - * (don't even check user roles at that point) - */ - if (contains < 0) contains = 0; - ASSIGN(result, PyInt_FromLong(contains)); - goto cP_done; - } /* End of stack check */ - -cP_check_user: - - /*| return context.user.allowed(object, roles) - */ - user = PyObject_GetAttr(context, user_str); - if (user != NULL) { - ASSIGN(user, PyObject_GetAttr(user, allowed_str)); - if (user != NULL) { - result = callfunction2(user, object, roles); - if (result == NULL) goto cP_done; - } - } - -cP_done: - Py_XDECREF(roles); - Py_XDECREF(user); - Py_XDECREF(stack); - Py_XDECREF(eo); - Py_XDECREF(owner); - Py_XDECREF(proxy_roles); - Py_XDECREF(method); - Py_XDECREF(wrappedowner); - Py_XDECREF(objectbase); - Py_XDECREF(incontext); - - return result; -} - -/* ** ZopeSecurityPolicy_dealloc ** */ Modified: Zope/branches/tseaver-collector_1774/lib/python/AccessControl/tests/testZopeSecurityPolicy.py =================================================================== --- Zope/branches/tseaver-collector_1774/lib/python/AccessControl/tests/testZopeSecurityPolicy.py 2005-12-01 19:47:51 UTC (rev 40457) +++ Zope/branches/tseaver-collector_1774/lib/python/AccessControl/tests/testZopeSecurityPolicy.py 2005-12-01 22:21:57 UTC (rev 40458) @@ -415,7 +415,7 @@ return ZopeSecurityPolicy class C_ZSPTests(ZopeSecurityPolicyTestBase, - # ISecurityPolicyConformance, #XXX C version, how? + ISecurityPolicyConformance, ): def _getTargetClass(self): from AccessControl.ImplC import ZopeSecurityPolicy _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins