[Zope-Checkins] SVN: Zope/trunk/ Let the <permission /> directive auto-register permissions that don't exist already

Martin Aspeli optilude at gmx.net
Mon Apr 13 06:46:06 EDT 2009


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()



More information about the Zope-Checkins mailing list