[Zope-Checkins] SVN: Zope/branches/2.10/lib/python/OFS/ Fixed refactored traversal on bound methods of classes with no default

Florent Guillaume fg at nuxeo.com
Wed Jul 5 12:53:21 EDT 2006


Log message for revision 68980:
  Fixed refactored traversal on bound methods of classes with no default
  access.
  

Changed:
  U   Zope/branches/2.10/lib/python/OFS/Traversable.py
  U   Zope/branches/2.10/lib/python/OFS/tests/testTraverse.py

-=-
Modified: Zope/branches/2.10/lib/python/OFS/Traversable.py
===================================================================
--- Zope/branches/2.10/lib/python/OFS/Traversable.py	2006-07-05 16:13:42 UTC (rev 68979)
+++ Zope/branches/2.10/lib/python/OFS/Traversable.py	2006-07-05 16:53:20 UTC (rev 68980)
@@ -237,11 +237,11 @@
                             if not validated:
                                 raise Unauthorized, name
                     else:
-                        if hasattr(aq_base(obj), name):
+                        if getattr(aq_base(obj), name, marker) is not marker:
                             if restricted:
-                                next = guarded_getattr(obj, name, marker)
+                                next = guarded_getattr(obj, name)
                             else:
-                                next = _getattr(obj, name, marker)
+                                next = _getattr(obj, name)
                         else:
                             try:
                                 next=obj[name]
@@ -249,6 +249,9 @@
                                 # Raise NotFound for easier debugging
                                 # instead of AttributeError: __getitem__
                                 raise NotFound, name
+                            if restricted and not securityManager.validate(
+                                obj, obj, _none, next):
+                                raise Unauthorized, name
 
                 except (AttributeError, NotFound, KeyError), e: 
                     # Try to look for a view
@@ -270,13 +273,10 @@
                                 next = _getattr(obj, name, marker)
                         except AttributeError:
                             raise e
-                    if next is marker:
-                        # Nothing found re-raise error
-                        raise e
-                
-                if restricted and not securityManager.validate(
-                    obj, obj, _none, next):
-                    raise Unauthorized, name
+                        if next is marker:
+                            # Nothing found re-raise error
+                            raise e
+
                 obj = next
 
             return obj

Modified: Zope/branches/2.10/lib/python/OFS/tests/testTraverse.py
===================================================================
--- Zope/branches/2.10/lib/python/OFS/tests/testTraverse.py	2006-07-05 16:13:42 UTC (rev 68979)
+++ Zope/branches/2.10/lib/python/OFS/tests/testTraverse.py	2006-07-05 16:53:20 UTC (rev 68980)
@@ -68,6 +68,24 @@
         return 0
 
 
+class ProtectedMethodSecurityPolicy:
+    """Check security strictly on bound methods.
+    """
+    def validate(self, accessed, container, name, value, *args):
+        if getattr(aq_base(value), 'im_self', None) is None:
+            return 1
+
+        # Bound method
+        if name is None:
+            raise Unauthorized
+        klass = value.im_self.__class__
+        roles = getattr(klass, name+'__roles__', object())
+        if roles is None: # ACCESS_PUBLIC
+            return 1
+
+        raise Unauthorized(name)
+
+
 class UnitTestUser( Acquisition.Implicit ):
     """
         Stubbed out manager for unit testing purposes.
@@ -103,6 +121,22 @@
     bb_status = 'screechy'
 
 
+class Restricted(SimpleItem):
+    """Instance we'll check with ProtectedMethodSecurityPolicy
+    """
+    getId__roles__ = None # ACCESS_PUBLIC
+    def getId(self):
+        return self.id
+
+    private__roles__ = () # ACCESS_PRIVATE
+    def private(self):
+        return 'private!'
+
+    # not protected
+    def ohno(self):
+        return 'ohno!'
+
+
 class BoboTraversableWithAcquisition(SimpleItem):
     """
        A BoboTraversable class which may use acquisition to find objects.
@@ -210,6 +244,17 @@
         self.failUnlessRaises(
             KeyError, self.folder1.unrestrictedTraverse,  '/folder1/file2/' )
 
+    def testTraverseMethodRestricted(self):
+        self.root.my = Restricted('my')
+        my = self.root.my
+        my.id = 'my'
+        noSecurityManager()
+        SecurityManager.setSecurityPolicy(ProtectedMethodSecurityPolicy())
+        r = my.restrictedTraverse('getId')
+        self.assertEquals(r(), 'my')
+        self.assertRaises(Unauthorized, my.restrictedTraverse, 'private')
+        self.assertRaises(Unauthorized, my.restrictedTraverse, 'ohno')
+
     def testBoboTraverseToWrappedSubObj(self):
         # Verify it's possible to use __bobo_traverse__ with the
         # Zope security policy.



More information about the Zope-Checkins mailing list