[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security - IExecutableObject.py:1.1.2.3 ISecurityManager.py:1.1.2.4 SecurityManager.py:1.1.2.4

Tres Seaver tseaver@zope.com
Fri, 30 Nov 2001 22:39:59 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/Security
In directory cvs.zope.org:/tmp/cvs-serv30342

Modified Files:
      Tag: Zope-3x-branch
	IExecutableObject.py ISecurityManager.py SecurityManager.py 
Log Message:


  - Clean up docstrings on 'IExecutableObject' and
    'IExecutableObjectWithCustomSecurityPolicy', including note that both
    are "pseudo" interfaces (no objects will actually assert them).

  - Rename '[I]SecurityManger.addContext' -> 'pushExecutable', and
    'removeContext' -> 'popExecutable', to avoid name clash with the
    SecurityContext objects used by security policies (also makes the
    stacked nature more explicit).

  - Added tests for 'SecurityManager.pushExecutable' and 'popExecutable'.

  - Ensured that all SecurityManger tests restore security policy, if
    munged.


=== Zope3/lib/python/Zope/App/Security/IExecutableObject.py 1.1.2.2 => 1.1.2.3 ===
 class IExecutableObject( Interface ):
     """
+        (pseudo interface)
+
         An executable object is an object that executes logic provided
         through the web (TTW).  Examples of executable objects include
-        DTML methods and documents, SQL methods, Wiki pages, and,
-        someday, TTW Python methods.
+        DTML methods and documents, SQL methods, Wiki pages, Python
+        Scripts, and Page Templates.
 
         It is likely that SecurityPolicy objects will expect executable
         objects to provide certain interfaces. These interfaces
         may, in fact, turn out to be policy dependent.
-
-        An executable object may provide its own security policy by
-        defining the method:
     """
 
 class IExecutableObjectWithCustomSecurityPolicy( IExecutableObject ):
+    """
+        (pseudo interface)
+
+        An executable object may provide its own security policy by
+        defining the following method:
+    """
 
     def _customSecurityPolicy():
         """
-            Return a custom SecurityPolicy.
-
-            This should rarely, if ever, be needed.
+            Return a custom ISecurityPolicy implementation.
         """
 


=== Zope3/lib/python/Zope/App/Security/ISecurityManager.py 1.1.2.3 => 1.1.2.4 ===
         executable context and policies.
     """
+    def getUser():
+        """
+            Return the authenticated user. 
+
+            This is equivalent to something like::
+
+            REQUEST['AUTHENTICATED_USER']
+
+            but is a bit cleaner, especially if 'REQUEST' isn't handy.
+        """
+
     def validate( name, value ):
         """
             Validate access, raising Unauthorized if not allowed..
@@ -45,46 +56,24 @@
             object -- The object being accessed according to the permission
         """
 
-    def addContext( anExecutableObject ):
-        """
-            Add an ExecutableObject to the current security
-            context.
-
-            There is no return.
+    def pushExecutable( anExecutableObject ):
         """
-
-    def removeContext( anExecutableObject ):
+            Push an ExecutableObject onto the manager's stack, and
+            activate it's custom security policy, if any.
         """
-            Remove an ExecutableObject.
 
-            There is no return.
+    def popExecutable( anExecutableObject ):
         """
-
-    def getUser():
-        """
-            Return the authenticated user. 
-
-            This is equivalent to something like::
-
-            REQUEST['AUTHENTICATED_USER']
-
-            but is a bit cleaner, especially if 'REQUEST' isn't handy.
+            Pop the topmost ExecutableObject from the stack, deactivating
+            any custom security policy it might have installed.
         """
 
     def calledByExecutable():
         """
-            Determine if called through an ExecutableObject.
-
-            A true value is returned if any ExecutableObjects 
-            have (directly or indirectly) called the current method and
-            a true value otherwise.
+            Return a boolean indicating whether the current request has
+            invoked any IExecutableObjects.
 
             This can be used to determine if an object was called 
             (more or less) directly from a URL, or if it was called by
             through-the-web provided code.
-
-            (The value returned by the initial implementation
-            is actually size of the context stack, which is the depth
-            of the through-the-web call stack.  Is this information
-            valuable enough to promise in the interface?)     
         """


=== Zope3/lib/python/Zope/App/Security/SecurityManager.py 1.1.2.3 => 1.1.2.4 ===
 from Zope.Exceptions import Unauthorized
 
-max_stack_size = 100
+MAX_STACK_SIZE = 100
 
 class DefaultSecurityPolicy:
     """
@@ -68,6 +68,18 @@
     #
     #   ISecurityManager implementation
     #
+    def getUser( self ):
+        """
+            Return the authenticated user. 
+
+            This is equivalent to something like::
+
+            REQUEST['AUTHENTICATED_USER']
+
+            but is a bit cleaner, especially if 'REQUEST' isn't handy.
+        """
+        return self._context.user
+
     def validate( self, name, value ):
         """
             Validate access.
@@ -107,16 +119,14 @@
         return self._getPolicy().checkPermission( permission, object
                                               , self._context )
 
-    def addContext( self, anExecutableObject ):
+    def pushExecutable( self, anExecutableObject ):
         """
-            Add an ExecutableObject to the current security
-            context.
-
-            There is no return.
+            Push an ExecutableObject onto the manager's stack, and
+            activate it's custom security policy, if any.
         """
         stack=self._context.stack
 
-        if len( stack ) > max_stack_size:
+        if len( stack ) >= MAX_STACK_SIZE:
             raise SystemError, 'Excessive recursion'
 
         stack.append( anExecutableObject )
@@ -124,13 +134,13 @@
 
         if p is not None:
             p = p()
+
         self._policy = p
 
-    def removeContext( self, anExecutableObject ):
+    def popExecutable( self, anExecutableObject ):
         """
-            Remove an ExecutableObject.
-
-            There is no return.
+            Pop the topmost ExecutableObject from the stack, deactivating
+            any custom security policy it might have installed.
         """
         stack=self._context.stack
 
@@ -164,34 +174,14 @@
         else:
             self._policy=None
 
-    def getUser( self ):
-        """
-            Return the authenticated user. 
-
-            This is equivalent to something like::
-
-            REQUEST['AUTHENTICATED_USER']
-
-            but is a bit cleaner, especially if 'REQUEST' isn't handy.
-        """
-        return self._context.user
-
     def calledByExecutable( self ):
         """
-            Determine if called through an ExecutableObject.
-
-            A true value is returned if any ExecutableObjects 
-            have (directly or indirectly) called the current method and
-            a true value otherwise.
+            Return a boolean indicating whether the current request has
+            invoked any IExecutableObjects.
 
             This can be used to determine if an object was called 
             (more or less) directly from a URL, or if it was called by
             through-the-web provided code.
-
-            (The value returned by the initial implementation
-            is actually size of the context stack, which is the depth
-            of the through-the-web call stack.  Is this information
-            valuable enough to promise in the interface?)     
         """
         return len( self._context.stack )