[Zope-Checkins] CVS: Zope/lib/python/AccessControl - DTML.py:1.7.44.1 SecurityManagement.py:1.4.32.1 SecurityManager.py:1.6.18.2 ZopeGuards.py:1.6.28.2 ZopeSecurityPolicy.py:1.12.30.5 cAccessControl.c:1.10.12.7

Jim Fulton jim@zope.com
Fri, 19 Oct 2001 15:05:09 -0400


Update of /cvs-repository/Zope/lib/python/AccessControl
In directory cvs.zope.org:/tmp/cvs-serv8146

Modified Files:
      Tag: cAccessControl-review-branch
	DTML.py SecurityManagement.py SecurityManager.py ZopeGuards.py 
	ZopeSecurityPolicy.py cAccessControl.c 
Log Message:
Rewrote frequntly-called routines:

- guarded_getattr and aq_validate in ZopeGuards

- validation and check routines in SecurityManager

- guarded_getattr in the DTML mixin

in C to get better performance.

Also converted PyArg_ParseTuple calls to use more basic tuple
unpacking to get a measurable (~4%) improvement.


=== Zope/lib/python/AccessControl/DTML.py 1.7 => 1.7.44.1 ===
 import DocumentTemplate.sequence
 
-from ZopeGuards import guarded_getattr, guarded_getitem, _marker
+from ZopeGuards import guarded_getattr, guarded_getitem
 
 class RestrictedDTML:
     '''
     A mix-in for derivatives of DT_String.String that adds Zope security.
     '''
-    def guarded_getattr(self, ob, name, default=_marker):
-        return guarded_getattr(ob, name, default)
+    def guarded_getattr(self, *args): # ob, name [, default]
+        return guarded_getattr(*args)
 
     def guarded_getitem(self, ob, index):
         return guarded_getitem(ob, index)
 
+
+try:
+    #raise ImportError
+    import os
+    if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
+        raise ImportError # :)
+    from cAccessControl import RestrictedDTMLMixin
+except ImportError:
+    pass
+else:
+
+    class RestrictedDTML(RestrictedDTMLMixin, RestrictedDTML):
+        '''
+        A mix-in for derivatives of DT_String.String that adds Zope security.
+        '''
+    
 
 # Allow access to unprotected attributes
 DT_Util.TemplateDict.__allow_access_to_unprotected_subobjects__=1


=== Zope/lib/python/AccessControl/SecurityManagement.py 1.4 => 1.4.32.1 ===
 __version__='$Revision$'[11:-2]
 
+def getSecurityManager():
+    """Get a security manager, for the current thread.
+    """
+    thread_id=get_ident()
+    manager=_managers.get(thread_id, None)
+    if manager is None:
+        manager=SecurityManager(
+            thread_id,
+            SecurityContext(SpecialUsers.nobody))
+        _managers[thread_id]=manager
+        
+    return manager
+
 import SpecialUsers
 from SecurityManager import SecurityManager
 try:    import thread
@@ -109,19 +122,6 @@
     try: del _managers[get_ident()]
     except: pass
     
-
-def getSecurityManager():
-    """Get a security manager, for the current thread.
-    """
-    thread_id=get_ident()
-    manager=_managers.get(thread_id, None)
-    if manager is None:
-        manager=SecurityManager(
-            thread_id,
-            SecurityContext(SpecialUsers.nobody))
-        _managers[thread_id]=manager
-        
-    return manager
 
 def setSecurityPolicy(aSecurityPolicy):
     """Set the system default security policy. 


=== Zope/lib/python/AccessControl/SecurityManager.py 1.6.18.1 => 1.6.18.2 ===
     return last
 
+
 class SecurityManager:
     """A security manager provides methods for checking access and managing
     executable context and policies
@@ -116,35 +117,34 @@
         'validate': 1, 'validateValue': 1, 'checkPermission': 1,
         'getUser': 1, 'calledByExecutable': 1
         }
-    
+
     def __init__(self, thread_id, context):
         self._thread_id=thread_id
         self._context=context
-        self._policy=None
+        self._policy=_defaultPolicy
 
     def validate(self, accessed=None, container=None, name=None, value=None,
                  roles=_noroles):
         """Validate access.
 
         Arguments:
-        
+
         accessed -- the object that was being accessed
-        
+
         container -- the object the value was found in
-        
+
         name -- The name used to access the value
-        
+
         value -- The value retrieved though the access.
 
         roles -- The roles of the object if already known.
-        
+
         The arguments may be provided as keyword arguments. Some of these
         arguments may be ommitted, however, the policy may reject access
         in some cases when arguments are ommitted.  It is best to provide
         all the values possible.
         """
         policy=self._policy
-        if policy is None: policy=_defaultPolicy
         if roles is _noroles:
             return policy.validate(accessed, container, name, value,
                                    self._context)
