# HG changeset patch # User Thierry Florac # Date 1434527958 -7200 # Node ID 07229ac2497bb9886718d0fdbd903d2e9381ec1f # Parent 905e30f5467b0b4203578b3b59ffdbe952b404ac Version 0.1.0 diff -r 905e30f5467b -r 07229ac2497b .installed.cfg --- a/.installed.cfg Wed May 20 12:31:27 2015 +0200 +++ b/.installed.cfg Wed Jun 17 09:59:18 2015 +0200 @@ -1,26 +1,29 @@ [buildout] -installed_develop_eggs = /home/tflorac/Dropbox/src/PyAMS/pyams_security/develop-eggs/pyams-security.egg-link +installed_develop_eggs = parts = package i18n pyflakes test [package] -__buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pshell - /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pviews +__buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/ptweens + /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/proutes + /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pshell /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pcreate - /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/proutes + /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pdistreport /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/prequest - /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pdistreport - /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/ptweens /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pserve -__buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.1-py3.4.egg zc.buildout-2.3.1-py3.4.egg + /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pviews + /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/zpasswd +__buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.3-py3.4.egg zc.buildout-2.3.1-py3.4.egg _b = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin _d = /home/tflorac/Dropbox/src/PyAMS/pyams_security/develop-eggs _e = /var/local/env/pyams/eggs bin-directory = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin develop-eggs-directory = /home/tflorac/Dropbox/src/PyAMS/pyams_security/develop-eggs -eggs = pyams_security +eggs = authomatic + pyams_security pyramid zope.component zope.interface + zope.password eggs-directory = /var/local/env/pyams/eggs recipe = zc.recipe.egg @@ -28,7 +31,7 @@ __buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pybabel /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pot-create /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/polint -__buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.1-py3.4.egg zc.buildout-2.3.1-py3.4.egg +__buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.3-py3.4.egg zc.buildout-2.3.1-py3.4.egg _b = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin _d = /home/tflorac/Dropbox/src/PyAMS/pyams_security/develop-eggs _e = /var/local/env/pyams/eggs @@ -42,7 +45,7 @@ [pyflakes] __buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pyflakes /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/pyflakes -__buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.1-py3.4.egg zc.buildout-2.3.1-py3.4.egg +__buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.3-py3.4.egg zc.buildout-2.3.1-py3.4.egg _b = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin _d = /home/tflorac/Dropbox/src/PyAMS/pyams_security/develop-eggs _e = /var/local/env/pyams/eggs @@ -58,7 +61,7 @@ [test] __buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_security/parts/test /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin/test -__buildout_signature__ = zc.recipe.testrunner-2.0.0-py3.4.egg zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.1-py3.4.egg zope.testrunner-4.4.6-py3.4.egg zc.buildout-2.3.1-py3.4.egg zope.interface-4.1.2-py3.4-linux-x86_64.egg zope.exceptions-4.0.7-py3.4.egg six-1482e89f68d85eea27f4ed7749df2819 +__buildout_signature__ = zc.recipe.testrunner-2.0.0-py3.4.egg zc.recipe.egg-2.0.1-py3.4.egg setuptools-12.3-py3.4.egg zope.testrunner-4.4.6-py3.4.egg zc.buildout-2.3.1-py3.4.egg zope.interface-4.1.2-py3.4-linux-x86_64.egg zope.exceptions-4.0.7-py3.4.egg six-e6b62e54b4df360c40dfcbb76c1ecf1a _b = /home/tflorac/Dropbox/src/PyAMS/pyams_security/bin _d = /home/tflorac/Dropbox/src/PyAMS/pyams_security/develop-eggs _e = /var/local/env/pyams/eggs diff -r 905e30f5467b -r 07229ac2497b docs/README.txt --- a/docs/README.txt Wed May 20 12:31:27 2015 +0200 +++ b/docs/README.txt Wed Jun 17 09:59:18 2015 +0200 @@ -2,6 +2,16 @@ PyAMS security package ====================== +OAuth +----- + - twitter : F41qIog95eVs07RupYccokWbk + yrEYMT3VnkT4yvCsXvaKDWok5gehU6fjz38e2FTphE8BXaapUA + - facebook : 417712258385794 + 0a2bfc72bdc05caff800b8e46fe8ca64 + - google : 203791088227-a2nuqdo2t74ebv1n0s8houb4jfmjtp1t.apps.googleusercontent.com + gsATqmPQASMtC60OACMcOH0i + + Roles et permissions -------------------- - déclaration des permissions diff -r 905e30f5467b -r 07229ac2497b setup.py --- a/setup.py Wed May 20 12:31:27 2015 +0200 +++ b/setup.py Wed Jun 17 09:59:18 2015 +0200 @@ -61,7 +61,8 @@ 'pyramid', 'zope.component', 'zope.interface', - 'zope.password' + 'zope.password', + 'zope.principalannotation' ], entry_points={ 'fanstatic.libraries': [ diff -r 905e30f5467b -r 07229ac2497b src/pyams_security.egg-info/PKG-INFO --- a/src/pyams_security.egg-info/PKG-INFO Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security.egg-info/PKG-INFO Wed Jun 17 09:59:18 2015 +0200 @@ -10,6 +10,16 @@ PyAMS security package ====================== + OAuth + ----- + - twitter : F41qIog95eVs07RupYccokWbk + yrEYMT3VnkT4yvCsXvaKDWok5gehU6fjz38e2FTphE8BXaapUA + - facebook : 417712258385794 + 0a2bfc72bdc05caff800b8e46fe8ca64 + - google : 203791088227-a2nuqdo2t74ebv1n0s8houb4jfmjtp1t.apps.googleusercontent.com + gsATqmPQASMtC60OACMcOH0i + + Roles et permissions -------------------- - déclaration des permissions diff -r 905e30f5467b -r 07229ac2497b src/pyams_security.egg-info/SOURCES.txt --- a/src/pyams_security.egg-info/SOURCES.txt Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security.egg-info/SOURCES.txt Wed Jun 17 09:59:18 2015 +0200 @@ -6,11 +6,17 @@ src/pyams_security/configure.zcml src/pyams_security/credential.py src/pyams_security/include.py +src/pyams_security/index.py +src/pyams_security/notification.py src/pyams_security/permission.py src/pyams_security/principal.py +src/pyams_security/property.py src/pyams_security/role.py +src/pyams_security/schema.py +src/pyams_security/security.py src/pyams_security/site.py src/pyams_security/utility.py +src/pyams_security/vocabulary.py src/pyams_security.egg-info/PKG-INFO src/pyams_security.egg-info/SOURCES.txt src/pyams_security.egg-info/dependency_links.txt @@ -21,9 +27,45 @@ src/pyams_security.egg-info/top_level.txt src/pyams_security/doctests/README.txt src/pyams_security/interfaces/__init__.py +src/pyams_security/interfaces/notification.py +src/pyams_security/locales/pyams_security.pot +src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.mo +src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.po src/pyams_security/plugin/__init__.py src/pyams_security/plugin/admin.py +src/pyams_security/plugin/group.py src/pyams_security/plugin/http.py +src/pyams_security/plugin/social.py +src/pyams_security/plugin/userfolder.py +src/pyams_security/plugin/templates/register-info.pt +src/pyams_security/plugin/templates/register-message.pt +src/pyams_security/resources/img/behance.ico +src/pyams_security/resources/img/bitbucket.ico +src/pyams_security/resources/img/bitly.ico +src/pyams_security/resources/img/cosm.ico +src/pyams_security/resources/img/deviantart.ico +src/pyams_security/resources/img/facebook.ico +src/pyams_security/resources/img/flickr.ico +src/pyams_security/resources/img/foursquare.ico +src/pyams_security/resources/img/github.ico +src/pyams_security/resources/img/google.ico +src/pyams_security/resources/img/linkedin.ico +src/pyams_security/resources/img/meetup.ico +src/pyams_security/resources/img/paypal.ico +src/pyams_security/resources/img/plurk.ico +src/pyams_security/resources/img/reddit.ico +src/pyams_security/resources/img/tumblr.ico +src/pyams_security/resources/img/twitter.ico +src/pyams_security/resources/img/ubuntuone.ico +src/pyams_security/resources/img/viadeo.ico +src/pyams_security/resources/img/vimeo.ico +src/pyams_security/resources/img/vk.ico +src/pyams_security/resources/img/windows_live.ico +src/pyams_security/resources/img/xero.ico +src/pyams_security/resources/img/xing.ico +src/pyams_security/resources/img/yahoo.ico +src/pyams_security/resources/img/yammer.ico +src/pyams_security/resources/img/yandex.ico src/pyams_security/resources/js/authomatic.js src/pyams_security/resources/js/authomatic.min.js src/pyams_security/resources/js/security.js @@ -34,10 +76,31 @@ src/pyams_security/views/__init__.py src/pyams_security/views/login.py src/pyams_security/views/oauth.py +src/pyams_security/views/userfolder.py +src/pyams_security/views/utility.py src/pyams_security/views/templates/social-login.pt +src/pyams_security/views/templates/user-registration-end.pt +src/pyams_security/views/templates/user-registration.pt +src/pyams_security/widget/__init__.py +src/pyams_security/widget/interfaces.py +src/pyams_security/widget/templates/permission-display.pt +src/pyams_security/widget/templates/permission-input.pt +src/pyams_security/widget/templates/permissions-set-display.pt +src/pyams_security/widget/templates/permissions-set-input.pt +src/pyams_security/widget/templates/principal-display.pt +src/pyams_security/widget/templates/principal-input.pt +src/pyams_security/widget/templates/principals-set-display.pt +src/pyams_security/widget/templates/principals-set-input.pt src/pyams_security/zmi/__init__.py -src/pyams_security/zmi/configure.zcml src/pyams_security/zmi/interfaces.py +src/pyams_security/zmi/notification.py +src/pyams_security/zmi/security.py src/pyams_security/zmi/utility.py src/pyams_security/zmi/plugin/__init__.py -src/pyams_security/zmi/plugin/admin.py \ No newline at end of file +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/widget/__init__.py +src/pyams_security/zmi/widget/templates/ordered-list-display.pt +src/pyams_security/zmi/widget/templates/ordered-list-input.pt \ No newline at end of file diff -r 905e30f5467b -r 07229ac2497b src/pyams_security.egg-info/requires.txt --- a/src/pyams_security.egg-info/requires.txt Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security.egg-info/requires.txt Wed Jun 17 09:59:18 2015 +0200 @@ -1,8 +1,10 @@ setuptools +authomatic fanstatic pyramid zope.component zope.interface zope.password +zope.principalannotation [test] diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/__init__.py --- a/src/pyams_security/__init__.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/__init__.py Wed Jun 17 09:59:18 2015 +0200 @@ -40,6 +40,14 @@ config.register_permission({'id': 'system.manage', 'title': _("Manage system properties")}) + config.register_permission({'id': 'security.manage', + 'title': _("Manage security")}) + config.register_permission({'id': 'security.manage_roles', + 'title': _("Manage roles")}) + + # register custom roles config.register_role({'id': 'system.Manager', 'title': "System manager (role)", - 'permissions': {'public', 'view', 'manage', 'system.manage', 'system.view'}}) + 'permissions': {'public', 'view', 'manage', 'system.manage', 'system.view', + 'security.manage', 'security.manage_roles'}, + 'managers': {'system:admin', 'role:system.Manager'}}) diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/index.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_security/index.py Wed Jun 17 09:59:18 2015 +0200 @@ -0,0 +1,36 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_security.interfaces import IProtectedObject + +# import packages +from hypatia.keyword import KeywordIndex + + +class PrincipalsRoleIndex(KeywordIndex): + """Principals role index""" + + def __init__(self, role_id, family=None): + KeywordIndex.__init__(self, role_id, family) + self.role_id = role_id + + def discriminate(self, obj, default): + protected_object = IProtectedObject(obj, None) + if protected_object is None: + return default + return protected_object.get_principals(self.role_id) diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/interfaces/__init__.py --- a/src/pyams_security/interfaces/__init__.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/interfaces/__init__.py Wed Jun 17 09:59:18 2015 +0200 @@ -33,6 +33,9 @@ from pyams_security import _ +FORBIDDEN_PERMISSION = 'system.forbidden' + + class IPermission(Interface): """Permission utility class""" @@ -63,6 +66,12 @@ value_type=TextLine(), required=False) + managers = Set(title="Managers", + description="List of principal IDs allowed to manage this role. " + "If it's a role, use 'role:role_id' syntax...", + value_type=TextLine(), + required=False) + class IPrincipalInfo(Interface): """Principal info class @@ -178,8 +187,12 @@ class IDirectoryInfo(Interface): """Principal directory plug-in interface""" - def get_principal(self, principal_id): - """Returns real principal matching given ID, or None""" + def get_principal(self, principal_id, info=True): + """Returns real principal matching given ID, or None + + If info is True, returns a PrincipalINfo record instead + of original principal object + """ def get_all_principals(self, principal_id): """Returns all principals matching given principal ID""" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.mo Binary file src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.mo has changed diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.po --- a/src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.po Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.po Wed Jun 17 09:59:18 2015 +0200 @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" -"POT-Creation-Date: 2015-04-17 13:45+0200\n" +"POT-Creation-Date: 2015-06-01 14:47+0200\n" "PO-Revision-Date: 2015-02-18 22:19+0100\n" "Last-Translator: Thierry Florac \n" "Language-Team: French\n" @@ -16,35 +16,49 @@ "Generated-By: Lingua 3.8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: src/pyams_security/__init__.py:41 +#: src/pyams_security/__init__.py:33 msgid "View public contents" msgstr "Voir les contenus publics" -#: src/pyams_security/__init__.py:43 +#: src/pyams_security/__init__.py:35 msgid "View protected contents" msgstr "Voir les contenus protégés" -#: src/pyams_security/__init__.py:45 +#: src/pyams_security/__init__.py:37 msgid "Manage contents properties" msgstr "Gérer les propriétés des contenus" -#: src/pyams_security/__init__.py:47 +#: src/pyams_security/__init__.py:39 msgid "View management screens" msgstr "Voir les propriétés du système" -#: src/pyams_security/__init__.py:49 +#: src/pyams_security/__init__.py:41 msgid "Manage system properties" msgstr "Gérer les propriétés du système" +#: src/pyams_security/__init__.py:44 +msgid "Manage security" +msgstr "Gérer les paramètres de sécurité" + +#: src/pyams_security/__init__.py:46 +msgid "Manage roles" +msgstr "Gérer l'attribution des rôles" + #: src/pyams_security/principal.py:53 msgid "Not logged in" msgstr "Non connecté" #: src/pyams_security/widget/templates/principals-set-input.pt:4 #: src/pyams_security/widget/templates/principal-input.pt:4 +#: src/pyams_security/widget/templates/permission-input.pt:4 +#: src/pyams_security/widget/templates/permissions-set-input.pt:4 msgid "Clear selected values" msgstr "Effacer les valeurs sélectionnées" +#: src/pyams_security/widget/templates/permissions-set-input.pt:11 +msgid "Select permissions..." +msgstr "Sélectionner des permissions..." + #: src/pyams_security/zmi/utility.py:75 msgid "Security" msgstr "Sécurité" @@ -53,39 +67,39 @@ msgid "Authentication and users directory plug-ins" msgstr "Modules d'authentification et dossiers utilisateurs" -#: src/pyams_security/zmi/utility.py:105 +#: src/pyams_security/zmi/utility.py:104 msgid "See plug-in contents" msgstr "Voir le contenu du module" -#: src/pyams_security/zmi/utility.py:120 +#: src/pyams_security/zmi/utility.py:119 #: src/pyams_security/zmi/plugin/social.py:195 #: src/pyams_security/zmi/plugin/social.py:328 #: src/pyams_security/zmi/plugin/userfolder.py:192 #: src/pyams_security/zmi/plugin/group.py:159 -#: src/pyams_security/interfaces/__init__.py:236 +#: src/pyams_security/interfaces/__init__.py:246 msgid "Name" msgstr "Nom" -#: src/pyams_security/zmi/utility.py:129 +#: src/pyams_security/zmi/utility.py:128 msgid "Delete plug-in" msgstr "Supprimer ce module" -#: src/pyams_security/zmi/utility.py:163 +#: src/pyams_security/zmi/utility.py:162 #: src/pyams_security/zmi/plugin/social.py:370 #: src/pyams_security/zmi/plugin/social.py:388 #: src/pyams_security/zmi/plugin/social.py:443 msgid "Security manager" msgstr "Gestionnaire de sécurité" -#: src/pyams_security/zmi/utility.py:164 +#: src/pyams_security/zmi/utility.py:163 msgid "Security manager plug-ins" msgstr "Modules du gestionnaire de sécurité" -#: src/pyams_security/zmi/utility.py:172 +#: src/pyams_security/zmi/utility.py:171 msgid "Properties..." msgstr "Propriétés..." -#: src/pyams_security/zmi/utility.py:185 +#: src/pyams_security/zmi/utility.py:184 #: src/pyams_security/zmi/notification.py:58 #: src/pyams_security/zmi/plugin/social.py:79 #: src/pyams_security/zmi/plugin/userfolder.py:76 @@ -94,29 +108,29 @@ msgid "System security manager" msgstr "Gestionnaire de sécurité" -#: src/pyams_security/zmi/utility.py:186 +#: src/pyams_security/zmi/utility.py:185 msgid "Security manager properties" msgstr "Propriétés du gestionnaire de sécurité" -#: src/pyams_security/zmi/utility.py:223 +#: src/pyams_security/zmi/utility.py:222 msgid "Plug-ins" msgstr "Modules" -#: src/pyams_security/zmi/utility.py:208 -#: src/pyams_security/interfaces/__init__.py:542 +#: src/pyams_security/zmi/utility.py:207 +#: src/pyams_security/interfaces/__init__.py:552 msgid "Enable social login?" msgstr "Activer les réseaux sociaux ?" -#: src/pyams_security/zmi/utility.py:215 -#: src/pyams_security/interfaces/__init__.py:566 +#: src/pyams_security/zmi/utility.py:214 +#: src/pyams_security/interfaces/__init__.py:576 msgid "Enable free registration?" msgstr "Activer l'inscription libre ?" -#: src/pyams_security/zmi/utility.py:245 +#: src/pyams_security/zmi/utility.py:244 msgid "No provided object_name argument!" msgstr "Argument 'object_name' non fourni !" -#: src/pyams_security/zmi/utility.py:249 +#: src/pyams_security/zmi/utility.py:248 msgid "Given plug-in name doesn't exist!" msgstr "Le module indiqué n'existe pas !" @@ -128,15 +142,19 @@ msgid "Notifications properties" msgstr "Paramétrage des notifications" -#: src/pyams_security/zmi/security.py:41 +#: src/pyams_security/zmi/security.py:46 msgid "Access rules..." msgstr "Règles d'accès..." -#: src/pyams_security/zmi/security.py:56 -msgid "Edit local roles" -msgstr "Gestion des règles d'accès" +#: src/pyams_security/zmi/security.py:71 +msgid "Security management" +msgstr "Paramètres de sécurité" -#: src/pyams_security/zmi/security.py:73 src/pyams_security/zmi/security.py:74 +#: src/pyams_security/zmi/security.py:93 +msgid "Granted roles" +msgstr "Affectation des rôles" + +#: src/pyams_security/zmi/security.py:83 src/pyams_security/zmi/security.py:84 msgid "(inherit from parent)" msgstr "(héritée du parent)" @@ -168,19 +186,19 @@ #: src/pyams_security/zmi/plugin/social.py:205 #: src/pyams_security/zmi/plugin/userfolder.py:202 -#: src/pyams_security/interfaces/__init__.py:247 -#: src/pyams_security/interfaces/__init__.py:323 +#: src/pyams_security/interfaces/__init__.py:257 +#: src/pyams_security/interfaces/__init__.py:333 msgid "E-mail address" msgstr "Adresse de messagerie" #: src/pyams_security/zmi/plugin/social.py:215 -#: src/pyams_security/interfaces/__init__.py:231 +#: src/pyams_security/interfaces/__init__.py:241 msgid "OAuth provider name" msgstr "Nom du fournisseur" #: src/pyams_security/zmi/plugin/social.py:225 #: src/pyams_security/zmi/plugin/userfolder.py:212 -#: src/pyams_security/interfaces/__init__.py:271 +#: src/pyams_security/interfaces/__init__.py:281 msgid "Registration date" msgstr "Date d'enregistrement" @@ -266,8 +284,8 @@ msgstr "Code utilisateur" #: src/pyams_security/zmi/plugin/userfolder.py:228 -#: src/pyams_security/interfaces/__init__.py:445 -#: src/pyams_security/interfaces/__init__.py:448 +#: src/pyams_security/interfaces/__init__.py:455 +#: src/pyams_security/interfaces/__init__.py:458 msgid "Activation date" msgstr "Date d'activation" @@ -305,7 +323,7 @@ msgstr "Groupes locaux" #: src/pyams_security/zmi/plugin/group.py:169 -#: src/pyams_security/interfaces/__init__.py:489 +#: src/pyams_security/interfaces/__init__.py:499 msgid "Description" msgstr "Description" @@ -424,9 +442,9 @@ msgstr "Veuillez indiquer vos paramètres de connexion" #: src/pyams_security/views/login.py:57 -#: src/pyams_security/interfaces/__init__.py:342 -#: src/pyams_security/interfaces/__init__.py:368 -#: src/pyams_security/interfaces/__init__.py:420 +#: src/pyams_security/interfaces/__init__.py:352 +#: src/pyams_security/interfaces/__init__.py:378 +#: src/pyams_security/interfaces/__init__.py:430 msgid "Password" msgstr "Mot de passe" @@ -465,92 +483,92 @@ msgid "Return to home page" msgstr "Retourner à la page d'accueil" -#: src/pyams_security/interfaces/__init__.py:131 +#: src/pyams_security/interfaces/__init__.py:137 msgid "Plug-in prefix" msgstr "Préfixe du module" -#: src/pyams_security/interfaces/__init__.py:132 +#: src/pyams_security/interfaces/__init__.py:138 msgid "" "This prefix is mainly used by authentication plug-ins to mark principals" msgstr "" "Ce préfixe est utilisé par les modules d'authentification pour identifier " "les utilisateurs" -#: src/pyams_security/interfaces/__init__.py:134 +#: src/pyams_security/interfaces/__init__.py:140 msgid "Plug-in title" msgstr "Libellé du module" -#: src/pyams_security/interfaces/__init__.py:137 +#: src/pyams_security/interfaces/__init__.py:143 msgid "Enabled plug-in?" msgstr "Module actif ?" -#: src/pyams_security/interfaces/__init__.py:138 +#: src/pyams_security/interfaces/__init__.py:144 msgid "You can choose to disable any plug-in..." msgstr "" "Un module inactif ne peut plus être utilisé pour authentifier ou rechercher " "les utilisateurs..." -#: src/pyams_security/interfaces/__init__.py:173 +#: src/pyams_security/interfaces/__init__.py:179 msgid "Admin. login" msgstr "Code utilisateur" -#: src/pyams_security/interfaces/__init__.py:175 +#: src/pyams_security/interfaces/__init__.py:181 msgid "Admin. password" msgstr "Mot de passe" -#: src/pyams_security/interfaces/__init__.py:229 +#: src/pyams_security/interfaces/__init__.py:239 msgid "Internal provider ID" msgstr "ID du connecteur" -#: src/pyams_security/interfaces/__init__.py:233 +#: src/pyams_security/interfaces/__init__.py:243 msgid "User name" msgstr "Nom d'utilisateur" -#: src/pyams_security/interfaces/__init__.py:238 -#: src/pyams_security/interfaces/__init__.py:333 -#: src/pyams_security/interfaces/__init__.py:404 +#: src/pyams_security/interfaces/__init__.py:248 +#: src/pyams_security/interfaces/__init__.py:343 +#: src/pyams_security/interfaces/__init__.py:414 msgid "First name" msgstr "Prénom" -#: src/pyams_security/interfaces/__init__.py:241 -#: src/pyams_security/interfaces/__init__.py:336 -#: src/pyams_security/interfaces/__init__.py:407 +#: src/pyams_security/interfaces/__init__.py:251 +#: src/pyams_security/interfaces/__init__.py:346 +#: src/pyams_security/interfaces/__init__.py:417 msgid "Last name" msgstr "Nom" -#: src/pyams_security/interfaces/__init__.py:244 +#: src/pyams_security/interfaces/__init__.py:254 msgid "Nickname" msgstr "Surnom" -#: src/pyams_security/interfaces/__init__.py:250 +#: src/pyams_security/interfaces/__init__.py:260 msgid "Timezone" msgstr "Fuseau horaire" -#: src/pyams_security/interfaces/__init__.py:253 +#: src/pyams_security/interfaces/__init__.py:263 msgid "Country" msgstr "Pays" -#: src/pyams_security/interfaces/__init__.py:256 +#: src/pyams_security/interfaces/__init__.py:266 msgid "City" msgstr "Ville" -#: src/pyams_security/interfaces/__init__.py:259 +#: src/pyams_security/interfaces/__init__.py:269 msgid "Postal code" msgstr "Code postal" -#: src/pyams_security/interfaces/__init__.py:262 +#: src/pyams_security/interfaces/__init__.py:272 msgid "Locale code" msgstr "Langue" -#: src/pyams_security/interfaces/__init__.py:265 +#: src/pyams_security/interfaces/__init__.py:275 msgid "Picture URL" msgstr "Photo (URL)" -#: src/pyams_security/interfaces/__init__.py:268 +#: src/pyams_security/interfaces/__init__.py:278 msgid "Birth date" msgstr "Date de naissance" -#: src/pyams_security/interfaces/__init__.py:304 +#: src/pyams_security/interfaces/__init__.py:314 msgid "" "Your password must contain at least three of these kinds of characters: " "lowercase letters, uppercase letters, numbers and special characters" @@ -558,20 +576,20 @@ "Votre mot de passe doit contenir au moins trois de ces types de caractères : " "minuscules, majuscules, chiffres et autres caractères" -#: src/pyams_security/interfaces/__init__.py:314 -#: src/pyams_security/interfaces/__init__.py:365 -#: src/pyams_security/interfaces/__init__.py:387 +#: src/pyams_security/interfaces/__init__.py:324 +#: src/pyams_security/interfaces/__init__.py:375 +#: src/pyams_security/interfaces/__init__.py:397 msgid "User login" msgstr "Code utilisateur" -#: src/pyams_security/interfaces/__init__.py:315 +#: src/pyams_security/interfaces/__init__.py:325 msgid "" "If you don't provide a custom login, your login will be your email address..." msgstr "" "Si vous n'indiquez pas de code utilisateur, vous pourrez utiliser votre " "adresse de messagerie pour vous connecter..." -#: src/pyams_security/interfaces/__init__.py:324 +#: src/pyams_security/interfaces/__init__.py:334 msgid "" "An email will be sent to this address to validate account activation; it " "will be used as your future user login" @@ -580,12 +598,12 @@ "permettre d'activer votre compte ; il pourra être utilisé compte identifiant " "de connexion si vous n'avez pas indiqué de code utilisateur" -#: src/pyams_security/interfaces/__init__.py:339 -#: src/pyams_security/interfaces/__init__.py:412 +#: src/pyams_security/interfaces/__init__.py:349 +#: src/pyams_security/interfaces/__init__.py:422 msgid "Company name" msgstr "Société" -#: src/pyams_security/interfaces/__init__.py:343 +#: src/pyams_security/interfaces/__init__.py:353 msgid "" "Password must be at least 8 characters long, and contain at least three kins " "of characters between lowercase letters, uppercase letters, numbers and " @@ -595,29 +613,29 @@ "moins trois types de caractères parmi les lettres minuscules, les " "majuscules, les chiffres et les caractères spéciaux" -#: src/pyams_security/interfaces/__init__.py:349 -#: src/pyams_security/interfaces/__init__.py:372 +#: src/pyams_security/interfaces/__init__.py:359 +#: src/pyams_security/interfaces/__init__.py:382 msgid "Confirmed password" msgstr "Confirmation du mot de passe" -#: src/pyams_security/interfaces/__init__.py:362 -#: src/pyams_security/interfaces/__init__.py:439 +#: src/pyams_security/interfaces/__init__.py:372 +#: src/pyams_security/interfaces/__init__.py:449 msgid "Activation hash" msgstr "Clé d'activation" -#: src/pyams_security/interfaces/__init__.py:396 +#: src/pyams_security/interfaces/__init__.py:406 msgid "User email address" msgstr "Adresse de messagerie" -#: src/pyams_security/interfaces/__init__.py:415 +#: src/pyams_security/interfaces/__init__.py:425 msgid "Password manager name" msgstr "Gestionnaire de mot de passe" -#: src/pyams_security/interfaces/__init__.py:424 +#: src/pyams_security/interfaces/__init__.py:434 msgid "Wait confirmation?" msgstr "Attendre la confirmation ?" -#: src/pyams_security/interfaces/__init__.py:425 +#: src/pyams_security/interfaces/__init__.py:435 msgid "" "If 'no', user will be activated immediately without waiting email " "confirmation" @@ -625,20 +643,20 @@ "Si 'non', ce compte utilisateur sera activé immédiatement sans attendre le " "message de confirmation" -#: src/pyams_security/interfaces/__init__.py:430 +#: src/pyams_security/interfaces/__init__.py:440 msgid "Self-registered profile?" msgstr "Profil auto-enregistré ?" -#: src/pyams_security/interfaces/__init__.py:435 +#: src/pyams_security/interfaces/__init__.py:445 msgid "Activation secret key" msgstr "Clé secrète" -#: src/pyams_security/interfaces/__init__.py:436 +#: src/pyams_security/interfaces/__init__.py:446 msgid "This private secret is used to create and check activation hash" msgstr "" "Cette clé secrète est utilisé pour créer et vérifier la clé d'activation" -#: src/pyams_security/interfaces/__init__.py:440 +#: src/pyams_security/interfaces/__init__.py:450 msgid "" "This hash is provided into activation message URL. Activation hash is " "missing for local users which were registered without waiting their " @@ -648,84 +666,84 @@ "Cette clé d'activation n'est pas définie pour les utilisateurs pour lesquels " "l'attente de confirmation n'a pas été demandée." -#: src/pyams_security/interfaces/__init__.py:480 +#: src/pyams_security/interfaces/__init__.py:490 msgid "Group ID" msgstr "ID du groupe" -#: src/pyams_security/interfaces/__init__.py:481 +#: src/pyams_security/interfaces/__init__.py:491 msgid "This ID should be unique between all groups" msgstr "Cet ID doit être unique pour tous les groupes" -#: src/pyams_security/interfaces/__init__.py:485 +#: src/pyams_security/interfaces/__init__.py:495 msgid "Title" msgstr "Nom" -#: src/pyams_security/interfaces/__init__.py:486 +#: src/pyams_security/interfaces/__init__.py:496 msgid "Public label of this group" msgstr "Libellé public de ce groupe" -#: src/pyams_security/interfaces/__init__.py:492 +#: src/pyams_security/interfaces/__init__.py:502 msgid "Group principals" msgstr "Mandants du groupe" -#: src/pyams_security/interfaces/__init__.py:493 +#: src/pyams_security/interfaces/__init__.py:503 msgid "IDs of principals contained in this group" msgstr "ID des mandants contenus dans ce groupe" -#: src/pyams_security/interfaces/__init__.py:543 +#: src/pyams_security/interfaces/__init__.py:553 msgid "Enable login via social OAuth plug-ins" msgstr "" "Autoriser la connexion à partir des réseaux sociaux via les modules OAuth" -#: src/pyams_security/interfaces/__init__.py:547 +#: src/pyams_security/interfaces/__init__.py:557 msgid "Social users folder" msgstr "Dossier des utilisateurs \"sociaux\"" -#: src/pyams_security/interfaces/__init__.py:548 +#: src/pyams_security/interfaces/__init__.py:558 msgid "Name of folder used to store social users properties" msgstr "" "Nom du dossier dans lequel seront stockés les profils des utilisateurs " "connectés via des réseaux sociaux" -#: src/pyams_security/interfaces/__init__.py:557 +#: src/pyams_security/interfaces/__init__.py:567 msgid "Authomatic secret" msgstr "Clé OAuth" -#: src/pyams_security/interfaces/__init__.py:558 +#: src/pyams_security/interfaces/__init__.py:568 msgid "This secret phrase is used to encrypt Authomatic cookie" msgstr "" "Cette phrase secrète est utilisée pour crypter le cookie d'authentification" -#: src/pyams_security/interfaces/__init__.py:562 +#: src/pyams_security/interfaces/__init__.py:572 msgid "Use social popup?" msgstr "Connection via une popup ?" -#: src/pyams_security/interfaces/__init__.py:567 +#: src/pyams_security/interfaces/__init__.py:577 msgid "If 'Yes', any use will be able to create a new user account" msgstr "Si 'oui', toute personne sera à même de se créer un compte utilisateur" -#: src/pyams_security/interfaces/__init__.py:571 +#: src/pyams_security/interfaces/__init__.py:581 msgid "Users folder" msgstr "Dossier des utilisateurs locaux" -#: src/pyams_security/interfaces/__init__.py:572 +#: src/pyams_security/interfaces/__init__.py:582 msgid "Name of users folder used to store registered principals" msgstr "Nom du dossier dans lequel seront créés les utilisateurs enregistrés" -#: src/pyams_security/interfaces/__init__.py:581 +#: src/pyams_security/interfaces/__init__.py:591 msgid "Credentials plug-ins" msgstr "Modules d'identification" -#: src/pyams_security/interfaces/__init__.py:582 +#: src/pyams_security/interfaces/__init__.py:592 msgid "These plug-ins can be used to extract request credentials" msgstr "" "Ces modules peuvent être utilisés pour extraire l'identitité des utilisateurs" -#: src/pyams_security/interfaces/__init__.py:587 +#: src/pyams_security/interfaces/__init__.py:597 msgid "Authentication plug-ins" msgstr "Modules d'authentification" -#: src/pyams_security/interfaces/__init__.py:588 +#: src/pyams_security/interfaces/__init__.py:598 msgid "" "The plug-ins can be used to check extracted credentials against a local or " "remote users database" @@ -733,88 +751,88 @@ "Ces modules sont utilisés pour vérifier l'identité des utilisateurs vis à " "vis d'une base d'utilisateurs locale ou distante" -#: src/pyams_security/interfaces/__init__.py:593 +#: src/pyams_security/interfaces/__init__.py:603 msgid "Directory plug-ins" msgstr "Modules d'annuaires" -#: src/pyams_security/interfaces/__init__.py:594 +#: src/pyams_security/interfaces/__init__.py:604 msgid "The plug-in can be used to extract principals information" msgstr "" "Ces modules peuvent être utilisés pour extraire les propriétés des " "utilisateurs" -#: src/pyams_security/interfaces/__init__.py:668 +#: src/pyams_security/interfaces/__init__.py:678 msgid "Provider name" msgstr "Nom du fournisseur" -#: src/pyams_security/interfaces/__init__.py:672 +#: src/pyams_security/interfaces/__init__.py:682 msgid "Provider ID" msgstr "ID du fournisseur" -#: src/pyams_security/interfaces/__init__.py:673 +#: src/pyams_security/interfaces/__init__.py:683 msgid "This value should be unique between all providers" msgstr "Cette valeur numérique doit être unique pour tous les fournisseurs" -#: src/pyams_security/interfaces/__init__.py:677 +#: src/pyams_security/interfaces/__init__.py:687 msgid "Provider consumer key" msgstr "Clé cliente" -#: src/pyams_security/interfaces/__init__.py:680 +#: src/pyams_security/interfaces/__init__.py:690 msgid "Provider secret" msgstr "Clé secrète" -#: src/pyams_security/interfaces/__init__.py:698 +#: src/pyams_security/interfaces/__init__.py:708 msgid "Inherit parent security?" msgstr "Héritage de la sécurité ?" -#: src/pyams_security/interfaces/__init__.py:699 +#: src/pyams_security/interfaces/__init__.py:709 msgid "Get access control entries (ACE) inherited from parent levels" msgstr "Utiliser les règles d'accès (ACE) héritées du parent" -#: src/pyams_security/interfaces/__init__.py:704 -msgid "Public permission" -msgstr "Permission publique" +#: src/pyams_security/interfaces/__init__.py:714 +msgid "Public permissions" +msgstr "Permissions publiques" -#: src/pyams_security/interfaces/__init__.py:705 -msgid "This permission will be granted to all users" -msgstr "Cette permission sera attribuée à tous les utilisateurs" +#: src/pyams_security/interfaces/__init__.py:715 +msgid "These permissions will be granted to all users" +msgstr "Ces permissions seront attribuées à tous les utilisateurs" -#: src/pyams_security/interfaces/__init__.py:709 -msgid "Authenticated permission" -msgstr "Permission authentifiée" +#: src/pyams_security/interfaces/__init__.py:718 +msgid "Authenticated permissions" +msgstr "Permissions authentifiées" -#: src/pyams_security/interfaces/__init__.py:710 -msgid "This permission will be granted to authenticated users" -msgstr "Cette permission sera attribuée à tous les utilisateurs authentifiés" +#: src/pyams_security/interfaces/__init__.py:719 +msgid "These permissions will be granted to authenticated users" +msgstr "Ces permissions seront attribuées à tous les utilisateurs authentifiés" -#: src/pyams_security/interfaces/__init__.py:714 +#: src/pyams_security/interfaces/__init__.py:723 msgid "Inherit parent roles?" msgstr "Héritage des rôles ?" -#: src/pyams_security/interfaces/__init__.py:715 +#: src/pyams_security/interfaces/__init__.py:724 msgid "Get roles granted on parent levels" msgstr "Disposer des rôles affectés aux niveaux parents" -#: src/pyams_security/interfaces/__init__.py:331 +#: src/pyams_security/interfaces/__init__.py:341 msgid "Your email address is not valid!" msgstr "Votre adresse de messagerie est incorrecte !" -#: src/pyams_security/interfaces/__init__.py:355 -#: src/pyams_security/interfaces/__init__.py:378 +#: src/pyams_security/interfaces/__init__.py:365 +#: src/pyams_security/interfaces/__init__.py:388 msgid "You didn't confirmed your password correctly!" msgstr "Vous n'avez pas confirmé votre mot de passe correctement !" -#: src/pyams_security/interfaces/__init__.py:402 +#: src/pyams_security/interfaces/__init__.py:412 msgid "Given email address is not valid!" msgstr "L'adrese de messagerie indiquée est invalide !" -#: src/pyams_security/interfaces/__init__.py:555 +#: src/pyams_security/interfaces/__init__.py:565 msgid "You can't activate social login without selecting a social users folder" msgstr "" "Vous ne pouvez pas activer la connexion via les réseaux sociaux sans " "sélectionner de dossier de stockage des utilisateurs" -#: src/pyams_security/interfaces/__init__.py:579 +#: src/pyams_security/interfaces/__init__.py:589 msgid "You can't activate open registration without selecting a users folder" msgstr "" "Vous ne pouvez pas activer les fonctions d'inscription libre sans " @@ -905,7 +923,7 @@ msgstr "" "Impossible de confirmer votre inscription avec les paramètres fournis !" -#: src/pyams_security/plugin/userfolder.py:252 +#: src/pyams_security/plugin/userfolder.py:255 #, python-format msgid "{prefix}Please confirm registration" msgstr "{prefix}Veuillez confirmer votre inscription" @@ -972,3 +990,6 @@ msgstr "" "Vous avez créé un nouveau compte que vous devez confirmer avant de pouvoir " "utiliser ce service." + +#~ msgid "Edit local roles" +#~ msgstr "Gestion des règles d'accès" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/locales/pyams_security.pot --- a/src/pyams_security/locales/pyams_security.pot Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/locales/pyams_security.pot Wed Jun 17 09:59:18 2015 +0200 @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" -"POT-Creation-Date: 2015-04-17 13:45+0200\n" +"POT-Creation-Date: 2015-06-01 14:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" @@ -16,35 +16,49 @@ "Content-Transfer-Encoding: 8bit\n" "Generated-By: Lingua 3.10.dev0\n" -#: ./src/pyams_security/__init__.py:41 +#: ./src/pyams_security/__init__.py:33 msgid "View public contents" msgstr "" -#: ./src/pyams_security/__init__.py:43 +#: ./src/pyams_security/__init__.py:35 msgid "View protected contents" msgstr "" -#: ./src/pyams_security/__init__.py:45 +#: ./src/pyams_security/__init__.py:37 msgid "Manage contents properties" msgstr "" -#: ./src/pyams_security/__init__.py:47 +#: ./src/pyams_security/__init__.py:39 msgid "View management screens" msgstr "" -#: ./src/pyams_security/__init__.py:49 +#: ./src/pyams_security/__init__.py:41 msgid "Manage system properties" msgstr "" +#: ./src/pyams_security/__init__.py:44 +msgid "Manage security" +msgstr "" + +#: ./src/pyams_security/__init__.py:46 +msgid "Manage roles" +msgstr "" + #: ./src/pyams_security/principal.py:53 msgid "Not logged in" msgstr "" #: ./src/pyams_security/widget/templates/principals-set-input.pt:4 #: ./src/pyams_security/widget/templates/principal-input.pt:4 +#: ./src/pyams_security/widget/templates/permission-input.pt:4 +#: ./src/pyams_security/widget/templates/permissions-set-input.pt:4 msgid "Clear selected values" msgstr "" +#: ./src/pyams_security/widget/templates/permissions-set-input.pt:11 +msgid "Select permissions..." +msgstr "" + #: ./src/pyams_security/zmi/utility.py:75 msgid "Security" msgstr "" @@ -53,39 +67,39 @@ msgid "Authentication and users directory plug-ins" msgstr "" -#: ./src/pyams_security/zmi/utility.py:105 +#: ./src/pyams_security/zmi/utility.py:104 msgid "See plug-in contents" msgstr "" -#: ./src/pyams_security/zmi/utility.py:120 +#: ./src/pyams_security/zmi/utility.py:119 #: ./src/pyams_security/zmi/plugin/social.py:195 #: ./src/pyams_security/zmi/plugin/social.py:328 #: ./src/pyams_security/zmi/plugin/userfolder.py:192 #: ./src/pyams_security/zmi/plugin/group.py:159 -#: ./src/pyams_security/interfaces/__init__.py:236 +#: ./src/pyams_security/interfaces/__init__.py:246 msgid "Name" msgstr "" -#: ./src/pyams_security/zmi/utility.py:129 +#: ./src/pyams_security/zmi/utility.py:128 msgid "Delete plug-in" msgstr "" -#: ./src/pyams_security/zmi/utility.py:163 +#: ./src/pyams_security/zmi/utility.py:162 #: ./src/pyams_security/zmi/plugin/social.py:370 #: ./src/pyams_security/zmi/plugin/social.py:388 #: ./src/pyams_security/zmi/plugin/social.py:443 msgid "Security manager" msgstr "" -#: ./src/pyams_security/zmi/utility.py:164 +#: ./src/pyams_security/zmi/utility.py:163 msgid "Security manager plug-ins" msgstr "" -#: ./src/pyams_security/zmi/utility.py:172 +#: ./src/pyams_security/zmi/utility.py:171 msgid "Properties..." msgstr "" -#: ./src/pyams_security/zmi/utility.py:185 +#: ./src/pyams_security/zmi/utility.py:184 #: ./src/pyams_security/zmi/notification.py:58 #: ./src/pyams_security/zmi/plugin/social.py:79 #: ./src/pyams_security/zmi/plugin/userfolder.py:76 @@ -94,29 +108,29 @@ msgid "System security manager" msgstr "" -#: ./src/pyams_security/zmi/utility.py:186 +#: ./src/pyams_security/zmi/utility.py:185 msgid "Security manager properties" msgstr "" -#: ./src/pyams_security/zmi/utility.py:223 +#: ./src/pyams_security/zmi/utility.py:222 msgid "Plug-ins" msgstr "" -#: ./src/pyams_security/zmi/utility.py:208 -#: ./src/pyams_security/interfaces/__init__.py:542 +#: ./src/pyams_security/zmi/utility.py:207 +#: ./src/pyams_security/interfaces/__init__.py:552 msgid "Enable social login?" msgstr "" -#: ./src/pyams_security/zmi/utility.py:215 -#: ./src/pyams_security/interfaces/__init__.py:566 +#: ./src/pyams_security/zmi/utility.py:214 +#: ./src/pyams_security/interfaces/__init__.py:576 msgid "Enable free registration?" msgstr "" -#: ./src/pyams_security/zmi/utility.py:245 +#: ./src/pyams_security/zmi/utility.py:244 msgid "No provided object_name argument!" msgstr "" -#: ./src/pyams_security/zmi/utility.py:249 +#: ./src/pyams_security/zmi/utility.py:248 msgid "Given plug-in name doesn't exist!" msgstr "" @@ -128,16 +142,20 @@ msgid "Notifications properties" msgstr "" -#: ./src/pyams_security/zmi/security.py:41 +#: ./src/pyams_security/zmi/security.py:46 msgid "Access rules..." msgstr "" -#: ./src/pyams_security/zmi/security.py:56 -msgid "Edit local roles" +#: ./src/pyams_security/zmi/security.py:71 +msgid "Security management" msgstr "" -#: ./src/pyams_security/zmi/security.py:73 -#: ./src/pyams_security/zmi/security.py:74 +#: ./src/pyams_security/zmi/security.py:93 +msgid "Granted roles" +msgstr "" + +#: ./src/pyams_security/zmi/security.py:83 +#: ./src/pyams_security/zmi/security.py:84 msgid "(inherit from parent)" msgstr "" @@ -169,19 +187,19 @@ #: ./src/pyams_security/zmi/plugin/social.py:205 #: ./src/pyams_security/zmi/plugin/userfolder.py:202 -#: ./src/pyams_security/interfaces/__init__.py:247 -#: ./src/pyams_security/interfaces/__init__.py:323 +#: ./src/pyams_security/interfaces/__init__.py:257 +#: ./src/pyams_security/interfaces/__init__.py:333 msgid "E-mail address" msgstr "" #: ./src/pyams_security/zmi/plugin/social.py:215 -#: ./src/pyams_security/interfaces/__init__.py:231 +#: ./src/pyams_security/interfaces/__init__.py:241 msgid "OAuth provider name" msgstr "" #: ./src/pyams_security/zmi/plugin/social.py:225 #: ./src/pyams_security/zmi/plugin/userfolder.py:212 -#: ./src/pyams_security/interfaces/__init__.py:271 +#: ./src/pyams_security/interfaces/__init__.py:281 msgid "Registration date" msgstr "" @@ -267,8 +285,8 @@ msgstr "" #: ./src/pyams_security/zmi/plugin/userfolder.py:228 -#: ./src/pyams_security/interfaces/__init__.py:445 -#: ./src/pyams_security/interfaces/__init__.py:448 +#: ./src/pyams_security/interfaces/__init__.py:455 +#: ./src/pyams_security/interfaces/__init__.py:458 msgid "Activation date" msgstr "" @@ -306,7 +324,7 @@ msgstr "" #: ./src/pyams_security/zmi/plugin/group.py:169 -#: ./src/pyams_security/interfaces/__init__.py:489 +#: ./src/pyams_security/interfaces/__init__.py:499 msgid "Description" msgstr "" @@ -417,9 +435,9 @@ msgstr "" #: ./src/pyams_security/views/login.py:57 -#: ./src/pyams_security/interfaces/__init__.py:342 -#: ./src/pyams_security/interfaces/__init__.py:368 -#: ./src/pyams_security/interfaces/__init__.py:420 +#: ./src/pyams_security/interfaces/__init__.py:352 +#: ./src/pyams_security/interfaces/__init__.py:378 +#: ./src/pyams_security/interfaces/__init__.py:430 msgid "Password" msgstr "" @@ -456,324 +474,324 @@ msgid "Return to home page" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:131 +#: ./src/pyams_security/interfaces/__init__.py:137 msgid "Plug-in prefix" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:132 +#: ./src/pyams_security/interfaces/__init__.py:138 msgid "" "This prefix is mainly used by authentication plug-ins to mark principals" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:134 +#: ./src/pyams_security/interfaces/__init__.py:140 msgid "Plug-in title" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:137 +#: ./src/pyams_security/interfaces/__init__.py:143 msgid "Enabled plug-in?" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:138 +#: ./src/pyams_security/interfaces/__init__.py:144 msgid "You can choose to disable any plug-in..." msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:173 +#: ./src/pyams_security/interfaces/__init__.py:179 msgid "Admin. login" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:175 +#: ./src/pyams_security/interfaces/__init__.py:181 msgid "Admin. password" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:229 +#: ./src/pyams_security/interfaces/__init__.py:239 msgid "Internal provider ID" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:233 +#: ./src/pyams_security/interfaces/__init__.py:243 msgid "User name" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:238 -#: ./src/pyams_security/interfaces/__init__.py:333 -#: ./src/pyams_security/interfaces/__init__.py:404 +#: ./src/pyams_security/interfaces/__init__.py:248 +#: ./src/pyams_security/interfaces/__init__.py:343 +#: ./src/pyams_security/interfaces/__init__.py:414 msgid "First name" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:241 -#: ./src/pyams_security/interfaces/__init__.py:336 -#: ./src/pyams_security/interfaces/__init__.py:407 +#: ./src/pyams_security/interfaces/__init__.py:251 +#: ./src/pyams_security/interfaces/__init__.py:346 +#: ./src/pyams_security/interfaces/__init__.py:417 msgid "Last name" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:244 +#: ./src/pyams_security/interfaces/__init__.py:254 msgid "Nickname" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:250 +#: ./src/pyams_security/interfaces/__init__.py:260 msgid "Timezone" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:253 +#: ./src/pyams_security/interfaces/__init__.py:263 msgid "Country" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:256 +#: ./src/pyams_security/interfaces/__init__.py:266 msgid "City" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:259 +#: ./src/pyams_security/interfaces/__init__.py:269 msgid "Postal code" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:262 +#: ./src/pyams_security/interfaces/__init__.py:272 msgid "Locale code" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:265 +#: ./src/pyams_security/interfaces/__init__.py:275 msgid "Picture URL" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:268 +#: ./src/pyams_security/interfaces/__init__.py:278 msgid "Birth date" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:304 +#: ./src/pyams_security/interfaces/__init__.py:314 msgid "" "Your password must contain at least three of these kinds of characters: " "lowercase letters, uppercase letters, numbers and special characters" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:314 -#: ./src/pyams_security/interfaces/__init__.py:365 -#: ./src/pyams_security/interfaces/__init__.py:387 +#: ./src/pyams_security/interfaces/__init__.py:324 +#: ./src/pyams_security/interfaces/__init__.py:375 +#: ./src/pyams_security/interfaces/__init__.py:397 msgid "User login" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:315 +#: ./src/pyams_security/interfaces/__init__.py:325 msgid "" "If you don't provide a custom login, your login will be your email address..." msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:324 +#: ./src/pyams_security/interfaces/__init__.py:334 msgid "" "An email will be sent to this address to validate account activation; it will" " be used as your future user login" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:339 -#: ./src/pyams_security/interfaces/__init__.py:412 +#: ./src/pyams_security/interfaces/__init__.py:349 +#: ./src/pyams_security/interfaces/__init__.py:422 msgid "Company name" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:343 +#: ./src/pyams_security/interfaces/__init__.py:353 msgid "" "Password must be at least 8 characters long, and contain at least three kins " "of characters between lowercase letters, uppercase letters, numbers and " "special characters" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:349 -#: ./src/pyams_security/interfaces/__init__.py:372 +#: ./src/pyams_security/interfaces/__init__.py:359 +#: ./src/pyams_security/interfaces/__init__.py:382 msgid "Confirmed password" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:362 -#: ./src/pyams_security/interfaces/__init__.py:439 +#: ./src/pyams_security/interfaces/__init__.py:372 +#: ./src/pyams_security/interfaces/__init__.py:449 msgid "Activation hash" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:396 +#: ./src/pyams_security/interfaces/__init__.py:406 msgid "User email address" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:415 +#: ./src/pyams_security/interfaces/__init__.py:425 msgid "Password manager name" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:424 +#: ./src/pyams_security/interfaces/__init__.py:434 msgid "Wait confirmation?" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:425 +#: ./src/pyams_security/interfaces/__init__.py:435 msgid "" "If 'no', user will be activated immediately without waiting email " "confirmation" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:430 +#: ./src/pyams_security/interfaces/__init__.py:440 msgid "Self-registered profile?" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:435 +#: ./src/pyams_security/interfaces/__init__.py:445 msgid "Activation secret key" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:436 +#: ./src/pyams_security/interfaces/__init__.py:446 msgid "This private secret is used to create and check activation hash" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:440 +#: ./src/pyams_security/interfaces/__init__.py:450 msgid "" "This hash is provided into activation message URL. Activation hash is missing" " for local users which were registered without waiting their confirmation." msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:480 +#: ./src/pyams_security/interfaces/__init__.py:490 msgid "Group ID" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:481 +#: ./src/pyams_security/interfaces/__init__.py:491 msgid "This ID should be unique between all groups" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:485 +#: ./src/pyams_security/interfaces/__init__.py:495 msgid "Title" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:486 +#: ./src/pyams_security/interfaces/__init__.py:496 msgid "Public label of this group" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:492 +#: ./src/pyams_security/interfaces/__init__.py:502 msgid "Group principals" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:493 +#: ./src/pyams_security/interfaces/__init__.py:503 msgid "IDs of principals contained in this group" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:543 +#: ./src/pyams_security/interfaces/__init__.py:553 msgid "Enable login via social OAuth plug-ins" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:547 -msgid "Social users folder" -msgstr "" - -#: ./src/pyams_security/interfaces/__init__.py:548 -msgid "Name of folder used to store social users properties" -msgstr "" - #: ./src/pyams_security/interfaces/__init__.py:557 -msgid "Authomatic secret" +msgid "Social users folder" msgstr "" #: ./src/pyams_security/interfaces/__init__.py:558 +msgid "Name of folder used to store social users properties" +msgstr "" + +#: ./src/pyams_security/interfaces/__init__.py:567 +msgid "Authomatic secret" +msgstr "" + +#: ./src/pyams_security/interfaces/__init__.py:568 msgid "This secret phrase is used to encrypt Authomatic cookie" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:562 +#: ./src/pyams_security/interfaces/__init__.py:572 msgid "Use social popup?" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:567 +#: ./src/pyams_security/interfaces/__init__.py:577 msgid "If 'Yes', any use will be able to create a new user account" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:571 +#: ./src/pyams_security/interfaces/__init__.py:581 msgid "Users folder" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:572 +#: ./src/pyams_security/interfaces/__init__.py:582 msgid "Name of users folder used to store registered principals" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:581 +#: ./src/pyams_security/interfaces/__init__.py:591 msgid "Credentials plug-ins" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:582 +#: ./src/pyams_security/interfaces/__init__.py:592 msgid "These plug-ins can be used to extract request credentials" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:587 +#: ./src/pyams_security/interfaces/__init__.py:597 msgid "Authentication plug-ins" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:588 +#: ./src/pyams_security/interfaces/__init__.py:598 msgid "" "The plug-ins can be used to check extracted credentials against a local or " "remote users database" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:593 +#: ./src/pyams_security/interfaces/__init__.py:603 msgid "Directory plug-ins" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:594 +#: ./src/pyams_security/interfaces/__init__.py:604 msgid "The plug-in can be used to extract principals information" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:668 +#: ./src/pyams_security/interfaces/__init__.py:678 msgid "Provider name" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:672 +#: ./src/pyams_security/interfaces/__init__.py:682 msgid "Provider ID" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:673 +#: ./src/pyams_security/interfaces/__init__.py:683 msgid "This value should be unique between all providers" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:677 +#: ./src/pyams_security/interfaces/__init__.py:687 msgid "Provider consumer key" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:680 +#: ./src/pyams_security/interfaces/__init__.py:690 msgid "Provider secret" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:698 +#: ./src/pyams_security/interfaces/__init__.py:708 msgid "Inherit parent security?" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:699 +#: ./src/pyams_security/interfaces/__init__.py:709 msgid "Get access control entries (ACE) inherited from parent levels" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:704 -msgid "Public permission" -msgstr "" - -#: ./src/pyams_security/interfaces/__init__.py:705 -msgid "This permission will be granted to all users" -msgstr "" - -#: ./src/pyams_security/interfaces/__init__.py:709 -msgid "Authenticated permission" -msgstr "" - -#: ./src/pyams_security/interfaces/__init__.py:710 -msgid "This permission will be granted to authenticated users" -msgstr "" - #: ./src/pyams_security/interfaces/__init__.py:714 -msgid "Inherit parent roles?" +msgid "Public permissions" msgstr "" #: ./src/pyams_security/interfaces/__init__.py:715 +msgid "These permissions will be granted to all users" +msgstr "" + +#: ./src/pyams_security/interfaces/__init__.py:718 +msgid "Authenticated permissions" +msgstr "" + +#: ./src/pyams_security/interfaces/__init__.py:719 +msgid "These permissions will be granted to authenticated users" +msgstr "" + +#: ./src/pyams_security/interfaces/__init__.py:723 +msgid "Inherit parent roles?" +msgstr "" + +#: ./src/pyams_security/interfaces/__init__.py:724 msgid "Get roles granted on parent levels" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:331 +#: ./src/pyams_security/interfaces/__init__.py:341 msgid "Your email address is not valid!" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:355 -#: ./src/pyams_security/interfaces/__init__.py:378 +#: ./src/pyams_security/interfaces/__init__.py:365 +#: ./src/pyams_security/interfaces/__init__.py:388 msgid "You didn't confirmed your password correctly!" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:402 +#: ./src/pyams_security/interfaces/__init__.py:412 msgid "Given email address is not valid!" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:555 +#: ./src/pyams_security/interfaces/__init__.py:565 msgid "You can't activate social login without selecting a social users folder" msgstr "" -#: ./src/pyams_security/interfaces/__init__.py:579 +#: ./src/pyams_security/interfaces/__init__.py:589 msgid "You can't activate open registration without selecting a users folder" msgstr "" @@ -857,7 +875,7 @@ msgid "Can't activate profile with given params!" msgstr "" -#: ./src/pyams_security/plugin/userfolder.py:252 +#: ./src/pyams_security/plugin/userfolder.py:255 #, python-format msgid "{prefix}Please confirm registration" msgstr "" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/plugin/admin.py --- a/src/pyams_security/plugin/admin.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/plugin/admin.py Wed Jun 17 09:59:18 2015 +0200 @@ -61,15 +61,18 @@ if login == self.login and manager.checkPassword(self._password, password): return "{0}:{1}".format(self.prefix, login) - def get_principal(self, principal_id): + def get_principal(self, principal_id, info=True): if not self.enabled: return None if not principal_id.startswith(self.prefix + ':'): return None prefix, login = principal_id.split(':', 1) if (prefix == self.prefix) and (login == self.login): - return PrincipalInfo(id=principal_id, - title=self.title) + if info: + return PrincipalInfo(id=principal_id, + title=self.title) + else: + return self def get_all_principals(self, principal_id): if not self.enabled: diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/plugin/group.py --- a/src/pyams_security/plugin/group.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/plugin/group.py Wed Jun 17 09:59:18 2015 +0200 @@ -19,7 +19,7 @@ # import interfaces from pyams_security.interfaces import IGroupsFolderPlugin, ILocalGroup, IPrincipalsAddedToGroupEvent, \ - IPrincipalsRemovedFromGroupEvent, PrincipalsAddedToGroupEvent, PrincipalsRemovedFromGroupEvent + IPrincipalsRemovedFromGroupEvent, PrincipalsAddedToGroupEvent, PrincipalsRemovedFromGroupEvent, ISecurityManager from zope.lifecycleevent.interfaces import IObjectAddedEvent # import packages @@ -83,7 +83,7 @@ return False return group_id not in self - def get_principal(self, principal_id): + def get_principal(self, principal_id, info=True): if not self.enabled: return None if not principal_id.startswith(self.prefix + ':'): @@ -91,9 +91,12 @@ prefix, group_id = principal_id.split(':', 1) group = self.get(group_id) if group is not None: - return PrincipalInfo(id='{prefix}:{group_id}'.format(prefix=self.prefix, - group_id=group.group_id), - title=group.title) + if info: + return PrincipalInfo(id='{prefix}:{group_id}'.format(prefix=self.prefix, + group_id=group.group_id), + title=group.title) + else: + return group def get_all_principals(self, principal_id, seen=None): if not self.enabled: diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/plugin/social.py --- a/src/pyams_security/plugin/social.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/plugin/social.py Wed Jun 17 09:59:18 2015 +0200 @@ -94,7 +94,7 @@ title = FieldProperty(ISocialUsersFolderPlugin['title']) enabled = FieldProperty(ISocialUsersFolderPlugin['enabled']) - def get_principal(self, principal_id): + def get_principal(self, principal_id, info=True): if not self.enabled: return None if not principal_id.startswith(self.prefix + ':'): @@ -102,9 +102,12 @@ prefix, login = principal_id.split(':', 1) user = self.get(login) if user is not None: - return PrincipalInfo(id='{prefix}:{user_id}'.format(prefix=self.prefix, - user_id=user.user_id), - title=user.title) + if info: + return PrincipalInfo(id='{prefix}:{user_id}'.format(prefix=self.prefix, + user_id=user.user_id), + title=user.title) + else: + return user def get_all_principals(self, principal_id): if not self.enabled: diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/plugin/userfolder.py --- a/src/pyams_security/plugin/userfolder.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/plugin/userfolder.py Wed Jun 17 09:59:18 2015 +0200 @@ -9,8 +9,6 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # -from zope.component.interfaces import ISite -from pyams_utils.traversing import get_parent __docformat__ = 'restructuredtext' @@ -30,6 +28,7 @@ from pyams_security.interfaces.notification import INotificationSettings from pyramid_chameleon.interfaces import IChameleonTranslate from pyramid_mailer.interfaces import IMailer +from zope.component.interfaces import ISite from zope.lifecycleevent.interfaces import IObjectAddedEvent from zope.password.interfaces import IPasswordManager from zope.schema.interfaces import IVocabularyRegistry @@ -42,6 +41,7 @@ from pyams_utils.html import html_to_text from pyams_utils.registry import query_utility, get_utility from pyams_utils.request import check_request +from pyams_utils.traversing import get_parent from pyramid.events import subscriber from pyramid_mailer.message import Message, Attachment from zope.container.contained import Contained @@ -158,7 +158,7 @@ return False return login not in self - def get_principal(self, principal_id): + def get_principal(self, principal_id, info=True): if not self.enabled: return None if not principal_id.startswith(self.prefix + ':'): @@ -166,9 +166,12 @@ prefix, login = principal_id.split(':', 1) user = self.get(login) if user is not None: - return PrincipalInfo(id='{prefix}:{login}'.format(prefix=self.prefix, - login=user.login), - title=user.title) + if info: + return PrincipalInfo(id='{prefix}:{login}'.format(prefix=self.prefix, + login=user.login), + title=user.title) + else: + return user def get_all_principals(self, principal_id): if not self.enabled: diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/principal.py --- a/src/pyams_security/principal.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/principal.py Wed Jun 17 09:59:18 2015 +0200 @@ -17,8 +17,12 @@ # import interfaces from pyams_security.interfaces import IPrincipalInfo +from zope.annotation.interfaces import IAnnotations +from zope.principalannotation.interfaces import IPrincipalAnnotationUtility # import packages +from pyams_utils.adapter import adapter_config +from pyams_utils.registry import query_utility from zope.interface import implementer from zope.schema.fieldproperty import FieldProperty @@ -74,3 +78,11 @@ def __eq__(self, other): return isinstance(other, PrincipalInfo) and (self.id == other.id) + + +@adapter_config(context=IPrincipalInfo, provides=IAnnotations) +def get_principal_annotations(principal): + """Principal annotations adapter""" + annotations = query_utility(IPrincipalAnnotationUtility) + if annotations is not None: + return annotations.getAnnotations(principal) diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/property.py --- a/src/pyams_security/property.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/property.py Wed Jun 17 09:59:18 2015 +0200 @@ -18,7 +18,7 @@ # import interfaces from pyams_security.interfaces import IRole, IProtectedObject, IPrincipalInfo, IRoleProtectedObject from pyams_security.schema import IRoleField -from zope.schema.interfaces import IField +from zope.schema.interfaces import IField, ISet # import packages @@ -53,12 +53,15 @@ return protection.get_principals(self.__role_id) def __set__(self, instance, value): - if value is None: - value = set() - elif isinstance(value, str): - value = set(value.split(',')) - value = set(map(lambda x: x.id if IPrincipalInfo.providedBy(x) else x, value)) field = self.__field.bind(instance) + if ISet.providedBy(field): + if value is None: + value = set() + elif isinstance(value, str): + value = set(value.split(',')) + value = set(map(lambda x: x.id if IPrincipalInfo.providedBy(x) else x, value)) + else: + value = value.id if IPrincipalInfo.providedBy(value) else value field.validate(value) if field.readonly: raise ValueError("Field {0} is readonly!".format(self.__name)) @@ -67,6 +70,8 @@ raise ValueError("Can't use role properties on object not providing " "IRoleProtectedObject interface!") old_principals = protection.get_principals(self.__role_id) + if not isinstance(value, set): + value = {value} added = value - old_principals removed = old_principals - value for principal_id in added: diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/role.py --- a/src/pyams_security/role.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/role.py Wed Jun 17 09:59:18 2015 +0200 @@ -34,6 +34,7 @@ title = FieldProperty(IRole['title']) description = FieldProperty(IRole['description']) permissions = FieldProperty(IRole['permissions']) + managers = FieldProperty(IRole['managers']) def __init__(self, values=None, **args): if not isinstance(values, dict): @@ -42,6 +43,7 @@ self.title = values.get('title') self.description = values.get('description') self.permissions = values.get('permissions') + self.managers = values.get('managers') def register_role(config, role): @@ -66,6 +68,8 @@ # new registration of a given role to add permissions role_utility.permissions = (role_utility.permissions or set()) | \ (role.get('permissions') or set()) + role_utility.managers = (role_utility.managers or set()) | \ + (role.get('managers') or set()) else: registry.registerUtility(role, IRole, name=role.id) diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/security.py --- a/src/pyams_security/security.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/security.py Wed Jun 17 09:59:18 2015 +0200 @@ -27,7 +27,6 @@ from pyams_utils.adapter import adapter_config from pyams_utils.property import request_property from pyams_utils.registry import query_utility -from pyams_utils.request import check_request from pyramid.location import lineage from pyramid.security import DENY_ALL, Everyone, Allow, ALL_PERMISSIONS, Authenticated from pyramid.threadlocal import get_current_registry @@ -88,7 +87,7 @@ self._authenticated_permissions = value def grant_role(self, role_id, principal_ids): - registry = check_request().registry + registry = get_current_registry() if IRole.providedBy(role_id): role_id = role_id.id if isinstance(principal_ids, str): @@ -106,13 +105,13 @@ registry.notify(GrantedRoleEvent(self, role_id, principal_id)) def revoke_role(self, role_id, principal_ids): - registry = check_request().registry + registry = get_current_registry() if IRole.providedBy(role_id): role_id = role_id.id if isinstance(principal_ids, str): principal_ids = {principal_ids} role_principals = self._principals_by_role.get(role_id) or set() - for principal_id in principal_ids: + for principal_id in principal_ids.copy(): if IPrincipalInfo.providedBy(principal_id): principal_id = principal_id.id if principal_id in role_principals: @@ -140,7 +139,7 @@ return self._roles_by_principal.get(principal_id) or set() def get_permissions(self, principal_id): - registry = check_request().registry + registry = get_current_registry() result = set() for role_id in self.get_roles(principal_id): role = registry.queryUtility(IRole, role_id) diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/site.py --- a/src/pyams_security/site.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/site.py Wed Jun 17 09:59:18 2015 +0200 @@ -19,6 +19,7 @@ from pyams_security.interfaces import ISecurityManager from pyams_utils.interfaces.site import ISiteGenerations from zope.lifecycleevent.interfaces import IObjectCreatedEvent +from zope.principalannotation.interfaces import IPrincipalAnnotationUtility from zope.site.interfaces import INewLocalSite # import packages @@ -29,14 +30,16 @@ from pyramid.events import subscriber from pyramid.threadlocal import get_current_registry from zope.lifecycleevent import ObjectCreatedEvent +from zope.principalannotation.utility import PrincipalAnnotationUtility -REQUIRED_UTILITIES = ((ISecurityManager, '', SecurityManager, 'Security manager'),) +REQUIRED_UTILITIES = ((ISecurityManager, '', SecurityManager, 'Security manager'), + (IPrincipalAnnotationUtility, '', PrincipalAnnotationUtility, 'User profiles')) @subscriber(INewLocalSite) def handle_new_local_site(event): - """Create a new negotiator when a site is created""" + """Create a new security manager when a site is created""" site = event.manager.__parent__ check_required_utilities(site, REQUIRED_UTILITIES) diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/utility.py --- a/src/pyams_security/utility.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/utility.py Wed Jun 17 09:59:18 2015 +0200 @@ -17,6 +17,8 @@ import logging logger = logging.getLogger('PyAMS (security)') +from functools import lru_cache + # import interfaces from pyams_security.interfaces import ISecurityManager, ICredentialsPlugin, IAuthenticationPlugin, \ IDirectoryPlugin, AuthenticatedPrincipalEvent, IProtectedObject, IGroupsAwareDirectoryPlugin @@ -162,12 +164,13 @@ return principals # IDirectoryPlugin interface methods - def get_principal(self, principal_id): + @lru_cache(maxsize=100) + def get_principal(self, principal_id, info=True): if not principal_id: return UnknownPrincipal for plugin in self.get_directory_plugins(): try: - principal = plugin.get_principal(principal_id) + principal = plugin.get_principal(principal_id, info) except: logging.debug("Can't get principal {0}!".format(principal_id), exc_info=True) continue diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/views/login.py --- a/src/pyams_security/views/login.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/views/login.py Wed Jun 17 09:59:18 2015 +0200 @@ -124,6 +124,8 @@ if LOGIN_REFERER_KEY in session: status['location'] = session[LOGIN_REFERER_KEY] or '/' del session[LOGIN_REFERER_KEY] + else: + status['location'] = '/' return status diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/widget/__init__.py --- a/src/pyams_security/widget/__init__.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/widget/__init__.py Wed Jun 17 09:59:18 2015 +0200 @@ -191,7 +191,11 @@ if not value: return None manager = query_utility(ISecurityManager) - return manager.get_principal(value) + if isinstance(value, str): + return manager.get_principal(value) + else: + for principal_id in value: + return manager.get_principal(principal_id) def toFieldValue(self, value): # Principal widget only returns selected principal ID diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/zmi/plugin/group.py --- a/src/pyams_security/zmi/plugin/group.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/zmi/plugin/group.py Wed Jun 17 09:59:18 2015 +0200 @@ -18,7 +18,7 @@ # import interfaces from pyams_security.interfaces import IGroupsFolderPlugin, ISecurityManager, ILocalGroup from pyams_skin.interfaces import IPageHeader, IInnerPage -from pyams_skin.interfaces.viewlet import IToolbarViewletManager, IToolbarAddingMenu +from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager from pyams_skin.layer import IPyAMSLayer from pyams_zmi.layer import IAdminLayer from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent @@ -31,6 +31,7 @@ from pyams_security.plugin.group import GroupsFolder, Group from pyams_security.zmi.utility import SecurityManagerPluginsTable from pyams_skin.container import ContainerView +from pyams_skin.page import DefaultPageHeaderAdapter from pyams_skin.table import BaseTable, I18nColumn from pyams_skin.viewlet.toolbar import ToolbarMenuItem, ToolbarAction from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter @@ -138,7 +139,7 @@ """Groups folder contents table""" id = 'groups_folder_table' - title = _("Local groups") + title = _("Local groups list") cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight datatable'} @@ -186,18 +187,17 @@ @adapter_config(context=(IGroupsFolderPlugin, IAdminLayer, GroupsFolderSearchView), provides=IPageHeader) -class GroupsFolderSearchViewHeaderAdapter(ContextRequestViewAdapter): +class GroupsFolderSearchViewHeaderAdapter(DefaultPageHeaderAdapter): """Groups folder search view header adapter""" back_url = '#security-manager.html' icon_class = 'fa fa-fw fa-users' + title = _("Security manager") @property - def title(self): + def subtitle(self): return self.context.title - subtitle = _("Groups list") - # # Groups views @@ -205,7 +205,7 @@ @viewlet_config(name='groups-folder.toolbar.adding', context=IGroupsFolderPlugin, view=GroupsFolderContentsTable, layer=IAdminLayer, - manager=IToolbarViewletManager, permission='system.manage') + manager=IWidgetTitleViewletManager, permission='system.manage') class LocalGroupAddAction(ToolbarAction): """Groups folder adding action""" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/zmi/plugin/social.py --- a/src/pyams_security/zmi/plugin/social.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/zmi/plugin/social.py Wed Jun 17 09:59:18 2015 +0200 @@ -20,7 +20,7 @@ ISocialLoginConfiguration, ISocialLoginProviderConnection from pyams_security.zmi.interfaces import ISecurityManagerMenu from pyams_skin.interfaces import IPageHeader, IInnerPage -from pyams_skin.interfaces.viewlet import IToolbarViewletManager, IToolbarAddingMenu +from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager from pyams_skin.layer import IPyAMSLayer from pyams_zmi.layer import IAdminLayer from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent @@ -35,6 +35,7 @@ from pyams_security.plugin.social import SocialUsersFolder, SocialLoginProviderConnection, get_provider_info from pyams_security.zmi.utility import SecurityManagerPluginsTable from pyams_skin.container import ContainerView +from pyams_skin.page import DefaultPageHeaderAdapter from pyams_skin.skin import apply_skin from pyams_skin.table import I18nColumn, BaseTable, ActionColumn, TrashColumn from pyams_skin.viewlet.menu import MenuItem @@ -150,7 +151,7 @@ @adapter_config(context=(ISocialUsersFolderPlugin, IAdminLayer, SocialUsersFolderSearchView), provides=IPageHeader) -class SocialUsersFolderSearchViewHeaderAdapter(ContextRequestViewAdapter): +class SocialUsersFolderSearchViewHeaderAdapter(DefaultPageHeaderAdapter): """Social users folder search view header adapter""" back_url = '#security-manager.html' @@ -363,7 +364,7 @@ @adapter_config(context=(ISite, IAdminLayer, SecurityManagerSocialProvidersView), provides=IPageHeader) -class SecurityManagerSocialProvidersHeaderAdapter(ContextRequestViewAdapter): +class SecurityManagerSocialProvidersHeaderAdapter(DefaultPageHeaderAdapter): """Security manager social providers header adapter""" icon_class = 'fa fa-fw fa-share-alt' @@ -372,7 +373,7 @@ @viewlet_config(name='security-manager.social.adding', context=ISite, view=SecurityManagerSocialProvidersTable, - layer=IAdminLayer, manager=IToolbarViewletManager, permission='system.manage') + layer=IAdminLayer, manager=IWidgetTitleViewletManager, permission='system.manage') class SocialToolbarAddingsAction(ToolbarAction): """Security manager social toolbar adding action""" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/zmi/plugin/userfolder.py --- a/src/pyams_security/zmi/plugin/userfolder.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/zmi/plugin/userfolder.py Wed Jun 17 09:59:18 2015 +0200 @@ -17,8 +17,9 @@ from datetime import datetime # import interfaces +from pyams_pagelet.interfaces import PageletCreatedEvent from pyams_security.interfaces import IUsersFolderPlugin, ISecurityManager, ILocalUser, IUserRegistrationInfo -from pyams_skin.interfaces.viewlet import IToolbarViewletManager, IToolbarAddingMenu +from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager from pyams_skin.interfaces import IPageHeader from pyams_skin.layer import IPyAMSLayer from pyams_zmi.layer import IAdminLayer @@ -33,10 +34,10 @@ from pyams_pagelet.pagelet import pagelet_config from pyams_security.plugin.userfolder import UsersFolder, User from pyams_security.zmi.utility import SecurityManagerPluginsTable -from pyams_skin.skin import apply_skin +from pyams_skin.page import DefaultPageHeaderAdapter from pyams_skin.table import I18nColumn from pyams_skin.viewlet.toolbar import ToolbarMenuItem, ToolbarAction -from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter +from pyams_utils.adapter import adapter_config from pyams_utils.date import format_datetime from pyams_utils.registry import query_utility from pyams_utils.url import absolute_url @@ -147,18 +148,17 @@ @adapter_config(context=(IUsersFolderPlugin, IAdminLayer, UsersFolderSearchView), provides=IPageHeader) -class UsersFolderSearchViewHeaderAdapter(ContextRequestViewAdapter): +class UsersFolderSearchViewHeaderAdapter(DefaultPageHeaderAdapter): """Users folder search view header adapter""" back_url = '#security-manager.html' icon_class = 'fa fa-fw fa-user' + title = _("Security manager") @property - def title(self): + def subtitle(self): return self.context.title - subtitle = _("Search users") - @view_config(name='search-results.html', context=IUsersFolderPlugin, request_type=IPyAMSLayer, permission='system.view') @@ -171,7 +171,7 @@ def __init__(self, context, request): super(UsersFolderSearchResultsView, self).__init__(context, request) - apply_skin(self.request, 'PyAMS admin skin') + request.registry.notify(PageletCreatedEvent(self)) @adapter_config(name='login', context=(IUsersFolderPlugin, IAdminLayer, UsersFolderSearchResultsView), @@ -241,7 +241,7 @@ @viewlet_config(name='users-folder.toolbar.adding', context=IUsersFolderPlugin, view=UsersFolderSearchView.search_form_factory, layer=IAdminLayer, - manager=IToolbarViewletManager, permission='system.manage') + manager=IWidgetTitleViewletManager, permission='system.manage') class LocalUserAddAction(ToolbarAction): """Users folder adding action""" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/zmi/security.py --- a/src/pyams_security/zmi/security.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/zmi/security.py Wed Jun 17 09:59:18 2015 +0200 @@ -16,25 +16,36 @@ # import standard library # import interfaces -from pyams_security.interfaces import IDefaultProtectionPolicy, IProtectedObject +from pyams_form.interfaces.form import IInnerSubForm +from pyams_security.interfaces import IDefaultProtectionPolicy, IProtectedObject, IRole from pyams_skin.layer import IPyAMSLayer from pyams_zmi.interfaces.menu import IPropertiesMenu from pyams_zmi.layer import IAdminLayer +from z3c.form.interfaces import DISPLAY_MODE, INPUT_MODE # import packages -from pyams_form.form import AJAXEditForm +from pyams_form.form import AJAXEditForm, InnerEditForm from pyams_pagelet.pagelet import pagelet_config -from pyams_skin.viewlet.menu import MenuItem +from pyams_skin.viewlet.menu import MenuItem, MenuDivider +from pyams_utils.adapter import adapter_config +from pyams_utils.registry import get_utility from pyams_viewlet.viewlet import viewlet_config from pyams_zmi.form import AdminDialogEditForm from pyramid.view import view_config from z3c.form import field +from zope.interface import 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""" + + @viewlet_config(name='protected-object-roles.menu', context=IDefaultProtectionPolicy, layer=IAdminLayer, - manager=IPropertiesMenu, permission='system.view', weight=10) + manager=IPropertiesMenu, permission='system.view', weight=900) class ProtectedObjectRolesMenuItem(MenuItem): """Protected object roles menu item""" @@ -49,32 +60,67 @@ class ProtectedObjectRolesEditForm(AdminDialogEditForm): """Protected object roles edit form""" - @property - def title(self): - return self.context.title + legend = None + fieldset_class = 'no-padding' + + fields = field.Fields(Interface) + ajax_handler = 'protected-object-roles.json' + edit_permission = None + - legend = _("Edit local roles") +@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' - ajax_handler = 'protected-object-roles.json' - edit_permission = 'system.manage' - - @property - def fields(self): - fields = field.Fields(IProtectedObject) + \ - field.Fields(self.context.roles_interface) - return fields + fields = field.Fields(IProtectedObject) + edit_permission = 'security.manage' + weight = 1 def updateWidgets(self, prefix=None): - super(ProtectedObjectRolesEditForm, self).updateWidgets() + super(ProtectedObjectSecuritySubform, self).updateWidgets() translate = self.request.localizer.translate self.widgets['everyone_permissions'].noValueMessage = translate(_("(inherit from parent)")) self.widgets['authenticated_permissions'].noValueMessage = translate(_("(inherit from parent)")) +@adapter_config(name='roles.subform', + context=(IDefaultProtectionPolicy, IPyAMSLayer, ProtectedObjectRolesEditForm), + provides=IInnerSubForm) +class ProtectedObjectRolesSubform(InnerEditForm): + """Protected object roles edit form""" + + legend = _("Granted 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 + + def updateWidgets(self, prefix=None): + super(ProtectedObjectRolesSubform, self).updateWidgets(prefix) + if self.mode == DISPLAY_MODE: + return + principals = self.request.effective_principals + for widget in self.widgets.values(): + widget.mode = DISPLAY_MODE + role = get_utility(IRole, name=widget.field.role_id) + if role.managers: + for manager in role.managers: + if manager in principals: + widget.mode = INPUT_MODE + + @view_config(name='protected-object-roles.json', context=IDefaultProtectionPolicy, request_type=IPyAMSLayer, - permission='system.manage', renderer='json', xhr=True) + permission='security.manage', renderer='json', xhr=True) class ProtectedObjectRolesAJAXEditForm(AJAXEditForm, ProtectedObjectRolesEditForm): """Protected object roles edit form, AJAX view""" diff -r 905e30f5467b -r 07229ac2497b src/pyams_security/zmi/utility.py --- a/src/pyams_security/zmi/utility.py Wed May 20 12:31:27 2015 +0200 +++ b/src/pyams_security/zmi/utility.py Wed Jun 17 09:59:18 2015 +0200 @@ -32,6 +32,7 @@ from pyams_pagelet.pagelet import pagelet_config from pyams_security.zmi.widget import OrderedPluginsFieldWidget from pyams_skin.container import ContainerView +from pyams_skin.page import DefaultPageHeaderAdapter from pyams_skin.table import BaseTable, DefaultElementEditorAdapter, ActionColumn, I18nColumn, TrashColumn from pyams_skin.viewlet.menu import MenuItem from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config @@ -155,12 +156,12 @@ @adapter_config(context=(ISite, IAdminLayer, SecurityManagerView), provides=IPageHeader) -class SecurityManagerHeaderAdapter(ContextRequestViewAdapter): +class SecurityManagerHeaderAdapter(DefaultPageHeaderAdapter): """Security manager header adapter""" icon_class = 'fa fa-fw fa-lock' - title = _("Security manager") - subtitle = _("Security manager plug-ins") + title = _("Control panel") + subtitle = _("Security manager") @viewlet_config(name='security-manager.properties.menu', context=ISite, layer=IAdminLayer,