Log message for revision 68981: Merged r68980 from 2.10 branch: Fixed refactored traversal on bound methods of classes with no default access.
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-07-05 16:53:20 UTC (rev 68980) +++ Zope/trunk/lib/python/OFS/Traversable.py 2006-07-05 16:54:24 UTC (rev 68981) @@ -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/trunk/lib/python/OFS/tests/testTraverse.py =================================================================== --- Zope/trunk/lib/python/OFS/tests/testTraverse.py 2006-07-05 16:53:20 UTC (rev 68980) +++ Zope/trunk/lib/python/OFS/tests/testTraverse.py 2006-07-05 16:54:24 UTC (rev 68981) @@ -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. _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins