--- a/src/pyams_security/utility.py Sat Feb 28 15:28:24 2015 +0100
+++ b/src/pyams_security/utility.py Sat Feb 28 15:29:00 2015 +0100
@@ -14,10 +14,12 @@
# import standard library
+import logging
+logger = logging.getLogger('PyAMS (security)')
# import interfaces
from pyams_security.interfaces import ISecurityManager, ICredentialsPlugin, IAuthenticationPlugin, \
- IDirectoryPlugin, AuthenticatedPrincipalEvent, IProtectedObject
+ IDirectoryPlugin, AuthenticatedPrincipalEvent, IProtectedObject, IGroupsAwareDirectoryPlugin
from pyramid.interfaces import IAuthenticationPolicy
# import packages
@@ -94,6 +96,12 @@
if IDirectoryPlugin.providedBy(plugin):
yield plugin
+ def get_groups_directory_plugins(self):
+ for name in self.directory_plugins_names or ():
+ plugin = self.get(name)
+ if IGroupsAwareDirectoryPlugin.providedBy(plugin):
+ yield plugin
+
# IAuthenticationInfo interface methods
def extract_credentials(self, request, **kwargs):
for plugin in self.get_credentials_plugins():
@@ -103,10 +111,15 @@
def authenticate(self, credentials, request):
for plugin in self.get_authentication_plugins():
- principal_id = plugin.authenticate(credentials, request)
- if principal_id is not None:
- request.registry.notify(AuthenticatedPrincipalEvent(plugin.prefix, principal_id))
- return principal_id
+ try:
+ principal_id = plugin.authenticate(credentials, request)
+ except:
+ logging.debug("Can't authenticate!", exc_info=True)
+ continue
+ else:
+ if principal_id is not None:
+ request.registry.notify(AuthenticatedPrincipalEvent(plugin.prefix, principal_id))
+ return principal_id
def authenticated_userid(self, request):
credentials = self.extract_credentials(request)
@@ -118,13 +131,24 @@
if principal is not None:
return principal.id
- def effective_principals(self, principal_id, request=None):
+ # @cache_region('short', 'security_plugins_principals')
+ def _get_plugins_principals(self, principal_id):
principals = set()
+ # get direct principals
for plugin in self.get_directory_plugins():
principals |= set(plugin.get_all_principals(principal_id))
+ # get indirect principals by searching groups members
+ for principal in principals.copy():
+ for plugin in self.get_groups_directory_plugins():
+ principals |= set(plugin.get_all_principals(principal))
+ return principals
+
+ def effective_principals(self, principal_id, request=None):
+ # add principals extracted from security plug-ins
+ principals = self._get_plugins_principals(principal_id)
+ # add context roles granted to principal
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):
@@ -142,15 +166,24 @@
if not principal_id:
return UnknownPrincipal
for plugin in self.get_directory_plugins():
- principal = plugin.get_principal(principal_id)
- if principal is not None:
- return principal
+ try:
+ principal = plugin.get_principal(principal_id)
+ except:
+ logging.debug("Can't get principal {0}!".format(principal_id), exc_info=True)
+ continue
+ else:
+ if principal is not None:
+ return principal
return MissingPrincipal(id=principal_id)
def find_principals(self, query):
principals = set()
for plugin in self.get_directory_plugins():
- principals |= set(plugin.find_principals(query))
+ try:
+ principals |= set(plugin.find_principals(query))
+ except:
+ logging.debug("Can't find principals!", exc_info=True)
+ continue
return sorted(principals, key=lambda x: x.title)
@@ -236,7 +269,7 @@
manager = self._get_security_manager(request)
if manager is not None:
principals |= set(manager.effective_principals(principal_id))
- print(principals)
+ logger.debug('principals = {0}'.format(str(principals)))
return principals
def remember(self, request, principal, **kw):