[Zope-Checkins] SVN: Zope/trunk/ Get rid of some more testing dependencies in AccessControl by moving integration tests into higher level packages
Hanno Schlichting
hannosch at hannosch.eu
Sat Jun 5 13:35:01 EDT 2010
Log message for revision 113162:
Get rid of some more testing dependencies in AccessControl by moving integration tests into higher level packages
Changed:
U Zope/trunk/AC-vs-DTML-TODO.txt
U Zope/trunk/src/AccessControl/permissions.zcml
D Zope/trunk/src/AccessControl/tests/testAcquisition.py
D Zope/trunk/src/AccessControl/tests/testBindings.py
U Zope/trunk/src/AccessControl/tests/testOwned.py
A Zope/trunk/src/OFS/tests/testAcquisition.py
A Zope/trunk/src/Products/PythonScripts/tests/testBindings.py
-=-
Modified: Zope/trunk/AC-vs-DTML-TODO.txt
===================================================================
--- Zope/trunk/AC-vs-DTML-TODO.txt 2010-06-05 16:51:13 UTC (rev 113161)
+++ Zope/trunk/AC-vs-DTML-TODO.txt 2010-06-05 17:35:00 UTC (rev 113162)
@@ -35,11 +35,8 @@
- Test only dependencies:
* OFS
- * Products.PythonScripts
- * Products.SiteErrorLog
* Testing
* transaction
- * Zope2
DocumentTemplate
----------------
Modified: Zope/trunk/src/AccessControl/permissions.zcml
===================================================================
--- Zope/trunk/src/AccessControl/permissions.zcml 2010-06-05 16:51:13 UTC (rev 113161)
+++ Zope/trunk/src/AccessControl/permissions.zcml 2010-06-05 17:35:00 UTC (rev 113162)
@@ -1,8 +1,6 @@
<configure xmlns="http://namespaces.zope.org/zope"
i18n_domain="Zope2">
- <include package="Zope2.App" file="meta.zcml"/>
-
<!-- Create permissions declared in ZCML if they don't exist already -->
<subscriber
for="zope.security.interfaces.IPermission
Deleted: Zope/trunk/src/AccessControl/tests/testAcquisition.py
===================================================================
--- Zope/trunk/src/AccessControl/tests/testAcquisition.py 2010-06-05 16:51:13 UTC (rev 113161)
+++ Zope/trunk/src/AccessControl/tests/testAcquisition.py 2010-06-05 17:35:00 UTC (rev 113162)
@@ -1,252 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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()
-
-from OFS.SimpleItem import SimpleItem
-from AccessControl import ClassSecurityInfo
-from AccessControl.class_init import InitializeClass
-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):
- import transaction
- self.guarded_getattr = guarded_getattr_py
- transaction.manager.begin()
- self.app = makerequest(Zope2.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):
- import transaction
- noSecurityManager()
- transaction.manager.get().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')
-
Deleted: Zope/trunk/src/AccessControl/tests/testBindings.py
===================================================================
--- Zope/trunk/src/AccessControl/tests/testBindings.py 2010-06-05 16:51:13 UTC (rev 113161)
+++ Zope/trunk/src/AccessControl/tests/testBindings.py 2010-06-05 17:35:00 UTC (rev 113162)
@@ -1,319 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Test Bindings
-
-$Id$
-"""
-
-import unittest
-import ZODB
-import transaction
-from Acquisition import Implicit
-from AccessControl import ClassSecurityInfo
-from AccessControl.class_init import InitializeClass
-from OFS.ObjectManager import ObjectManager
-from OFS.Folder import Folder
-
-class SecurityManager:
-
- def __init__(self, reject=0):
- self.calls = []
- self.reject = reject
-
- def validate(self, *args):
- from AccessControl import Unauthorized
- self.calls.append(('validate', args))
- if self.reject:
- raise Unauthorized
- return 1
-
- def validateValue(self, *args):
- from AccessControl import Unauthorized
- self.calls.append(('validateValue', args))
- if self.reject:
- raise Unauthorized
- return 1
-
- def checkPermission(self, *args):
- self.calls.append(('checkPermission', args))
- return not self.reject
-
- def addContext(self, *args):
- self.calls.append(('addContext', args))
- return 1
-
- def removeContext(self, *args):
- self.calls.append(('removeContext', args))
- return 1
-
-class UnderprivilegedUser:
- def getId(self):
- return 'underprivileged'
-
- def allowed(self, object, object_roles=None):
- return 0
-
-class RivilegedUser:
- def getId(self):
- return 'privileged'
-
- def allowed(self, object, object_roles=None):
- return 1
-
-class FauxRoot(ObjectManager):
- def getPhysicalPath(self):
- return ('',)
- def __repr__(self):
- return '<FauxRoot>'
-
-class FauxFolder(Folder):
-
- security = ClassSecurityInfo()
- security.declareObjectPrivate()
-
- security.declarePrivate('__repr__')
- def __repr__(self):
- return '<FauxFolder: %s>' % self.getId()
-
- security.declarePublic('methodWithRoles')
- def methodWithRoles(self):
- return 'method called'
-
-InitializeClass(FauxFolder)
-
-class TestBindings(unittest.TestCase):
-
- def setUp(self):
- from Testing.ZODButil import makeDB
- transaction.begin()
- self.db = makeDB()
- self.connection = self.db.open()
-
- def tearDown(self):
- from Testing.ZODButil import cleanDB
- from AccessControl.SecurityManagement import noSecurityManager
- noSecurityManager()
- transaction.abort()
- self.connection.close()
- self.db.close()
- cleanDB()
-
- def _getRoot(self):
- from Testing.makerequest import makerequest
- #true_root = self.connection.root()[ 'Application' ]
- #true_root = self.connection.root()
- #return makerequest(true_root)
- return makerequest(FauxRoot())
-
- def _makeTree(self):
-
- root = self._getRoot()
-
- guarded = FauxFolder()
- guarded._setId('guarded')
- guarded.__roles__ = ( 'Manager', )
- root._setOb('guarded', guarded)
- guarded = root._getOb('guarded')
-
- open = FauxFolder()
- open._setId('open')
- open.__roles__ = ( 'Anonymous', )
- guarded._setOb('open', open)
-
- bound_unused_container_ps = self._newPS('return 1')
- guarded._setOb('bound_unused_container_ps', bound_unused_container_ps)
-
- bound_used_container_ps = self._newPS('return container.id')
- guarded._setOb('bound_used_container_ps', bound_used_container_ps)
-
- bound_used_container_ok_ps = self._newPS('return container.id')
- open._setOb('bound_used_container_ok_ps', bound_used_container_ok_ps)
-
- bound_unused_context_ps = self._newPS('return 1')
- guarded._setOb('bound_unused_context_ps', bound_unused_context_ps)
-
- bound_used_context_ps = self._newPS('return context.id')
- guarded._setOb('bound_used_context_ps', bound_used_context_ps)
-
- bound_used_context_methodWithRoles_ps = self._newPS(
- 'return context.methodWithRoles()')
- guarded._setOb('bound_used_context_methodWithRoles_ps',
- bound_used_context_methodWithRoles_ps)
-
- container_ps = self._newPS('return container')
- guarded._setOb('container_ps', container_ps)
-
- container_str_ps = self._newPS('return str(container)')
- guarded._setOb('container_str_ps', container_str_ps)
-
- context_ps = self._newPS('return context')
- guarded._setOb('context_ps', context_ps)
-
- context_str_ps = self._newPS('return str(context)')
- guarded._setOb('context_str_ps', context_str_ps)
-
- return root
-
- def _newPS(self, txt, bind=None):
- from Products.PythonScripts.PythonScript import PythonScript
- ps = PythonScript('ps')
- #ps.ZBindings_edit(bind or {})
- ps.write(txt)
- ps._makeFunction()
- return ps
-
- # These test that the mere binding of context or container, when the
- # user doesn't have access to them, doesn't raise an unauthorized. An
- # exception *will* be raised if the script attempts to use them. This
- # is a b/w compatibility hack: see Bindings.py for details.
-
- def test_bound_unused_container(self):
- from AccessControl.SecurityManagement import newSecurityManager
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
- ps = guarded._getOb('bound_unused_container_ps')
- self.assertEqual(ps(), 1)
-
- def test_bound_used_container(self):
- from AccessControl.SecurityManagement import newSecurityManager
- from AccessControl import Unauthorized
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
-
- ps = guarded._getOb('bound_used_container_ps')
- self.assertRaises(Unauthorized, ps)
-
- ps = guarded._getOb('container_str_ps')
- self.assertRaises(Unauthorized, ps)
-
- ps = guarded._getOb('container_ps')
- container = ps()
- self.assertRaises(Unauthorized, container)
- self.assertRaises(Unauthorized, container.index_html)
- try:
- str(container)
- except Unauthorized:
- pass
- else:
- self.fail("str(container) didn't raise Unauthorized!")
-
- ps = guarded._getOb('bound_used_container_ps')
- ps._proxy_roles = ( 'Manager', )
- ps()
-
- ps = guarded._getOb('container_str_ps')
- ps._proxy_roles = ( 'Manager', )
- ps()
-
- def test_bound_used_container_allowed(self):
- from AccessControl.SecurityManagement import newSecurityManager
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
- open = guarded._getOb('open')
- ps = open.unrestrictedTraverse('bound_used_container_ok_ps')
- self.assertEqual(ps(), 'open')
-
- def test_bound_unused_context(self):
- from AccessControl.SecurityManagement import newSecurityManager
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
- ps = guarded._getOb('bound_unused_context_ps')
- self.assertEqual(ps(), 1)
-
- def test_bound_used_context(self):
- from AccessControl.SecurityManagement import newSecurityManager
- from AccessControl import Unauthorized
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
-
- ps = guarded._getOb('bound_used_context_ps')
- self.assertRaises(Unauthorized, ps)
-
- ps = guarded._getOb('context_str_ps')
- self.assertRaises(Unauthorized, ps)
-
- ps = guarded._getOb('context_ps')
- context = ps()
- self.assertRaises(Unauthorized, context)
- self.assertRaises(Unauthorized, context.index_html)
- try:
- str(context)
- except Unauthorized:
- pass
- else:
- self.fail("str(context) didn't raise Unauthorized!")
-
- ps = guarded._getOb('bound_used_context_ps')
- ps._proxy_roles = ( 'Manager', )
- ps()
-
- ps = guarded._getOb('context_str_ps')
- ps._proxy_roles = ( 'Manager', )
- ps()
-
- def test_bound_used_context_allowed(self):
- from AccessControl.SecurityManagement import newSecurityManager
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
- open = guarded._getOb('open')
- ps = open.unrestrictedTraverse('bound_used_context_ps')
- self.assertEqual(ps(), 'open')
-
- def test_ok_no_bindings(self):
- from AccessControl.SecurityManagement import newSecurityManager
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
- boundless_ps = self._newPS('return 42')
- guarded._setOb('boundless_ps', boundless_ps)
- boundless_ps = guarded._getOb('boundless_ps')
- #
- # Clear the bindings, so that the script may execute.
- #
- boundless_ps.ZBindings_edit( {'name_context': '',
- 'name_container': '',
- 'name_m_self': '',
- 'name_ns': '',
- 'name_subpath': ''})
- self.assertEqual(boundless_ps(), 42)
-
- def test_bound_used_context_method_w_roles(self):
- from AccessControl.SecurityManagement import newSecurityManager
- from AccessControl import Unauthorized
- newSecurityManager(None, UnderprivilegedUser())
- root = self._makeTree()
- guarded = root._getOb('guarded')
-
- # Assert that we can call a protected method, even though we have
- # no access to the context directly.
- ps = guarded._getOb('bound_used_context_ps')
- self.assertRaises(Unauthorized, ps)
- ps = guarded._getOb('bound_used_context_methodWithRoles_ps')
- self.assertEqual(ps(), 'method called')
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestBindings))
- return suite
-
-
-if __name__ == '__main__':
- unittest.main()
Modified: Zope/trunk/src/AccessControl/tests/testOwned.py
===================================================================
--- Zope/trunk/src/AccessControl/tests/testOwned.py 2010-06-05 16:51:13 UTC (rev 113161)
+++ Zope/trunk/src/AccessControl/tests/testOwned.py 2010-06-05 17:35:00 UTC (rev 113162)
@@ -4,11 +4,13 @@
"""
import unittest
-import Testing
-import ZODB
+from persistent import Persistent
from Acquisition import Implicit, aq_inner
+from AccessControl.Owned import Owned
+
+
class FauxUser(Implicit):
def __init__(self, id):
@@ -17,11 +19,13 @@
def getId(self):
return self._id
+
class FauxUserFolder(Implicit):
def getUserById(self, id, default):
return FauxUser(id)
+
class FauxRoot(Implicit):
def getPhysicalRoot(self):
@@ -46,26 +50,40 @@
return obj
+
+class Folder(Implicit, Persistent, Owned):
+
+ def __init__(self, id):
+ self.id = id
+ self.names = set()
+
+ def _setObject(self, name, value):
+ setattr(self, name, value)
+ self.names.add(name)
+
+ def objectValues(self):
+ result = []
+ for name in self.names:
+ result.append(getattr(self, name))
+ return result
+
+
class OwnedTests(unittest.TestCase):
def _getTargetClass(self):
- from AccessControl.Owned import Owned
return Owned
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
def _makeDummy(self, *args, **kw):
-
- from AccessControl.Owned import Owned
class Dummy(Implicit, Owned):
pass
return Dummy(*args, **kw)
- def test_z3interfaces(self):
+ def test_interfaces(self):
from AccessControl.interfaces import IOwned
- from AccessControl.Owned import Owned
from zope.interface.verify import verifyClass
verifyClass(IOwned, Owned)
@@ -182,7 +200,6 @@
def setUp(self):
from AccessControl.Owned import UnownableOwner
from AccessControl.User import UserFolder
- from OFS.Folder import Folder
super(OwnershipChangeTests, self).setUp()
self.root = FauxRoot()
Copied: Zope/trunk/src/OFS/tests/testAcquisition.py (from rev 113160, Zope/trunk/src/AccessControl/tests/testAcquisition.py)
===================================================================
--- Zope/trunk/src/OFS/tests/testAcquisition.py (rev 0)
+++ Zope/trunk/src/OFS/tests/testAcquisition.py 2010-06-05 17:35:00 UTC (rev 113162)
@@ -0,0 +1,252 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Foundation and Contributors.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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()
+
+from OFS.SimpleItem import SimpleItem
+from AccessControl import ClassSecurityInfo
+from AccessControl.class_init import InitializeClass
+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):
+ import transaction
+ self.guarded_getattr = guarded_getattr_py
+ transaction.manager.begin()
+ self.app = makerequest(Zope2.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):
+ import transaction
+ noSecurityManager()
+ transaction.manager.get().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')
+
Copied: Zope/trunk/src/Products/PythonScripts/tests/testBindings.py (from rev 113160, Zope/trunk/src/AccessControl/tests/testBindings.py)
===================================================================
--- Zope/trunk/src/Products/PythonScripts/tests/testBindings.py (rev 0)
+++ Zope/trunk/src/Products/PythonScripts/tests/testBindings.py 2010-06-05 17:35:00 UTC (rev 113162)
@@ -0,0 +1,319 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+"""Test Bindings
+
+$Id$
+"""
+
+import unittest
+import ZODB
+import transaction
+from Acquisition import Implicit
+from AccessControl import ClassSecurityInfo
+from AccessControl.class_init import InitializeClass
+from OFS.ObjectManager import ObjectManager
+from OFS.Folder import Folder
+
+class SecurityManager:
+
+ def __init__(self, reject=0):
+ self.calls = []
+ self.reject = reject
+
+ def validate(self, *args):
+ from AccessControl import Unauthorized
+ self.calls.append(('validate', args))
+ if self.reject:
+ raise Unauthorized
+ return 1
+
+ def validateValue(self, *args):
+ from AccessControl import Unauthorized
+ self.calls.append(('validateValue', args))
+ if self.reject:
+ raise Unauthorized
+ return 1
+
+ def checkPermission(self, *args):
+ self.calls.append(('checkPermission', args))
+ return not self.reject
+
+ def addContext(self, *args):
+ self.calls.append(('addContext', args))
+ return 1
+
+ def removeContext(self, *args):
+ self.calls.append(('removeContext', args))
+ return 1
+
+class UnderprivilegedUser:
+ def getId(self):
+ return 'underprivileged'
+
+ def allowed(self, object, object_roles=None):
+ return 0
+
+class RivilegedUser:
+ def getId(self):
+ return 'privileged'
+
+ def allowed(self, object, object_roles=None):
+ return 1
+
+class FauxRoot(ObjectManager):
+ def getPhysicalPath(self):
+ return ('',)
+ def __repr__(self):
+ return '<FauxRoot>'
+
+class FauxFolder(Folder):
+
+ security = ClassSecurityInfo()
+ security.declareObjectPrivate()
+
+ security.declarePrivate('__repr__')
+ def __repr__(self):
+ return '<FauxFolder: %s>' % self.getId()
+
+ security.declarePublic('methodWithRoles')
+ def methodWithRoles(self):
+ return 'method called'
+
+InitializeClass(FauxFolder)
+
+class TestBindings(unittest.TestCase):
+
+ def setUp(self):
+ from Testing.ZODButil import makeDB
+ transaction.begin()
+ self.db = makeDB()
+ self.connection = self.db.open()
+
+ def tearDown(self):
+ from Testing.ZODButil import cleanDB
+ from AccessControl.SecurityManagement import noSecurityManager
+ noSecurityManager()
+ transaction.abort()
+ self.connection.close()
+ self.db.close()
+ cleanDB()
+
+ def _getRoot(self):
+ from Testing.makerequest import makerequest
+ #true_root = self.connection.root()[ 'Application' ]
+ #true_root = self.connection.root()
+ #return makerequest(true_root)
+ return makerequest(FauxRoot())
+
+ def _makeTree(self):
+
+ root = self._getRoot()
+
+ guarded = FauxFolder()
+ guarded._setId('guarded')
+ guarded.__roles__ = ( 'Manager', )
+ root._setOb('guarded', guarded)
+ guarded = root._getOb('guarded')
+
+ open = FauxFolder()
+ open._setId('open')
+ open.__roles__ = ( 'Anonymous', )
+ guarded._setOb('open', open)
+
+ bound_unused_container_ps = self._newPS('return 1')
+ guarded._setOb('bound_unused_container_ps', bound_unused_container_ps)
+
+ bound_used_container_ps = self._newPS('return container.id')
+ guarded._setOb('bound_used_container_ps', bound_used_container_ps)
+
+ bound_used_container_ok_ps = self._newPS('return container.id')
+ open._setOb('bound_used_container_ok_ps', bound_used_container_ok_ps)
+
+ bound_unused_context_ps = self._newPS('return 1')
+ guarded._setOb('bound_unused_context_ps', bound_unused_context_ps)
+
+ bound_used_context_ps = self._newPS('return context.id')
+ guarded._setOb('bound_used_context_ps', bound_used_context_ps)
+
+ bound_used_context_methodWithRoles_ps = self._newPS(
+ 'return context.methodWithRoles()')
+ guarded._setOb('bound_used_context_methodWithRoles_ps',
+ bound_used_context_methodWithRoles_ps)
+
+ container_ps = self._newPS('return container')
+ guarded._setOb('container_ps', container_ps)
+
+ container_str_ps = self._newPS('return str(container)')
+ guarded._setOb('container_str_ps', container_str_ps)
+
+ context_ps = self._newPS('return context')
+ guarded._setOb('context_ps', context_ps)
+
+ context_str_ps = self._newPS('return str(context)')
+ guarded._setOb('context_str_ps', context_str_ps)
+
+ return root
+
+ def _newPS(self, txt, bind=None):
+ from Products.PythonScripts.PythonScript import PythonScript
+ ps = PythonScript('ps')
+ #ps.ZBindings_edit(bind or {})
+ ps.write(txt)
+ ps._makeFunction()
+ return ps
+
+ # These test that the mere binding of context or container, when the
+ # user doesn't have access to them, doesn't raise an unauthorized. An
+ # exception *will* be raised if the script attempts to use them. This
+ # is a b/w compatibility hack: see Bindings.py for details.
+
+ def test_bound_unused_container(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+ ps = guarded._getOb('bound_unused_container_ps')
+ self.assertEqual(ps(), 1)
+
+ def test_bound_used_container(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ from AccessControl import Unauthorized
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+
+ ps = guarded._getOb('bound_used_container_ps')
+ self.assertRaises(Unauthorized, ps)
+
+ ps = guarded._getOb('container_str_ps')
+ self.assertRaises(Unauthorized, ps)
+
+ ps = guarded._getOb('container_ps')
+ container = ps()
+ self.assertRaises(Unauthorized, container)
+ self.assertRaises(Unauthorized, container.index_html)
+ try:
+ str(container)
+ except Unauthorized:
+ pass
+ else:
+ self.fail("str(container) didn't raise Unauthorized!")
+
+ ps = guarded._getOb('bound_used_container_ps')
+ ps._proxy_roles = ( 'Manager', )
+ ps()
+
+ ps = guarded._getOb('container_str_ps')
+ ps._proxy_roles = ( 'Manager', )
+ ps()
+
+ def test_bound_used_container_allowed(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+ open = guarded._getOb('open')
+ ps = open.unrestrictedTraverse('bound_used_container_ok_ps')
+ self.assertEqual(ps(), 'open')
+
+ def test_bound_unused_context(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+ ps = guarded._getOb('bound_unused_context_ps')
+ self.assertEqual(ps(), 1)
+
+ def test_bound_used_context(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ from AccessControl import Unauthorized
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+
+ ps = guarded._getOb('bound_used_context_ps')
+ self.assertRaises(Unauthorized, ps)
+
+ ps = guarded._getOb('context_str_ps')
+ self.assertRaises(Unauthorized, ps)
+
+ ps = guarded._getOb('context_ps')
+ context = ps()
+ self.assertRaises(Unauthorized, context)
+ self.assertRaises(Unauthorized, context.index_html)
+ try:
+ str(context)
+ except Unauthorized:
+ pass
+ else:
+ self.fail("str(context) didn't raise Unauthorized!")
+
+ ps = guarded._getOb('bound_used_context_ps')
+ ps._proxy_roles = ( 'Manager', )
+ ps()
+
+ ps = guarded._getOb('context_str_ps')
+ ps._proxy_roles = ( 'Manager', )
+ ps()
+
+ def test_bound_used_context_allowed(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+ open = guarded._getOb('open')
+ ps = open.unrestrictedTraverse('bound_used_context_ps')
+ self.assertEqual(ps(), 'open')
+
+ def test_ok_no_bindings(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+ boundless_ps = self._newPS('return 42')
+ guarded._setOb('boundless_ps', boundless_ps)
+ boundless_ps = guarded._getOb('boundless_ps')
+ #
+ # Clear the bindings, so that the script may execute.
+ #
+ boundless_ps.ZBindings_edit( {'name_context': '',
+ 'name_container': '',
+ 'name_m_self': '',
+ 'name_ns': '',
+ 'name_subpath': ''})
+ self.assertEqual(boundless_ps(), 42)
+
+ def test_bound_used_context_method_w_roles(self):
+ from AccessControl.SecurityManagement import newSecurityManager
+ from AccessControl import Unauthorized
+ newSecurityManager(None, UnderprivilegedUser())
+ root = self._makeTree()
+ guarded = root._getOb('guarded')
+
+ # Assert that we can call a protected method, even though we have
+ # no access to the context directly.
+ ps = guarded._getOb('bound_used_context_ps')
+ self.assertRaises(Unauthorized, ps)
+ ps = guarded._getOb('bound_used_context_methodWithRoles_ps')
+ self.assertEqual(ps(), 'method called')
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestBindings))
+ return suite
+
+
+if __name__ == '__main__':
+ unittest.main()
More information about the Zope-Checkins
mailing list