[Zope-Checkins] SVN: Zope/branches/tseaver-collector_1774/ Rip out the C version of 'checkPermisison' altogether

Tres Seaver tseaver at palladion.com
Thu Dec 1 17:21:58 EST 2005


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



More information about the Zope-Checkins mailing list