--- a/src/pyams_security/utility.py Sun Feb 22 14:52:32 2015 +0100
+++ b/src/pyams_security/utility.py Mon Feb 23 17:55:05 2015 +0100
@@ -17,15 +17,17 @@
# import interfaces
from pyams_security.interfaces import ISecurityManager, ICredentialsPlugin, IAuthenticationPlugin, \
- IDirectoryPlugin, AuthenticatedPrincipalEvent
+ IDirectoryPlugin, AuthenticatedPrincipalEvent, IProtectedObject
from pyramid.interfaces import IAuthenticationPolicy
# import packages
from pyams_security.principal import UnknownPrincipal, MissingPrincipal
from pyams_utils.registry import query_utility
from pyams_utils.request import check_request
+from pyams_utils.wsgi import wsgi_environ_cache
from pyramid.authentication import AuthTktCookieHelper
from pyramid.decorator import reify
+from pyramid.location import lineage
from pyramid.security import Everyone, Authenticated
from zope.container.folder import Folder
from zope.interface import implementer
@@ -37,6 +39,7 @@
"""Security manager utility"""
enable_social_login = FieldProperty(ISecurityManager['enable_social_login'])
+ social_users_folder = FieldProperty(ISecurityManager['social_users_folder'])
authomatic_secret = FieldProperty(ISecurityManager['authomatic_secret'])
social_login_use_popup = FieldProperty(ISecurityManager['social_login_use_popup'])
open_registration = FieldProperty(ISecurityManager['open_registration'])
@@ -61,9 +64,9 @@
def __delitem__(self, key):
super(SecurityManager, self).__delitem__(key)
if key in self.authentication_plugins_names:
- del self.authentication_plugins_names[self.authentication_plugins_names.index(key)]
+ self.authentication_plugins_names = tuple(filter(lambda x: x != key, self.authentication_plugins_names))
if key in self.directory_plugins_names:
- del self.directory_plugins_names[self.directory_plugins_names.index(key)]
+ self.directory_plugins_names = tuple(filter(lambda x: x != key, self.directory_plugins_names))
def get_plugin(self, name):
if name in self.credentials_plugins_names:
@@ -115,10 +118,23 @@
if principal is not None:
return principal.id
- def effective_principals(self, principal_id):
+ def effective_principals(self, principal_id, request=None):
principals = set()
for plugin in self.get_directory_plugins():
principals |= set(plugin.get_all_principals(principal_id))
+ if request is None:
+ request = check_request()
+ # add context roles granted to principal
+ context = request.context
+ if context is not None:
+ for parent in lineage(context):
+ protection = IProtectedObject(parent, None)
+ if protection is not None:
+ for principal_id in principals.copy():
+ principals |= set(map(lambda x: 'role:{0}'.format(x),
+ protection.get_roles(principal_id)))
+ if not protection.inherit_parent_roles:
+ break
return principals
# IDirectoryPlugin interface methods
@@ -134,7 +150,7 @@
def find_principals(self, query):
principals = set()
for plugin in self.get_directory_plugins():
- principals |= set(plugin.find_principals(query) or set())
+ principals |= set(plugin.find_principals(query))
return sorted(principals, key=lambda x: x.title)
@@ -153,7 +169,7 @@
"""
def __init__(self, secret,
- credentials=('http', 'session'),
+ credentials=('http', ),
cookie_name='auth_ticket',
secure=False,
include_ip=False,
@@ -189,6 +205,7 @@
def _get_security_manager(self, request):
return query_utility(ISecurityManager)
+ @wsgi_environ_cache('pyams_security.unauthenticated_userid')
def unauthenticated_userid(self, request):
result = self.cookie.identify(request)
if result:
@@ -199,6 +216,7 @@
if credentials is not None:
return credentials.id
+ @wsgi_environ_cache('pyams_security.authenticated_userid')
def authenticated_userid(self, request):
principal_id = self.unauthenticated_userid(request)
if principal_id:
@@ -207,10 +225,12 @@
if manager is not None:
return manager.authenticated_userid(request)
+ @wsgi_environ_cache('pyams_security.effective_principals')
def effective_principals(self, request):
principals = {Everyone}
principal_id = self.unauthenticated_userid(request)
if principal_id:
+ # get authenticated user principals
principals.add(Authenticated)
principals.add(principal_id)
manager = self._get_security_manager(request)