Use named permissions
authorThierry Florac <thierry.florac@onf.fr>
Thu, 08 Oct 2015 09:31:45 +0200
changeset 54 59683c264d94
parent 53 68678e37a77a
child 55 5713898178f3
Use named permissions
src/pyams_security/__init__.py
src/pyams_security/views/utility.py
src/pyams_security/zmi/interfaces.py
src/pyams_security/zmi/notification.py
src/pyams_security/zmi/plugin/admin.py
src/pyams_security/zmi/plugin/group.py
src/pyams_security/zmi/plugin/social.py
src/pyams_security/zmi/plugin/userfolder.py
src/pyams_security/zmi/security.py
src/pyams_security/zmi/utility.py
--- a/src/pyams_security/__init__.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/__init__.py	Thu Oct 08 09:31:45 2015 +0200
@@ -19,6 +19,9 @@
 from pyramid.i18n import TranslationStringFactory
 _ = TranslationStringFactory('pyams_security')
 
+from pyams_utils.interfaces import PUBLIC_PERMISSION, VIEW_PERMISSION, MANAGE_PERMISSION, VIEW_SYSTEM_PERMISSION, \
+    MANAGE_SYSTEM_PERMISSION, MANAGE_SECURITY_PERMISSION, MANAGE_ROLES_PERMISSION
+
 
 def includeme(config):
     """Pyramid include
@@ -29,25 +32,26 @@
     include_package(config)
 
     # register custom permissions
-    config.register_permission({'id': 'public',
+    config.register_permission({'id': PUBLIC_PERMISSION,
                                 'title': _("View public contents")})
-    config.register_permission({'id': 'view',
+    config.register_permission({'id': VIEW_PERMISSION,
                                 'title': _("View protected contents")})
-    config.register_permission({'id': 'manage',
+    config.register_permission({'id': MANAGE_PERMISSION,
                                 'title': _("Manage contents properties")})
-    config.register_permission({'id': 'system.view',
+    config.register_permission({'id': VIEW_SYSTEM_PERMISSION,
                                 'title': _("View management screens")})
-    config.register_permission({'id': 'system.manage',
+    config.register_permission({'id': MANAGE_SYSTEM_PERMISSION,
                                 'title': _("Manage system properties")})
 
-    config.register_permission({'id': 'security.manage',
+    config.register_permission({'id': MANAGE_SECURITY_PERMISSION,
                                 'title': _("Manage security")})
-    config.register_permission({'id': 'security.manage_roles',
+    config.register_permission({'id': MANAGE_ROLES_PERMISSION,
                                 'title': _("Manage roles")})
 
     # register custom roles
     config.register_role({'id': 'system.Manager',
                           'title': "System manager (role)",
-                          'permissions': {'public', 'view', 'manage', 'system.manage', 'system.view',
-                                          'security.manage', 'security.manage_roles'},
+                          'permissions': {PUBLIC_PERMISSION, VIEW_PERMISSION, MANAGE_PERMISSION,
+                                          MANAGE_SYSTEM_PERMISSION, VIEW_SYSTEM_PERMISSION,
+                                          MANAGE_SECURITY_PERMISSION, MANAGE_ROLES_PERMISSION},
                           'managers': {'system:admin', 'role:system.Manager'}})
--- a/src/pyams_security/views/utility.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/views/utility.py	Thu Oct 08 09:31:45 2015 +0200
@@ -18,6 +18,7 @@
 # import interfaces
 from pyams_security.interfaces import ISecurityManager
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
 
 # import packages
 from pyams_utils.registry import query_utility
@@ -25,7 +26,7 @@
 
 
 @view_config(name='find-principals.json', request_type=IPyAMSLayer,
-             permission='system.view', renderer='json', xhr=True)
+             permission=VIEW_SYSTEM_PERMISSION, renderer='json', xhr=True)
 def find_principals(request):
     """Find all principals matching given query"""
     query = request.params.get('query')
--- a/src/pyams_security/zmi/interfaces.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/interfaces.py	Thu Oct 08 09:31:45 2015 +0200
@@ -23,3 +23,7 @@
 
 class ISecurityManagerMenu(IMenuItem):
     """Security manager menu interface"""
+
+
+class IObjectSecurityMenu(IMenuItem):
+    """Object security menu"""
--- a/src/pyams_security/zmi/notification.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/notification.py	Thu Oct 08 09:31:45 2015 +0200
@@ -20,6 +20,7 @@
 from pyams_security.interfaces.notification import INotificationSettings
 from pyams_security.zmi.interfaces import ISecurityManagerMenu
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
 from pyams_zmi.layer import IAdminLayer
 from zope.component.interfaces import ISite
 
@@ -38,7 +39,7 @@
 
 
 @viewlet_config(name='notifications.menu', context=ISite, layer=IAdminLayer, manager=ISecurityManagerMenu,
-                permission='system.view', weight=2)
+                permission=VIEW_SYSTEM_PERMISSION, weight=2)
 class SecurityManagerNotificationsMenuItem(MenuItem):
     """Notifications properties menu item"""
 
@@ -51,7 +52,8 @@
         return resource_url(manager, self.request, self.url)
 
 
-@pagelet_config(name='notifications.html', context=ISecurityManager, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='notifications.html', context=ISecurityManager, layer=IPyAMSLayer,
+                permission=VIEW_SYSTEM_PERMISSION)
 class SecurityManagerNotificationsEditForm(AdminDialogEditForm):
     """Security manager notifications edit form"""
 
@@ -63,6 +65,7 @@
 
     fields = field.Fields(INotificationSettings)
     ajax_handler = 'notifications.json'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def getContent(self):
         return query_utility(ISecurityManager)
@@ -73,6 +76,6 @@
 
 
 @view_config(name='notifications.json', context=ISecurityManager, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SecurityManagerNotificationsAJAXEditForm(AJAXEditForm, SecurityManagerNotificationsEditForm):
     """Security manager notifications edit form, AJAX view"""
--- a/src/pyams_security/zmi/plugin/admin.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/plugin/admin.py	Thu Oct 08 09:31:45 2015 +0200
@@ -12,22 +12,24 @@
 
 __docformat__ = 'restructuredtext'
 
+
 # import standard library
 
 # import interfaces
+from pyams_form.interfaces.form import IFormHelp
 from pyams_security.interfaces import IAdminAuthenticationPlugin, ISecurityManager
-from pyams_skin.interfaces import IContentHelp
 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
 from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
 from zope.component.interfaces import ISite
 
 # import packages
 from pyams_form.form import AJAXAddForm, AJAXEditForm
+from pyams_form.help import FormHelp
 from pyams_pagelet.pagelet import pagelet_config
 from pyams_security.plugin.admin import AdminAuthenticationPlugin
 from pyams_security.zmi.utility import SecurityManagerPluginsTable
-from pyams_skin.help import ContentHelp
 from pyams_skin.viewlet.toolbar import ToolbarMenuItem
 from pyams_utils.adapter import adapter_config
 from pyams_utils.registry import query_utility
@@ -45,7 +47,7 @@
 
 @viewlet_config(name='add-admin-authentication.menu', context=ISite, layer=IAdminLayer,
                 view=SecurityManagerPluginsTable, manager=IToolbarAddingMenu,
-                permission='system.manage', weight=1)
+                permission=MANAGE_SYSTEM_PERMISSION, weight=1)
 class AdminAuthenticationAddMenu(ToolbarMenuItem):
     """Admin authentication add menu"""
 
@@ -56,7 +58,7 @@
 
 
 @pagelet_config(name='add-admin-authentication.html', context=ISite, layer=IPyAMSLayer,
-                permission='system.manage')
+                permission=MANAGE_SYSTEM_PERMISSION)
 class AdminAuthenticationAddForm(AdminDialogAddForm):
     """Admin authentication plug-in add form"""
 
@@ -67,7 +69,7 @@
     fields = field.Fields(IAdminAuthenticationPlugin).omit('__name__', '__parent__')
     autocomplete = 'off'
     ajax_handler = 'add-admin-authentication.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def create(self, data):
         return AdminAuthenticationPlugin()
@@ -90,13 +92,13 @@
 
 
 @view_config(name='add-admin-authentication.json', context=ISite, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class AdminAuthenticationAJAXAddForm(AJAXAddForm, AdminAuthenticationAddForm):
     """Admin authentication plug-in add form, AJAX handler"""
 
 
 @pagelet_config(name='properties.html', context=IAdminAuthenticationPlugin, layer=IPyAMSLayer,
-                permission='system.view')
+                permission=VIEW_SYSTEM_PERMISSION)
 class AdminAuthenticationEditForm(AdminDialogEditForm):
     """Admin authentication plug-in edit form"""
 
@@ -110,7 +112,7 @@
     fields = field.Fields(IAdminAuthenticationPlugin).omit('__name__', '__parent__')
     autocomplete = 'off'
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(AdminAuthenticationEditForm, self).updateWidgets()
@@ -118,13 +120,13 @@
 
 
 @view_config(name='properties.json', context=IAdminAuthenticationPlugin, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class AdminAuthenticationAJAXEditForm(AJAXEditForm, AdminAuthenticationEditForm):
     """Admin authentication plug-in edit form, AJAX handler"""
 
 
-@adapter_config(context=(IAdminAuthenticationPlugin, IAdminLayer, AdminAuthenticationEditForm), provides=IContentHelp)
-class AdminAuthenticationHelpAdapter(ContentHelp):
+@adapter_config(context=(IAdminAuthenticationPlugin, IAdminLayer, AdminAuthenticationEditForm), provides=IFormHelp)
+class AdminAuthenticationHelpAdapter(FormHelp):
     """Admin authentication edit form help adapter"""
 
     header = _("WARNING")
--- a/src/pyams_security/zmi/plugin/group.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/plugin/group.py	Thu Oct 08 09:31:45 2015 +0200
@@ -20,6 +20,7 @@
 from pyams_skin.interfaces import IPageHeader, IInnerPage
 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
 from pyams_zmi.layer import IAdminLayer
 from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
 from z3c.table.interfaces import IColumn, IValues
@@ -55,7 +56,7 @@
 
 @viewlet_config(name='add-groups-folder.menu', context=ISite, layer=IAdminLayer,
                 view=SecurityManagerPluginsTable, manager=IToolbarAddingMenu,
-                permission='system.manage', weight=20)
+                permission=MANAGE_SYSTEM_PERMISSION, weight=20)
 class GroupsFolderAddMenu(ToolbarMenuItem):
     """Local groups folder add menu"""
 
@@ -66,7 +67,7 @@
 
 
 @pagelet_config(name='add-groups-folder.html', context=ISite, layer=IPyAMSLayer,
-                permission='system.manage')
+                permission=MANAGE_SYSTEM_PERMISSION)
 class GroupsFolderAddForm(AdminDialogAddForm):
     """Groups folder plug-in add form"""
 
@@ -99,13 +100,13 @@
 
 
 @view_config(name='add-groups-folder.json', context=ISite, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class GroupsFolderAJAXAddForm(AJAXAddForm, GroupsFolderAddForm):
     """Groups folder plug-in add form, AJAX handler"""
 
 
 @pagelet_config(name='properties.html', context=IGroupsFolderPlugin, layer=IPyAMSLayer,
-                permission='system.view')
+                permission=VIEW_SYSTEM_PERMISSION)
 class GroupsFolderEditForm(AdminDialogEditForm):
     """Groups folder plug-in edit form"""
 
@@ -118,7 +119,7 @@
 
     fields = field.Fields(IGroupsFolderPlugin).omit('__name__', '__parent__')
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(GroupsFolderEditForm, self).updateWidgets()
@@ -126,7 +127,7 @@
 
 
 @view_config(name='properties.json', context=IGroupsFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class GroupsFolderAJAXEditForm(AJAXEditForm, GroupsFolderEditForm):
     """Groups folder plug-in edit form, AJAX handler"""
 
@@ -175,7 +176,7 @@
         return super(DescriptionColumn, self).getValue(obj) or ''
 
 
-@pagelet_config(name='search.html', context=IGroupsFolderPlugin, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='search.html', context=IGroupsFolderPlugin, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 @implementer(IInnerPage)
 class GroupsFolderSearchView(AdminView, ContainerView):
     """Groups folder search view"""
@@ -205,7 +206,7 @@
 
 @viewlet_config(name='groups-folder.toolbar.adding', context=IGroupsFolderPlugin,
                 view=GroupsFolderContentsTable, layer=IAdminLayer,
-                manager=IWidgetTitleViewletManager, permission='system.manage')
+                manager=IWidgetTitleViewletManager, permission=MANAGE_SYSTEM_PERMISSION)
 class LocalGroupAddAction(ToolbarAction):
     """Groups folder adding action"""
 
@@ -214,7 +215,8 @@
     modal_target = True
 
 
-@pagelet_config(name='add-group.html', context=IGroupsFolderPlugin, layer=IPyAMSLayer, permission='system.manage')
+@pagelet_config(name='add-group.html', context=IGroupsFolderPlugin, layer=IPyAMSLayer,
+                permission=MANAGE_SYSTEM_PERMISSION)
 class LocalGroupAddForm(AdminDialogAddForm):
     """Local group add form"""
 
@@ -230,7 +232,7 @@
     fields = field.Fields(ILocalGroup).omit('__parent__', '__name__')
 
     ajax_handler = 'add-group.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(LocalGroupAddForm, self).updateWidgets()
@@ -259,7 +261,7 @@
 
 
 @view_config(name='add-group.json', context=IGroupsFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class LocalGroupAJAXAddForm(AJAXAddForm, LocalGroupAddForm):
     """Local group add form, AJAX view"""
 
@@ -270,7 +272,7 @@
                 'message': translate(_("Group was created successfully"))}
 
 
-@pagelet_config(name='properties.html', context=ILocalGroup, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='properties.html', context=ILocalGroup, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 class LocalGroupEditForm(AdminDialogEditForm):
     """Local group edit form"""
 
@@ -286,7 +288,7 @@
     fields = field.Fields(ILocalGroup).omit('__parent__', '__name__')
 
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(LocalGroupEditForm, self).updateWidgets()
@@ -294,7 +296,7 @@
 
 
 @view_config(name='properties.json', context=ILocalGroup, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class LocalGroupAJAXEditForm(AJAXEditForm, LocalGroupEditForm):
     """Local group edit form, AJAX view"""
 
--- a/src/pyams_security/zmi/plugin/social.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/plugin/social.py	Thu Oct 08 09:31:45 2015 +0200
@@ -22,6 +22,7 @@
 from pyams_skin.interfaces import IPageHeader, IInnerPage
 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
 from pyams_zmi.layer import IAdminLayer
 from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
 from z3c.table.interfaces import IColumn, IValues
@@ -62,7 +63,7 @@
 
 @viewlet_config(name='add-social-users-folder.menu', context=ISite, layer=IAdminLayer,
                 view=SecurityManagerPluginsTable, manager=IToolbarAddingMenu,
-                permission='system.manage', weight=50)
+                permission=MANAGE_SYSTEM_PERMISSION, weight=50)
 class SocialUsersFolderAddMenu(ToolbarMenuItem):
     """Social users folder add menu"""
 
@@ -73,7 +74,7 @@
 
 
 @pagelet_config(name='add-social-users-folder.html', context=ISite, layer=IPyAMSLayer,
-                permission='system.manage')
+                permission=MANAGE_SYSTEM_PERMISSION)
 class SocialUsersFolderAddForm(AdminDialogAddForm):
     """Social users folder plug-in add form"""
 
@@ -83,7 +84,7 @@
 
     fields = field.Fields(ISocialUsersFolderPlugin).omit('__name__', '__parent__')
     ajax_handler = 'add-social-users-folder.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def create(self, data):
         return SocialUsersFolder()
@@ -106,13 +107,13 @@
 
 
 @view_config(name='add-social-users-folder.json', context=ISite, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SocialUsersFolderAJAXAddForm(AJAXAddForm, SocialUsersFolderAddForm):
     """Social users folder plug-in add form, AJAX handler"""
 
 
 @pagelet_config(name='properties.html', context=ISocialUsersFolderPlugin, layer=IPyAMSLayer,
-                permission='system.view')
+                permission=VIEW_SYSTEM_PERMISSION)
 class SocialUsersFolderEditForm(AdminDialogEditForm):
     """Social users folder plug-in edit form"""
 
@@ -125,7 +126,7 @@
 
     fields = field.Fields(ISocialUsersFolderPlugin).omit('__name__', '__parent__')
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(SocialUsersFolderEditForm, self).updateWidgets()
@@ -133,7 +134,7 @@
 
 
 @view_config(name='properties.json', context=ISocialUsersFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SocialUsersFolderAJAXEditForm(AJAXEditForm, SocialUsersFolderEditForm):
     """Social users folder plug-in edit form, AJAX handler"""
 
@@ -142,7 +143,8 @@
 # Social users folder search views
 #
 
-@pagelet_config(name='search.html', context=ISocialUsersFolderPlugin, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='search.html', context=ISocialUsersFolderPlugin, layer=IPyAMSLayer,
+                permission=VIEW_SYSTEM_PERMISSION)
 class SocialUsersFolderSearchView(AdminView, SearchView):
     """Social users folder search view"""
     
@@ -165,7 +167,7 @@
 
 
 @view_config(name='search-results.html', context=ISocialUsersFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.view')
+             permission=VIEW_SYSTEM_PERMISSION)
 class SocialUsersFolderSearchResultsView(AdminView, SearchResultsView):
     """Social users folder search results view table"""
 
@@ -238,7 +240,7 @@
 # Social users views
 #
 
-@pagelet_config(name='properties.html', context=ISocialUser, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='properties.html', context=ISocialUser, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 class SocialUserEditForm(AdminDialogEditForm):
     """Social user edit form"""
 
@@ -254,7 +256,7 @@
     fields = field.Fields(ISocialUser).omit('__parent__', '__name__', 'attributes')
 
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(SocialUserEditForm, self).updateWidgets()
@@ -264,7 +266,7 @@
 
 
 @view_config(name='properties.json', context=ISocialUser, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SocialUserAJAXEditForm(AJAXEditForm, SocialUserEditForm):
     """Social user edit form, AJAX view"""
 
@@ -274,7 +276,7 @@
 #
 
 @viewlet_config(name='security-manager.social.menu', context=ISite, layer=IAdminLayer,
-                manager=ISecurityManagerMenu, permission='system.view', weight=10)
+                manager=ISecurityManagerMenu, permission=VIEW_SYSTEM_PERMISSION, weight=10)
 class SecurityManagerSocialMenuItem(MenuItem):
     """Security manager social menu"""
 
@@ -336,7 +338,7 @@
     """Security manager plugins trash column"""
 
     icon_hint = _("Delete provider")
-    permission = 'system.manage'
+    permission = MANAGE_SYSTEM_PERMISSION
 
 
 @adapter_config(context=(ISite, IAdminLayer, SecurityManagerSocialProvidersTable), provides=IValues)
@@ -352,7 +354,7 @@
         return ()
 
 
-@pagelet_config(name='social-providers.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='social-providers.html', context=ISite, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 @implementer(IInnerPage)
 class SecurityManagerSocialProvidersView(AdminView, ContainerView):
     """Security manager social providers view"""
@@ -373,7 +375,7 @@
 
 
 @viewlet_config(name='security-manager.social.adding', context=ISite, view=SecurityManagerSocialProvidersTable,
-                layer=IAdminLayer, manager=IWidgetTitleViewletManager, permission='system.manage')
+                layer=IAdminLayer, manager=IWidgetTitleViewletManager, permission=MANAGE_SYSTEM_PERMISSION)
 class SocialToolbarAddingsAction(ToolbarAction):
     """Security manager social toolbar adding action"""
 
@@ -382,7 +384,7 @@
     modal_target = True
 
 
-@pagelet_config(name='add-social-provider.html', context=ISite, layer=IPyAMSLayer, permission='system.manage')
+@pagelet_config(name='add-social-provider.html', context=ISite, layer=IPyAMSLayer, permission=MANAGE_SYSTEM_PERMISSION)
 class SocialProviderAddForm(AdminDialogAddForm):
     """Social provider add form"""
 
@@ -395,7 +397,7 @@
     fields = field.Fields(ISocialLoginProviderConnection).omit('__parent__', '__name__')
 
     ajax_handler = 'add-social-provider.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(SocialProviderAddForm, self).updateWidgets()
@@ -425,7 +427,7 @@
 
 
 @view_config(name='add-social-provider.json', context=ISite, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SocialProviderAJAXAddForm(AJAXAddForm, SocialProviderAddForm):
     """Social provider add form, AJAX view"""
 
@@ -437,7 +439,7 @@
 
 
 @pagelet_config(name='properties.html', context=ISocialLoginProviderConnection, layer=IPyAMSLayer,
-                permission='system.view')
+                permission=VIEW_SYSTEM_PERMISSION)
 class SocialProviderEditForm(AdminDialogEditForm):
     """Social provider edit form"""
 
@@ -450,7 +452,7 @@
     fields = field.Fields(ISocialLoginProviderConnection).omit('__parent__', '__name__')
 
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(SocialProviderEditForm, self).updateWidgets()
@@ -459,13 +461,13 @@
 
 
 @view_config(name='properties.json', context=ISocialLoginProviderConnection, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SocialProviderAJAXEditForm(AJAXEditForm, SocialProviderEditForm):
     """Social provider edit form, AJAX view"""
 
 
 @view_config(name='delete-provider.json', context=ISocialLoginConfiguration, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 def delete_social_provider(request):
     """Delete social provider from security manager"""
     translate = request.localizer.translate
--- a/src/pyams_security/zmi/plugin/userfolder.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/plugin/userfolder.py	Thu Oct 08 09:31:45 2015 +0200
@@ -22,6 +22,7 @@
 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
 from pyams_skin.interfaces import IPageHeader
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
 from pyams_zmi.layer import IAdminLayer
 from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
 from z3c.table.interfaces import IColumn
@@ -59,7 +60,7 @@
 
 @viewlet_config(name='add-users-folder.menu', context=ISite, layer=IAdminLayer,
                 view=SecurityManagerPluginsTable, manager=IToolbarAddingMenu,
-                permission='system.manage', weight=10)
+                permission=MANAGE_SYSTEM_PERMISSION, weight=10)
 class UsersFolderAddMenu(ToolbarMenuItem):
     """Local users folder add menu"""
 
@@ -70,7 +71,7 @@
 
 
 @pagelet_config(name='add-users-folder.html', context=ISite, layer=IPyAMSLayer,
-                permission='system.manage')
+                permission=MANAGE_SYSTEM_PERMISSION)
 class UsersFolderAddForm(AdminDialogAddForm):
     """Users folder plug-in add form"""
 
@@ -80,7 +81,7 @@
 
     fields = field.Fields(IUsersFolderPlugin).omit('__name__', '__parent__')
     ajax_handler = 'add-users-folder.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def create(self, data):
         return UsersFolder()
@@ -103,13 +104,13 @@
 
 
 @view_config(name='add-users-folder.json', context=ISite, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class UsersFolderAJAXAddForm(AJAXAddForm, UsersFolderAddForm):
     """users folder plug-in add form, AJAX handler"""
 
 
 @pagelet_config(name='properties.html', context=IUsersFolderPlugin, layer=IPyAMSLayer,
-                permission='system.view')
+                permission=VIEW_SYSTEM_PERMISSION)
 class UsersFolderEditForm(AdminDialogEditForm):
     """Users folder plug-in edit form"""
 
@@ -122,7 +123,7 @@
 
     fields = field.Fields(IUsersFolderPlugin).omit('__name__', '__parent__')
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(UsersFolderEditForm, self).updateWidgets()
@@ -130,7 +131,7 @@
 
 
 @view_config(name='properties.json', context=IUsersFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class UsersFolderAJAXEditForm(AJAXEditForm, UsersFolderEditForm):
     """Users folder plug-in edit form, AJAX handler"""
 
@@ -139,7 +140,7 @@
 # Users folder search views
 #
 
-@pagelet_config(name='search.html', context=IUsersFolderPlugin, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='search.html', context=IUsersFolderPlugin, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 class UsersFolderSearchView(AdminView, SearchView):
     """Users folder search view"""
     
@@ -161,7 +162,7 @@
 
 
 @view_config(name='search-results.html', context=IUsersFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.view')
+             permission=VIEW_SYSTEM_PERMISSION)
 class UsersFolderSearchResultsView(AdminView, SearchResultsView):
     """Users folder search results view table"""
 
@@ -241,7 +242,7 @@
 
 @viewlet_config(name='users-folder.toolbar.adding', context=IUsersFolderPlugin,
                 view=UsersFolderSearchView.search_form_factory, layer=IAdminLayer,
-                manager=IWidgetTitleViewletManager, permission='system.manage')
+                manager=IWidgetTitleViewletManager, permission=MANAGE_SYSTEM_PERMISSION)
 class LocalUserAddAction(ToolbarAction):
     """Users folder adding action"""
 
@@ -250,7 +251,8 @@
     modal_target = True
 
 
-@pagelet_config(name='add-user.html', context=IUsersFolderPlugin, layer=IPyAMSLayer, permission='system.manage')
+@pagelet_config(name='add-user.html', context=IUsersFolderPlugin, layer=IPyAMSLayer,
+                permission=MANAGE_SYSTEM_PERMISSION)
 class LocalUserAddForm(AdminDialogAddForm):
     """Local user add form"""
 
@@ -270,7 +272,7 @@
 
     autocomplete = 'off'
     ajax_handler = 'add-user.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(LocalUserAddForm, self).updateWidgets()
@@ -312,7 +314,7 @@
 
 
 @view_config(name='add-user.json', context=IUsersFolderPlugin, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class LocalUserAJAXAddForm(AJAXAddForm, LocalUserAddForm):
     """Local user add form, AJAX view"""
 
@@ -322,7 +324,7 @@
                 'message': translate(_("User was created successfully"))}
 
 
-@pagelet_config(name='properties.html', context=ILocalUser, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='properties.html', context=ILocalUser, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 class LocalUserEditForm(AdminDialogEditForm):
     """Local user edit form"""
 
@@ -339,7 +341,7 @@
                                              'self_registered', 'activation_hash', 'activation_date')
 
     ajax_handler = 'properties.json'
-    edit_permission = 'system.manage'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def updateWidgets(self, prefix=None):
         super(LocalUserEditForm, self).updateWidgets()
@@ -349,6 +351,6 @@
 
 
 @view_config(name='properties.json', context=ILocalUser, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class LocalUserAJAXEditForm(AJAXEditForm, LocalUserEditForm):
     """Local user edit form, AJAX view"""
--- a/src/pyams_security/zmi/security.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/security.py	Thu Oct 08 09:31:45 2015 +0200
@@ -16,92 +16,69 @@
 # import standard library
 
 # import interfaces
-from pyams_form.interfaces.form import IInnerSubForm
+from pyams_form.interfaces.form import IWidgetForm
 from pyams_security.interfaces import IDefaultProtectionPolicy, IProtectedObject, IRole
+from pyams_security.zmi.interfaces import IObjectSecurityMenu
+from pyams_skin.interfaces import IInnerPage, IPageHeader
 from pyams_skin.layer import IPyAMSLayer
-from pyams_zmi.interfaces.menu import IPropertiesMenu
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SECURITY_PERMISSION, MANAGE_ROLES_PERMISSION
+from pyams_zmi.interfaces.menu import ISiteManagementMenu
 from pyams_zmi.layer import IAdminLayer
 from z3c.form.interfaces import DISPLAY_MODE, INPUT_MODE
 
 # import packages
-from pyams_form.form import AJAXEditForm, InnerEditForm
+from pyams_form.form import AJAXEditForm
 from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.viewlet.menu import MenuItem, MenuDivider
+from pyams_skin.page import DefaultPageHeaderAdapter
+from pyams_skin.viewlet.menu import MenuItem
 from pyams_utils.adapter import adapter_config
 from pyams_utils.registry import get_utility
+from pyams_viewlet.manager import viewletmanager_config
 from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.form import AdminDialogEditForm
+from pyams_zmi.form import AdminEditForm, AdminDialogEditForm
 from pyramid.view import view_config
 from z3c.form import field
-from zope.interface import Interface
+from zope.interface import implementer, Interface
 
 from pyams_security import _
 
 
-@viewlet_config(name='protected-object-roles.divider', context=IDefaultProtectionPolicy, layer=IAdminLayer,
-                manager=IPropertiesMenu, permission='system.view', weight=899)
-class ProtectedObjectRolesMenuDivider(MenuDivider):
-    """Protected object roles menu divider"""
-
+#
+# Object roles edit form
+#
 
 @viewlet_config(name='protected-object-roles.menu', context=IDefaultProtectionPolicy, layer=IAdminLayer,
-                manager=IPropertiesMenu, permission='system.view', weight=900)
+                manager=ISiteManagementMenu, permission=VIEW_SYSTEM_PERMISSION, weight=900)
+@viewletmanager_config(name='protected-object-roles.menu', layer=IAdminLayer, context=IDefaultProtectionPolicy,
+                       provides=IObjectSecurityMenu)
+@implementer(IObjectSecurityMenu)
 class ProtectedObjectRolesMenuItem(MenuItem):
     """Protected object roles menu item"""
 
-    label = _("Access rules...")
-    icon_class = 'fa-key'
-    url = 'protected-object-roles.html'
-    modal_target = True
+    label = _("Access rules")
+    icon_class = 'fa-users'
+    url = '#protected-object-roles.html'
+    modal_target = False
 
 
 @pagelet_config(name='protected-object-roles.html', context=IDefaultProtectionPolicy, layer=IPyAMSLayer,
-                permission='system.view')
-class ProtectedObjectRolesEditForm(AdminDialogEditForm):
+                permission=VIEW_SYSTEM_PERMISSION)
+@implementer(IWidgetForm, IInnerPage)
+class ProtectedObjectRolesEditForm(AdminEditForm):
     """Protected object roles edit form"""
 
-    legend = None
-    fieldset_class = 'no-padding'
-
-    fields = field.Fields(Interface)
-    ajax_handler = 'protected-object-roles.json'
-    edit_permission = None
-
-
-@adapter_config(name='security.subform',
-                context=(IDefaultProtectionPolicy, IPyAMSLayer, ProtectedObjectRolesEditForm),
-                provides=IInnerSubForm)
-class ProtectedObjectSecuritySubform(InnerEditForm):
-    """Protected object security sub-form"""
-
-    legend = _("Security management")
-    icon_css_class = 'fa fa-fw fa-key'
-    label_css_class = 'control-label col-md-4'
-    input_css_class = 'col-md-8'
-
-    fields = field.Fields(IProtectedObject)
-    edit_permission = 'security.manage'
-    weight = 1
-
-
-@adapter_config(name='roles.subform',
-                context=(IDefaultProtectionPolicy, IPyAMSLayer, ProtectedObjectRolesEditForm),
-                provides=IInnerSubForm)
-class ProtectedObjectRolesSubform(InnerEditForm):
-    """Protected object roles edit form"""
-
-    legend = _("Granted roles")
+    legend = _("Granted users roles")
     icon_css_class = 'fa fa-fw fa-users'
 
     @property
     def fields(self):
         return field.Fields(self.context.roles_interface)
 
-    edit_permission = 'security.manage_roles'
-    weight = 2
+    ajax_handler = 'protected-object-roles.json'
+    edit_permission = MANAGE_ROLES_PERMISSION
 
     def updateWidgets(self, prefix=None):
-        super(ProtectedObjectRolesSubform, self).updateWidgets(prefix)
+        super(ProtectedObjectRolesEditForm, self).updateWidgets(prefix)
         if self.mode == DISPLAY_MODE:
             return
         principals = self.request.effective_principals
@@ -112,9 +89,53 @@
                 for manager in role.managers:
                     if manager in principals:
                         widget.mode = INPUT_MODE
+                        continue
 
 
 @view_config(name='protected-object-roles.json', context=IDefaultProtectionPolicy, request_type=IPyAMSLayer,
-             permission='security.manage', renderer='json', xhr=True)
+             permission=MANAGE_ROLES_PERMISSION, renderer='json', xhr=True)
 class ProtectedObjectRolesAJAXEditForm(AJAXEditForm, ProtectedObjectRolesEditForm):
     """Protected object roles edit form, AJAX view"""
+
+
+@adapter_config(context=(Interface, IPyAMSLayer, ProtectedObjectRolesEditForm), provides=IPageHeader)
+class ProtectedObjectRolesEditFormHeaderAdapter(DefaultPageHeaderAdapter):
+    """Protected object security edit form header adapter"""
+
+    icon_class = 'fa fa-fw fa-users'
+
+
+#
+# Security policy edit form
+#
+
+@viewlet_config(name='security-policy.menu', context=IDefaultProtectionPolicy, layer=IAdminLayer,
+                manager=IObjectSecurityMenu, permission=MANAGE_SECURITY_PERMISSION, weight=10)
+class ProtectedObjectSecurityPolicyMenuItem(MenuItem):
+    """Protected object security policy menu item"""
+
+    label = _("Security policy...")
+    icon_class = 'fa-key'
+    url = 'security-policy.html'
+    modal_target = True
+
+
+@pagelet_config(name='security-policy.html', context=IDefaultProtectionPolicy, layer=IPyAMSLayer,
+                permission=MANAGE_SECURITY_PERMISSION)
+class ProtectedObjectSecurityPolicyEditForm(AdminDialogEditForm):
+    """Protected object security policy edit form"""
+
+    legend = _("Update security policy")
+    icon_css_class = 'fa fa-fw fa-key'
+
+    fields = field.Fields(IProtectedObject)
+    ajax_handler = 'security-policy.json'
+    edit_permission = MANAGE_SECURITY_PERMISSION
+
+    dialog_class = 'modal-large'
+
+
+@view_config(name='security-policy.json', context=IDefaultProtectionPolicy, request_type=IPyAMSLayer,
+             permission=MANAGE_SECURITY_PERMISSION, renderer='json', xhr=True)
+class ProtectedObjectSecurityPolicyAJAXEditForm(AJAXEditForm, ProtectedObjectSecurityPolicyEditForm):
+    """Protected object security policy edit form, JSON renderer"""
--- a/src/pyams_security/zmi/utility.py	Thu Oct 08 09:30:56 2015 +0200
+++ b/src/pyams_security/zmi/utility.py	Thu Oct 08 09:31:45 2015 +0200
@@ -21,6 +21,7 @@
 from pyams_skin.interfaces import IInnerPage, IPageHeader
 from pyams_skin.interfaces.container import ITableElementEditor
 from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
 from pyams_zmi.interfaces.menu import IControlPanelMenu
 from pyams_zmi.layer import IAdminLayer
 from z3c.table.interfaces import IValues, IColumn
@@ -67,7 +68,7 @@
 
 
 @viewlet_config(name='security-manager.menu', context=ISite, layer=IAdminLayer, manager=IControlPanelMenu,
-                permission='system.view', weight=5)
+                permission=VIEW_SYSTEM_PERMISSION, weight=5)
 @viewletmanager_config(name='security-manager.menu', context=ISite, layer=IAdminLayer)
 @implementer(ISecurityManagerMenu)
 class SecurityManagerMenuItem(MenuItem):
@@ -127,7 +128,7 @@
     """Security manager plugins trash column"""
 
     icon_hint = _("Delete plug-in")
-    permission = 'system.manage'
+    permission = MANAGE_SYSTEM_PERMISSION
 
     checker = lambda col, x: x.__name__ != '__system__'
 
@@ -144,7 +145,7 @@
         return ()
 
 
-@pagelet_config(name='security-manager.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='security-manager.html', context=ISite, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 @implementer(IInnerPage)
 class SecurityManagerView(AdminView, ContainerView):
     """Security manager view"""
@@ -162,7 +163,7 @@
 
 
 @viewlet_config(name='security-manager.properties.menu', context=ISite, layer=IAdminLayer,
-                manager=ISecurityManagerMenu, permission='system.view', weight=1)
+                manager=ISecurityManagerMenu, permission=VIEW_SYSTEM_PERMISSION, weight=1)
 class SecurityManagerPropertiesMenuItem(MenuItem):
     """Security manager properties menu"""
 
@@ -175,7 +176,7 @@
         return resource_url(manager, self.request, self.url)
 
 
-@pagelet_config(name='properties.html', context=ISecurityManager, layer=IPyAMSLayer, permission='system.view')
+@pagelet_config(name='properties.html', context=ISecurityManager, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
 class SecurityManagerEditForm(AdminDialogEditForm):
     """Security manager edit form"""
 
@@ -193,6 +194,7 @@
     fields['directory_plugins_names'].widgetFactory = OrderedPluginsFieldWidget
 
     ajax_handler = 'properties.json'
+    edit_permission = MANAGE_SYSTEM_PERMISSION
 
     def getContent(self):
         return query_utility(ISecurityManager)
@@ -225,13 +227,13 @@
 
 
 @view_config(name='properties.json', context=ISecurityManager, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 class SecurityManagerAJAXEditForm(AJAXEditForm, SecurityManagerEditForm):
     """Security manager edit form, AJAX view"""
 
 
 @view_config(name='delete-plugin.json', context=ISecurityManager, request_type=IPyAMSLayer,
-             permission='system.manage', renderer='json', xhr=True)
+             permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
 def delete_security_manager_plugin(request):
     """Delete plug-in from security manager"""
     translate = request.localizer.translate