[Zope-Checkins] SVN: Zope/branches/accesscontrol-forward-port/ - An
attempt to forward port Tres' fixes from Zope-2_7-branch to
trunk. Tres or someone else should review this cause I don't
feel comfortable enough to do it and there is one test failing at:
Sidnei da Silva
sidnei at awkly.org
Fri Mar 18 05:24:22 EST 2005
Log message for revision 29550:
- An attempt to forward port Tres' fixes from Zope-2_7-branch to trunk. Tres or someone else should review this cause I don't feel comfortable enough to do it and there is one test failing at:
ERROR: test_bound_used_context_method_w_roles (AccessControl.tests.testBindings.TestBindings)
Changed:
U Zope/branches/accesscontrol-forward-port/doc/CHANGES.txt
U Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/ImplPython.py
U Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/cAccessControl.c
A Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/tests/testAcquisition.py
U Zope/branches/accesscontrol-forward-port/lib/python/OFS/tests/testCopySupport.py
-=-
Modified: Zope/branches/accesscontrol-forward-port/doc/CHANGES.txt
===================================================================
--- Zope/branches/accesscontrol-forward-port/doc/CHANGES.txt 2005-03-18 10:21:52 UTC (rev 29549)
+++ Zope/branches/accesscontrol-forward-port/doc/CHANGES.txt 2005-03-18 10:24:22 UTC (rev 29550)
@@ -57,7 +57,11 @@
text/<foo> types
Bugs fixed
-
+
+ - Forward-ported guarded_getattr fix: Restored ability to aquire
+ "through" unprotected contexts, broken through overzealous
+ cleanup in Zope 2.7.3.
+
- Fixed Shared.DC.ZRDB.Results to behave with the new-style
ExtensionClass. Added a test.
Modified: Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/ImplPython.py
===================================================================
--- Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/ImplPython.py 2005-03-18 10:21:52 UTC (rev 29549)
+++ Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/ImplPython.py 2005-03-18 10:24:22 UTC (rev 29550)
@@ -17,6 +17,9 @@
import string
from Acquisition import aq_base
+from Acquisition import aq_parent
+from Acquisition import aq_inner
+from Acquisition import aq_acquire
from ExtensionClass import Base
from zLOG import LOG, PROBLEM
@@ -553,7 +556,13 @@
# No veto, so we can return
return v
+
+ # See if we can get the value doing a filtered acquire.
+ # aq_acquire will either return the same value as held by
+ # v or it will return an Unauthorized raised by validate.
validate = SecurityManagement.getSecurityManager().validate
- if validate(inst, inst, name, v):
- return v
+ aq_acquire(inst, name, aq_validate, validate)
+
+ return v
+
raise Unauthorized, name
Modified: Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/cAccessControl.c
===================================================================
--- Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/cAccessControl.c 2005-03-18 10:21:52 UTC (rev 29549)
+++ Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/cAccessControl.c 2005-03-18 10:24:22 UTC (rev 29550)
@@ -2176,17 +2176,23 @@
}
}
- /*
- if validate(inst, inst, name, v):
- return v
- */
- validate=callfunction4(validate, inst, inst, name, v);
- if (validate==NULL) goto err;
- i=PyObject_IsTrue(validate);
- Py_DECREF(validate);
- if (i < 0) goto err;
- if (i > 0) return v;
-
+ /*
+ # See if we can get the value doing a filtered acquire.
+ # aq_acquire will either return the same value as held by
+ # v or it will return an Unauthorized raised by validate.
+ validate = SecurityManagement.getSecurityManager().validate
+ aq_acquire(inst, name, aq_validate, validate)
+
+ return v
+ */
+
+ t = aq_Acquire(inst, name, aq_validate, validate, 1, NULL, 0);
+ if (t == NULL)
+ return NULL;
+ Py_DECREF(t);
+
+ return v;
+
unauthErr(name, v);
err:
Py_DECREF(v);
@@ -2378,4 +2384,3 @@
Py_DECREF(module);
module = NULL;
}
-
Added: Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/tests/testAcquisition.py
===================================================================
--- Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/tests/testAcquisition.py 2005-03-18 10:21:52 UTC (rev 29549)
+++ Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/tests/testAcquisition.py 2005-03-18 10:24:22 UTC (rev 29550)
@@ -0,0 +1,251 @@
+##############################################################################
+#
+# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+"""Tests demonstrating consequences of guarded_getattr fix from 2004/08/07
+
+ http://mail.zope.org/pipermail/zope-checkins/2004-August/028152.html
+ http://zope.org/Collectors/CMF/259
+
+"""
+
+import unittest
+
+from Testing.makerequest import makerequest
+
+import Zope2
+Zope2.startup()
+
+import transaction
+from OFS.SimpleItem import SimpleItem
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import noSecurityManager
+from AccessControl.Permissions import view, view_management_screens
+from AccessControl.ImplPython import guarded_getattr as guarded_getattr_py
+from AccessControl.ImplC import guarded_getattr as guarded_getattr_c
+from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
+
+
+class AllowedItem(SimpleItem):
+ id = 'allowed'
+ security = ClassSecurityInfo()
+ security.setDefaultAccess('allow')
+
+InitializeClass(AllowedItem)
+
+class DeniedItem(SimpleItem):
+ id = 'denied'
+ security = ClassSecurityInfo()
+ security.setDefaultAccess('deny')
+
+InitializeClass(DeniedItem)
+
+class ProtectedItem(SimpleItem):
+ id = 'protected'
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(view_management_screens)
+
+InitializeClass(ProtectedItem)
+
+class ProtectedSiteErrorLog(SiteErrorLog):
+ '''This differs from the base by declaring security
+ for the object itself.
+ '''
+ id = 'error_log2'
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(view)
+
+InitializeClass(ProtectedSiteErrorLog)
+
+
+class TestGetAttr(unittest.TestCase):
+
+ def setUp(self):
+ self.guarded_getattr = guarded_getattr_py
+ transaction.begin()
+ self.app = makerequest(Zope.app())
+ try:
+
+ # Set up a manager user
+ self.uf = self.app.acl_users
+ self.uf._doAddUser('manager', 'secret', ['Manager'], [])
+ self.login('manager')
+
+ # Set up objects in the root that we want to aquire
+ self.app.manage_addFolder('plain_folder')
+ self.app._setObject('error_log2', ProtectedSiteErrorLog())
+
+ # We also want to be able to acquire simple attributes
+ self.app.manage_addProperty(id='simple_type', type='string', value='a string')
+
+ # Set up a subfolder and the objects we want to acquire from
+ self.app.manage_addFolder('subfolder')
+ self.folder = self.app.subfolder
+ self.folder._setObject('allowed', AllowedItem())
+ self.folder._setObject('denied', DeniedItem())
+ self.folder._setObject('protected', ProtectedItem())
+
+ except:
+ self.tearDown()
+ raise
+
+ def tearDown(self):
+ noSecurityManager()
+ transaction.abort()
+ self.app._p_jar.close()
+
+ def login(self, name):
+ user = self.uf.getUserById(name)
+ user = user.__of__(self.uf)
+ newSecurityManager(None, user)
+
+ # Acquire plain folder
+
+ def testFolderAllowed(self):
+ o = self.guarded_getattr(self.folder.allowed, 'plain_folder')
+ self.assertEqual(o, self.app.plain_folder)
+
+ def testFolderDenied(self):
+ o = self.guarded_getattr(self.folder.denied, 'plain_folder')
+ self.assertEqual(o, self.app.plain_folder)
+
+ def testFolderProtected(self):
+ o = self.guarded_getattr(self.folder.protected, 'plain_folder')
+ self.assertEqual(o, self.app.plain_folder)
+
+ # Acquire user folder
+
+ def testAclUsersAllowed(self):
+ o = self.guarded_getattr(self.folder.allowed, 'acl_users')
+ self.assertEqual(o, self.app.acl_users)
+
+ def testAclUsersDenied(self):
+ # XXX: Fails in 2.7.3
+ o = self.guarded_getattr(self.folder.denied, 'acl_users')
+ self.assertEqual(o, self.app.acl_users)
+
+ def testAclUsersProtected(self):
+ # XXX: Fails in 2.7.3 for Anonymous
+ o = self.guarded_getattr(self.folder.protected, 'acl_users')
+ self.assertEqual(o, self.app.acl_users)
+
+ # Acquire browser id manager
+
+ def testBrowserIdManagerAllowed(self):
+ o = self.guarded_getattr(self.folder.allowed, 'browser_id_manager')
+ self.assertEqual(o, self.app.browser_id_manager)
+
+ def testBrowserIdManagerDenied(self):
+ o = self.guarded_getattr(self.folder.denied, 'browser_id_manager')
+ self.assertEqual(o, self.app.browser_id_manager)
+
+ def testBrowserIdManagerProtected(self):
+ o = self.guarded_getattr(self.folder.protected, 'browser_id_manager')
+ self.assertEqual(o, self.app.browser_id_manager)
+
+ # Acquire error log
+
+ def testErrorLogAllowed(self):
+ o = self.guarded_getattr(self.folder.allowed, 'error_log')
+ self.assertEqual(o, self.app.error_log)
+
+ def testErrorLogDenied(self):
+ # XXX: Fails in 2.7.3
+ o = self.guarded_getattr(self.folder.denied, 'error_log')
+ self.assertEqual(o, self.app.error_log)
+
+ def testErrorLogProtected(self):
+ # XXX: Fails in 2.7.3 for Anonymous
+ o = self.guarded_getattr(self.folder.protected, 'error_log')
+ self.assertEqual(o, self.app.error_log)
+
+ # Now watch this: error log with object security declaration works fine!
+
+ def testProtectedErrorLogAllowed(self):
+ o = self.guarded_getattr(self.folder.allowed, 'error_log2')
+ self.assertEqual(o, self.app.error_log2)
+
+ def testProtectedErrorLogDenied(self):
+ o = self.guarded_getattr(self.folder.denied, 'error_log2')
+ self.assertEqual(o, self.app.error_log2)
+
+ def testProtectedErrorLogProtected(self):
+ o = self.guarded_getattr(self.folder.protected, 'error_log2')
+ self.assertEqual(o, self.app.error_log2)
+
+ # This appears to mean that any potential acquiree must make sure
+ # to declareObjectProtected(SomePermission).
+
+ # From the ZDG:
+ # We've seen how to make assertions on methods - but in the case of
+ # someObject we are not trying to access any particular method, but
+ # rather the object itself (to pass it to some_method). Because the
+ # security machinery will try to validate access to someObject, we
+ # need a way to let the security machinery know how to handle access
+ # to the object itself in addition to protecting its methods.
+
+ # IOW, acquiring an object in restricted Python now amounts to
+ # "passing it to some_method".
+
+
+ # Also test Richard Jones' use-case of acquiring a string:
+
+ def testSimpleTypeAllowed(self):
+ o = self.guarded_getattr(self.folder.allowed, 'simple_type')
+ self.assertEqual(o, 'a string')
+
+ def testSimpleTypeDenied(self):
+ # XXX: Fails in 2.7.3
+ o = self.guarded_getattr(self.folder.denied, 'simple_type')
+ self.assertEqual(o, 'a string')
+
+ def testSimpleTypeProtected(self):
+ # XXX: Fails in 2.7.3 for Anonymous
+ o = self.guarded_getattr(self.folder.protected, 'simple_type')
+ self.assertEqual(o, 'a string')
+
+
+class TestGetAttrAnonymous(TestGetAttr):
+
+ # Run all tests again as Anonymous User
+
+ def setUp(self):
+ TestGetAttr.setUp(self)
+ # Log out
+ noSecurityManager()
+
+
+class TestGetAttr_c(TestGetAttr):
+
+ def setUp(self):
+ TestGetAttr.setUp(self)
+ self.guarded_getattr = guarded_getattr_c
+
+class TestGetAttrAnonymous_c(TestGetAttrAnonymous):
+
+ def setUp(self):
+ TestGetAttrAnonymous.setUp(self)
+ self.guarded_getattr = guarded_getattr_c
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestGetAttr))
+ suite.addTest(unittest.makeSuite(TestGetAttrAnonymous))
+ suite.addTest(unittest.makeSuite(TestGetAttr_c))
+ suite.addTest(unittest.makeSuite(TestGetAttrAnonymous_c))
+ return suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Property changes on: Zope/branches/accesscontrol-forward-port/lib/python/AccessControl/tests/testAcquisition.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: Zope/branches/accesscontrol-forward-port/lib/python/OFS/tests/testCopySupport.py
===================================================================
--- Zope/branches/accesscontrol-forward-port/lib/python/OFS/tests/testCopySupport.py 2005-03-18 10:21:52 UTC (rev 29549)
+++ Zope/branches/accesscontrol-forward-port/lib/python/OFS/tests/testCopySupport.py 2005-03-18 10:24:22 UTC (rev 29550)
@@ -4,7 +4,7 @@
from multifile import MultiFile
import transaction
-from AccessControl import SecurityManager
+from AccessControl import SecurityManager, Unauthorized
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import Implicit
@@ -281,7 +281,9 @@
self._lambdas = ( validate_lambda, checkPermission_lambda )
def validate( self, *args, **kw ):
- return self._lambdas[ 0 ]( *args, **kw )
+ if self._lambdas[ 0 ]( *args, **kw ):
+ return 1
+ raise Unauthorized
def checkPermission( self, *args, **kw ) :
return self._lambdas[ 1 ]( *args, **kw )
More information about the Zope-Checkins
mailing list