src/pyams_security/role.py
changeset 2 94e76f8e9828
parent 0 f04e1d0a0723
child 42 07229ac2497b
--- a/src/pyams_security/role.py	Sun Feb 22 14:52:32 2015 +0100
+++ b/src/pyams_security/role.py	Mon Feb 23 17:55:05 2015 +0100
@@ -12,14 +12,18 @@
 
 __docformat__ = 'restructuredtext'
 
+
 # import standard library
 
 # import interfaces
 from pyams_security.interfaces import IRole
+from zope.schema.interfaces import IVocabularyFactory
 
 # import packages
-from zope.interface import implementer
+from pyams_utils.request import check_request
+from zope.interface import implementer, provider
 from zope.schema.fieldproperty import FieldProperty
+from zope.schema.vocabulary import getVocabularyRegistry, SimpleVocabulary, SimpleTerm
 
 
 @implementer(IRole)
@@ -45,8 +49,40 @@
 
     Roles registry is not required.
     But only registered roles can be applied via default
-    ZMI features
+    ZMI features.
+
+    If a role is registered several times, previous registrations
+    will just be updated to add new permissions.
+    Title and description are not updated after first registration.
     """
+    registry = config.registry
     if not IRole.providedBy(role):
-        role = Role(role)
-    config.registry.registerUtility(role, IRole, name=role.id)
+        role_utility = registry.queryUtility(IRole, name=role.get('id'))
+        if role_utility is None:
+            # registering a new role
+            role_utility = Role(role)
+            registry.registerUtility(role_utility, IRole, name=role_utility.id)
+        else:
+            # new registration of a given role to add permissions
+            role_utility.permissions = (role_utility.permissions or set()) | \
+                                       (role.get('permissions') or set())
+    else:
+        registry.registerUtility(role, IRole, name=role.id)
+
+
+@provider(IVocabularyFactory)
+class RolesVocabulary(SimpleVocabulary):
+    """Roles vocabulary"""
+
+    interface = IRole
+
+    def __init__(self, *args, **kwargs):
+        request = check_request()
+        registry = request.registry
+        translate = request.localizer.translate
+        terms = [SimpleTerm(r.id, title=translate(r.title))
+                 for n, r in registry.getUtilitiesFor(self.interface)]
+        terms.sort(key=lambda x: x.title)
+        super(RolesVocabulary, self).__init__(terms)
+
+getVocabularyRegistry().register('PyAMS roles', RolesVocabulary)