Commit 5fd8e742 authored by Alec Mitchell's avatar Alec Mitchell

Collector #2072: Applied patch to fix problem with overly restrictive...

Collector #2072: Applied patch to fix problem with overly restrictive __bobo_traverse__ security and tests. (2.8 branch)
parent f6d2139d
...@@ -17,6 +17,9 @@ Zope Changes ...@@ -17,6 +17,9 @@ Zope Changes
After Zope 2.8.6 After Zope 2.8.6
Bugs fixed Bugs fixed
- Collector #2072: Applied patch to fix problem with overly restrictive
__bobo_traverse__ security and tests.
- Applied patch by Yoshinori Okuji to fix some XML export/import - Applied patch by Yoshinori Okuji to fix some XML export/import
problems problems
......
...@@ -196,8 +196,20 @@ class Traversable: ...@@ -196,8 +196,20 @@ class Traversable:
else: else:
# Can't determine container # Can't determine container
container = _none container = _none
if not securityManager.validate( try:
obj, container, name, next): 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 raise Unauthorized, name
else: else:
if restricted: if restricted:
......
...@@ -24,6 +24,7 @@ from OFS.Image import manage_addFile ...@@ -24,6 +24,7 @@ from OFS.Image import manage_addFile
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
from Testing.makerequest import makerequest from Testing.makerequest import makerequest
from AccessControl import SecurityManager, Unauthorized from AccessControl import SecurityManager, Unauthorized
from AccessControl.Permissions import access_contents_information
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
...@@ -101,6 +102,16 @@ class BoboTraversable(SimpleItem): ...@@ -101,6 +102,16 @@ class BoboTraversable(SimpleItem):
bb_status = 'screechy' 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(): def makeConnection():
import ZODB import ZODB
from ZODB.DemoStorage import DemoStorage from ZODB.DemoStorage import DemoStorage
...@@ -227,6 +238,58 @@ class TestTraverse( unittest.TestCase ): ...@@ -227,6 +238,58 @@ class TestTraverse( unittest.TestCase ):
self.failUnless( self.failUnless(
bb.restrictedTraverse('manufactured') is 42) 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): def testAcquiredAttributeDenial(self):
# Verify that restrictedTraverse raises the right kind of exception # Verify that restrictedTraverse raises the right kind of exception
# on denial of access to an acquired attribute. If it raises # on denial of access to an acquired attribute. If it raises
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment