Commit bb3ba109 authored by Martin Aspeli's avatar Martin Aspeli

Let the <permission /> directive auto-register permissions that don't exist already

parent 6c4b4d71
......@@ -23,6 +23,12 @@ Known issues
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
......
<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"
......
......@@ -34,6 +34,12 @@ from zope.security.simplepolicies import ParanoidSecurityPolicy
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 @@ def protectClass(klass, permission_id):
# 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)
......@@ -374,6 +374,76 @@ def test_checkPermission():
>>> 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()
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