Log message for revision 67196: Merge fix for #2072 into trunk Changed: U Zope/trunk/lib/python/OFS/Traversable.py U Zope/trunk/lib/python/OFS/tests/testTraverse.py
-=- Modified: Zope/trunk/lib/python/OFS/Traversable.py =================================================================== --- Zope/trunk/lib/python/OFS/Traversable.py 2006-04-21 00:31:16 UTC (rev 67195) +++ Zope/trunk/lib/python/OFS/Traversable.py 2006-04-21 00:34:55 UTC (rev 67196) @@ -206,8 +206,20 @@ else: # Can't determine container container = _none - if not securityManager.validate( - obj, container, name, next): + try: + validated = securityManager.validate( + obj, container, name, next) + except Unauthorized: + # If next is a simple unwrapped property, it's + # parentage is indeterminate, but it may have been + # acquired safely. In this case validate will + # raise an error, and we can explicitly check that + # our value was acquired safely. + validated = 0 + if container is _none and \ + guarded_getattr(obj, name, marker) is next: + validated = 1 + if not validated: raise Unauthorized, name else: if restricted: Modified: Zope/trunk/lib/python/OFS/tests/testTraverse.py =================================================================== --- Zope/trunk/lib/python/OFS/tests/testTraverse.py 2006-04-21 00:31:16 UTC (rev 67195) +++ Zope/trunk/lib/python/OFS/tests/testTraverse.py 2006-04-21 00:34:55 UTC (rev 67196) @@ -22,6 +22,7 @@ import transaction import ZODB, Acquisition, transaction from AccessControl import SecurityManager, Unauthorized +from AccessControl.Permissions import access_contents_information from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import noSecurityManager from Acquisition import aq_base @@ -102,6 +103,16 @@ bb_status = 'screechy' +class BoboTraversableWithAcquisition(SimpleItem): + """ + A BoboTraversable class which may use acquisition to find objects. + This is similar to how the __bobo_traverse__ added by Five behaves). + """ + + def __bobo_traverse__(self, request, name): + return Acquisition.aq_get(self, name) + + def makeConnection(): import ZODB from ZODB.DemoStorage import DemoStorage @@ -235,6 +246,58 @@ self.failUnless( bb.restrictedTraverse('manufactured') is 42) + def testBoboTraverseToAcquiredObject(self): + # Verify it's possible to use a __bobo_traverse__ which retrieves + # objects by acquisition + noSecurityManager() + SecurityManager.setSecurityPolicy( self.oldPolicy ) + bb = BoboTraversableWithAcquisition() + bb = bb.__of__(self.root) + self.assertEqual( + bb.restrictedTraverse('folder1'), bb.folder1) + self.assertEqual( + Acquisition.aq_inner(bb.restrictedTraverse('folder1')), + self.root.folder1) + + def testBoboTraverseToAcquiredProtectedObject(self): + # Verify it's possible to use a __bobo_traverse__ which retrieves + # objects by acquisition + noSecurityManager() + SecurityManager.setSecurityPolicy( self.oldPolicy ) + folder = self.root.folder1 + # restrict the ability to access the retrieved object itself + folder.manage_permission(access_contents_information, [], 0) + bb = BoboTraversableWithAcquisition() + bb = bb.__of__(self.root) + self.failUnlessRaises(Unauthorized, + self.root.folder1.restrictedTraverse, 'folder1') + + def testBoboTraverseToAcquiredAttribute(self): + # Verify it's possible to use __bobo_traverse__ to an acquired + # attribute + noSecurityManager() + SecurityManager.setSecurityPolicy( self.oldPolicy ) + folder = self.root.folder1 + folder.stuff = 'stuff here' + bb = BoboTraversableWithAcquisition() + bb = bb.__of__(folder) + self.assertEqual( + bb.restrictedTraverse('stuff'), 'stuff here') + + def testBoboTraverseToAcquiredProtectedAttribute(self): + # Verify that using __bobo_traverse__ to get an acquired but + # protected attribute results in Unauthorized + noSecurityManager() + SecurityManager.setSecurityPolicy( self.oldPolicy ) + folder = self.root.folder1 + # We protect the the attribute by restricting access to the parent + folder.manage_permission(access_contents_information, [], 0) + folder.stuff = 'stuff here' + bb = BoboTraversableWithAcquisition() + bb = bb.__of__(folder) + self.failUnlessRaises(Unauthorized, + self.root.folder1.restrictedTraverse, 'stuff') + def testAcquiredAttributeDenial(self): # Verify that restrictedTraverse raises the right kind of exception # on denial of access to an acquired attribute. If it raises _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins