--- 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
--- 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
--- 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': [
--- 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
--- 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
--- 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]
--- 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'}})
--- /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 <tflorac AT ulthar.net>
+# 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)
--- 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"""
Binary file src/pyams_security/locales/fr/LC_MESSAGES/pyams_security.mo has changed
--- 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 <tflorac@ulthar.net>\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"
--- 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 <EMAIL@ADDRESS\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""
--- 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:
--- 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:
--- 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:
--- 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:
--- 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)
--- 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:
--- 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)
--- 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)
--- 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)
--- 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
--- 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
--- 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
--- 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"""
--- 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"""
--- 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"""
--- 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"""
--- 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,