Log message for revision 99146: Let the <permission /> directive auto-register permissions that don't exist already
Changed: U Zope/trunk/doc/CHANGES.rst U Zope/trunk/src/Products/Five/permissions.zcml U Zope/trunk/src/Products/Five/security.py U Zope/trunk/src/Products/Five/tests/test_security.py -=- Modified: Zope/trunk/doc/CHANGES.rst =================================================================== --- Zope/trunk/doc/CHANGES.rst 2009-04-13 10:15:12 UTC (rev 99145) +++ Zope/trunk/doc/CHANGES.rst 2009-04-13 10:46:06 UTC (rev 99146) @@ -23,6 +23,12 @@ Restructuring +++++++++++++ +- If the <permission /> ZCML directive is used to declare a permission that + does not exist, the permission will now be created automatically, defaulting + to being granted to the Manager role only. This means it is possible to + create new permissions using ZCML only. The permission will Permissions that + already exist will not be changed. + - Using <require set_schema="..." /> or <require set_attributes="..." /> in the <class /> directive now emits a warning rather than an error. The concept of protecting attribute 'set' does not exist in Zope 2, but it Modified: Zope/trunk/src/Products/Five/permissions.zcml =================================================================== --- Zope/trunk/src/Products/Five/permissions.zcml 2009-04-13 10:15:12 UTC (rev 99145) +++ Zope/trunk/src/Products/Five/permissions.zcml 2009-04-13 10:46:06 UTC (rev 99146) @@ -1,6 +1,13 @@ <configure xmlns="http://namespaces.zope.org/zope" i18n_domain="Five"> + <!-- Create permissions declared in ZCML if they don't exist already --> + <subscriber + for="zope.security.interfaces.IPermission + zope.component.interfaces.IRegistered" + handler=".security.create_permission_from_permission_directive" + /> + <permission id="five.ManageSite" title="Manage Five local sites" Modified: Zope/trunk/src/Products/Five/security.py =================================================================== --- Zope/trunk/src/Products/Five/security.py 2009-04-13 10:15:12 UTC (rev 99145) +++ Zope/trunk/src/Products/Five/security.py 2009-04-13 10:46:06 UTC (rev 99146) @@ -34,7 +34,13 @@ from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityManagement import getSecurityManager +from AccessControl.Permission import _registeredPermissions +from AccessControl.Permission import pname +import Products + +from Globals import ApplicationDefaultPermissions + CheckerPublicId = 'zope.Public' CheckerPrivateId = 'zope2.Private' @@ -155,3 +161,21 @@ # Zope 2 uses string, not unicode yet perm = str(permission.title) security.declareObjectProtected(perm) + +def create_permission_from_permission_directive(permission, event): + """When a new IPermission utility is registered (via the <permission /> + directive), create the equivalent Zope2 style permission. + """ + + global _registeredPermissions + + zope2_permission = permission.title + roles = ('Manager',) + + if not _registeredPermissions.has_key(zope2_permission): + _registeredPermissions[zope2_permission] = 1 + + Products.__ac_permissions__ += ((zope2_permission, (), roles,),) + + mangled = pname(zope2_permission) + setattr(ApplicationDefaultPermissions, mangled, roles) Modified: Zope/trunk/src/Products/Five/tests/test_security.py =================================================================== --- Zope/trunk/src/Products/Five/tests/test_security.py 2009-04-13 10:15:12 UTC (rev 99145) +++ Zope/trunk/src/Products/Five/tests/test_security.py 2009-04-13 10:46:06 UTC (rev 99146) @@ -374,6 +374,76 @@ >>> tearDown() """ +def test_register_permission(): + """This test demonstrates that if the <permission /> directive is used + to create a permission that does not already exist, it is created on + startup, with roles defaulting to Manager. + + >>> from zope.app.testing.placelesssetup import setUp, tearDown + >>> setUp() + + First, we need to configure the relevant parts of Five. + + >>> import Products.Five + >>> from Products.Five import zcml + >>> zcml.load_config('meta.zcml', Products.Five) + >>> zcml.load_config('permissions.zcml', Products.Five) + + We can now register a permission in ZCML: + + >>> configure_zcml = ''' + ... <configure xmlns="http://namespaces.zope.org/zope"> + ... + ... <permission + ... id="Products.Five.tests.DummyPermission" + ... title="Five: Dummy permission" + ... /> + ... + ... </configure> + ... ''' + >>> zcml.load_string(configure_zcml) + + The permission will be made available globally, with default role set + of ('Manager',). + + >>> from pprint import pprint + >>> pprint(self.app.rolesOfPermission('Five: Dummy permission')) + [{'name': 'Anonymous', 'selected': ''}, + {'name': 'Authenticated', 'selected': ''}, + {'name': 'Manager', 'selected': 'SELECTED'}, + {'name': 'Owner', 'selected': ''}] + + Let's also ensure that permissions are not overwritten if they exist + already: + + >>> from AccessControl.Permission import _registeredPermissions + >>> import Products + >>> _registeredPermissions['Five: Other dummy'] = 1 + >>> Products.__ac_permissions__ += (('Five: Other dummy', (), (),),) + >>> self.app.manage_permission('Five: Other dummy', roles=['Anonymous']) + + >>> configure_zcml = ''' + ... <configure xmlns="http://namespaces.zope.org/zope"> + ... + ... <permission + ... id="Products.Five.tests.OtherDummy" + ... title="Five: Other dummy" + ... /> + ... + ... </configure> + ... ''' + >>> zcml.load_string(configure_zcml) + + >>> from pprint import pprint + >>> pprint(self.app.rolesOfPermission('Five: Other dummy')) + [{'name': 'Anonymous', 'selected': 'SELECTED'}, + {'name': 'Authenticated', 'selected': ''}, + {'name': 'Manager', 'selected': ''}, + {'name': 'Owner', 'selected': ''}] + + >>> tearDown() + """ + def test_suite(): from Testing.ZopeTestCase import ZopeDocTestSuite return ZopeDocTestSuite() _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins