[Zope3-checkins] CVS: Zope3/src/zope/app - context.py:1.6

Steve Alexander steve@cat-box.net
Mon, 2 Jun 2003 13:43:33 -0400


Update of /cvs-repository/Zope3/src/zope/app
In directory cvs.zope.org:/tmp/cvs-serv10642/src/zope/app

Modified Files:
	context.py 
Log Message:
Implemented descriptor for __Security_checker__ of context wrappers.
This descriptor gets a checker for the wrapper and for the proxied object,
and returns a checker combined from both of those.
If either the wrapper or the proxied object has no checker defined, then
the checker for the proxied object or the wrapper is returned,
respectively.
If no checkers are defined, None is returned.


=== Zope3/src/zope/app/context.py 1.5 => 1.6 ===
--- Zope3/src/zope/app/context.py:1.5	Mon Jun  2 12:55:46 2003
+++ Zope3/src/zope/app/context.py	Mon Jun  2 13:43:02 2003
@@ -29,11 +29,13 @@
 from zope.interface.declarations import ObjectSpecificationDescriptor
 from zope.interface import moduleProvides, implements, providedBy
 from zope.proxy import queryProxy, getProxiedObject
-from zope.security.checker import defineChecker, selectChecker, BasicTypes
 from zope.security.proxy import Proxy, getChecker
+from zope.security.checker import defineChecker, BasicTypes
+from zope.security.checker import selectChecker, CombinedChecker, NoProxy
 
 moduleProvides(IContextWrapper)
 __all__ = tuple(IContextWrapper)
+__metaclass__ = type
 
 class DecoratorSpecificationDescriptor(ObjectSpecificationDescriptor):
     """Support for interface declarations on decorators
@@ -75,11 +77,8 @@
 
     >>> [interface.__name__ for interface in list(providedBy(D2(D1(x))))]
     ['I4', 'I3', 'I1', 'I2']
-
-    $Id$
     """
-
-    def __get__(self, inst, cls):
+    def __get__(self, inst, cls=None):
         if inst is None:
             return getObjectSpecification(cls)
         else:
@@ -89,7 +88,27 @@
             # will return the proxied object's class.
             cls = type(inst) 
             return ObjectSpecification(provided, cls)
-        
+
+
+class DecoratedSecurityCheckerDescriptor:
+    """Descriptor for a Wrapper that provides a decorated security checker.
+    """
+    def __get__(self, inst, cls=None):
+        if inst is None:
+            return self
+        else:
+            proxied_object = getProxiedObject(inst)
+            checker = getattr(proxied_object, '__Security_checker__', None)
+            if checker is None:
+                checker = selectChecker(proxied_object)
+            wrapper_checker = selectChecker(inst)
+            if wrapper_checker is None:
+                return checker
+            elif checker is None:
+                return wrapper_checker
+            else:
+                return CombinedChecker(wrapper_checker, checker)
+
 
 class Wrapper(BaseWrapper):
     """Zope-specific context wrapper
@@ -102,9 +121,11 @@
 
     __providedBy__ = DecoratorSpecificationDescriptor()
 
+    __Security_checker__ = DecoratedSecurityCheckerDescriptor()
+
 
 def ContextWrapper(_ob, _parent, **kw):
-    
+
     if type(_ob) in BasicTypes:
         # Don't wrap basic objects
         return _ob
@@ -131,10 +152,7 @@
 
     return _ob
 
-# XXX Do I actually need these?
-def _contextWrapperChecker(ob):
-    return selectChecker(getProxiedObject(ob))
-defineChecker(Wrapper, _contextWrapperChecker)
+defineChecker(Wrapper, NoProxy)
 
 def getItem(collection, name):
     return ContextWrapper(collection[name], collection, name=name)