@@ -153,19 +153,19 @@
                                    self._context, roles)
 
     def DTMLValidate(self, accessed=None, container=None, name=None,
-                    value=None,md=None):
+                    value=None, md=None):
 
         """Validate access.
         * THIS EXISTS FOR DTML COMPATIBILITY *
 
         Arguments:
-        
+
         accessed -- the object that was being accessed
-        
+
         container -- the object the value was found in
-        
+
         name -- The name used to access the value
-        
+
         value -- The value retrieved though the access.
 
         md -- multidict for DTML (ignored)
@@ -177,7 +177,6 @@
 
         """
         policy=self._policy
-        if policy is None: policy=_defaultPolicy
         return policy.validate(accessed, container, name, value,
                                self._context)
 
@@ -185,7 +184,6 @@
         """Convenience for common case of simple value validation.
         """
         policy=self._policy
-        if policy is None: policy=_defaultPolicy
         if roles is _noroles:
             return policy.validate(None, None, None, value,
                                    self._context)
@@ -198,13 +196,12 @@
         the given object.
 
         Arguments:
-        
+
         permission -- A permission name
-        
+
         object -- The object being accessed according to the permission
         """
         policy=self._policy
-        if policy is None: policy=_defaultPolicy
         return policy.checkPermission(permission, object,
                                       self._context)
 
@@ -218,7 +215,10 @@
             raise SystemError, 'Excessive recursion'
         stack.append(anExecutableObject)
         p=getattr(anExecutableObject, '_customSecurityPolicy', None)
-        if p is not None: p=p()
+        if p is not None:
+            p=p()
+        else:
+            p=_defaultPolicy
         self._policy=p
 
     def removeContext(self, anExecutableObject,
@@ -245,10 +245,13 @@
         if stack:
             top=stack[-1]
             p=getattr(top, '_customSecurityPolicy', None)
-            if p is not None: p=p()
+            if p is not None:
+                p=p()
+            else:
+                p=_defaultPolicy
             self._policy=p
         else:
-            self._policy=None
+            self._policy=_defaultPolicy
 
     def getUser(self):
         """Get the current authenticated user"""
@@ -260,3 +263,17 @@
         return len(self._context.stack)
 
 
+try:
+    #raise ImportError
+    import os
+    if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
+        raise ImportError # :)
+    from cAccessControl import SecurityManager as cSecurityManager
+except ImportError:
+    pass
+else:
+
+    class SecurityManager(cSecurityManager, SecurityManager):
+        """A security manager provides methods for checking access and managing
+        executable context and policies
+        """


=== Zope/lib/python/AccessControl/ZopeGuards.py 1.6.28.1 => 1.6.28.2 ===
 safe_builtins.update(utility_builtins)
 
-def aq_validate(inst, obj, name, v, validate):
-    return validate(inst, obj, name, v)
+try:
+
+    #raise ImportError
+    import os
+    if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
+        raise ImportError # :)
+    from cAccessControl import aq_validate, guarded_getattr
+
+except ImportError:
+
+    def aq_validate(inst, obj, name, v, validate):
+        return validate(inst, obj, name, v)
+
+
+    def guarded_getattr(inst, name, default=_marker):
+        if name[:1] != '_':
+            # Try to get the attribute normally so that unusual
+            # exceptions are caught early.
+            try: v = getattr(inst, name)
+            except AttributeError:
+                if default is not _marker:
+                    return default
+                raise
+            if Containers(type(inst)):
+                # Simple type.  Short circuit.
+                return v
+            validate = getSecurityManager().validate
+            # Filter out the objects we can't access.
+            if hasattr(inst, 'aq_acquire'):
+                return inst.aq_acquire(name, aq_validate, validate)
+            # Or just try to get the attribute directly.
+            if validate(inst, inst, name, v):
+                return v
+        raise Unauthorized, name
 
-def guarded_getattr(inst, name, default=_marker):
-    if name[:1] != '_':
-        # Try to get the attribute normally so that unusual
-        # exceptions are caught early.
-        try: v = getattr(inst, name)
-        except AttributeError:
-            if default is not _marker:
-                return default
-            raise
-        if Containers(type(inst)):
-            # Simple type.  Short circuit.
-            return v
-        validate = getSecurityManager().validate
-        # Filter out the objects we can't access.
-        if hasattr(inst, 'aq_acquire'):
-            return inst.aq_acquire(name, aq_validate, validate)
-        # Or just try to get the attribute directly.
-        if validate(inst, inst, name, v):
-            return v
-    raise Unauthorized, name
 safe_builtins['getattr'] = guarded_getattr
 
 def guarded_hasattr(object, name):


=== Zope/lib/python/AccessControl/ZopeSecurityPolicy.py 1.12.30.4 => 1.12.30.5 ===
     class ZopeSecurityPolicy:
 
-        def __init__(self, ownerous=1):
+        def __init__(self, ownerous=1, authenticated=1):
+            """Create a Zope security policy.
+
+            Two optional keyword arguments may be provided:
+
+            ownerous -- Untrusted users can create code
+                        (e.g. Python scripts or templates),
+                        so check that code owners can access resources.
+                        The argument must have a truth value.
+                        The default is true.
+
+            authenticated -- Allow access to resources based on the
+                        privaledges of the authenticated user.  
+                        The argument must have a truth value.
+                        The default is true.
+
+                        This (somewhat experimental) option can be set
+                        to false on sites that allow only public
+                        (unauthenticated) access. An anticipated
+                        scenario is a ZEO configuration in which some
+                        clients allow only public access and other
+                        clients allow full management.
+            """
+            
             self._ownerous=ownerous
+            self._public=pulic
 
         def validate(self, accessed, container, name, value, context,
                      roles=_noroles, None=None, type=type, IntType=type(0),


=== Zope/lib/python/AccessControl/cAccessControl.c 1.10.12.6 => 1.10.12.7 === (756/856 lines abridged)
 
 static PyObject *
-callmethod1(PyObject *self, PyObject *name, PyObject *arg)
+callfunction1(PyObject *function, PyObject *arg)
 {
-  UNLESS(self = PyObject_GetAttr(self,name)) return NULL;
-  name = PyTuple_New(1);
-  if (name == NULL) {
-    Py_DECREF(self);
+  PyObject *t, *r;
+  t = PyTuple_New(1);
+  if (t == NULL)
     return NULL;
-  }
   Py_INCREF(arg);
-  PyTuple_SET_ITEM(name, 0, arg);
-  ASSIGN(self, PyObject_CallObject(self, name));
-  Py_DECREF(name);
+  PyTuple_SET_ITEM(t, 0, arg);
+  r = PyObject_CallObject(function, t);
+  Py_DECREF(t);
+  return r;
+}
+
+static PyObject *
+callmethod1(PyObject *self, PyObject *name, PyObject *arg)
+{
+  UNLESS(self = PyObject_GetAttr(self,name)) return NULL;
+  ASSIGN(self, callfunction1(self, arg));
   return self;
 }
 
@@ -97,6 +103,198 @@
   return r;
 }
 
+static PyObject *
+callfunction3(PyObject *function, 
+              PyObject *arg0, PyObject *arg1, 
+              PyObject *arg2
+              )
+{
+  PyObject *t, *r;
+  t = PyTuple_New(3);
+  if (t == NULL)
+    return NULL;
+  Py_INCREF(arg0);
+  Py_INCREF(arg1);
+  Py_INCREF(arg2);
+  PyTuple_SET_ITEM(t, 0, arg0);

[-=- -=- -=- 756 lines omitted -=- -=- -=-]

-		OBJECT(&PermissionRoleType));
-
-	imPermissionRoleType.ob_type = &PyType_Type;
-	PyDict_SetItemString(dict, "imPermissionRoleType", 
-		OBJECT(&imPermissionRoleType));
-
 	PyDict_SetItemString(dict, "__version__",
 		PyString_FromStringAndSize(rev+11,strlen(rev+11)-2));
 
 	PyDict_SetItemString(dict, "_what_not_even_god_should_do",
 		_what_not_even_god_should_do);
 
+        PyExtensionClass_Export(dict, "RestrictedDTMLMixin",
+                                RestrictedDTMLMixinType);
+
 	PyExtensionClass_Export(dict, "ZopeSecurityPolicy",
 		ZopeSecurityPolicyType);
 
+        PyExtensionClass_Export(dict,"SecurityManager",
+                SecurityManagerType);
+
 	PyExtensionClass_Export(dict, "PermissionRole",
 		PermissionRoleType);
 
 	PyExtensionClass_Export(dict, "imPermissionRole",
 		imPermissionRoleType);
 
- 	imPermissionRoleObj = PyDict_GetItemString(dict, "imPermissionRole");
+ 	imPermissionRoleObj = PyMapping_GetItemString(dict, 
+                                                      "imPermissionRole");
+
+        aq_validate = PyMapping_GetItemString(dict, "aq_validate");
 
 	/*| from SimpleObjectPolicies import Containers
 	*/
@@ -1504,6 +2128,14 @@
 
 	IMPORT(module, "AccessControl.unauthorized");
 	GETATTR(module, Unauthorized);
+	Py_DECREF(module);
+	module = NULL;
+
+	/*| from AccessControl.SecurityManagement import getSecurityManager
+	*/
+
+	IMPORT(module, "AccessControl.SecurityManagement");
+	GETATTR(module, getSecurityManager);
 	Py_DECREF(module);
 	module = NULL;