Added debug traces and exceptions checks
authorThierry Florac <tflorac@ulthar.net>
Sat, 28 Feb 2015 15:29:00 +0100
changeset 12 f227ffa9e824
parent 11 7f3ca73c67e6
child 13 2384821d0ddc
Added debug traces and exceptions checks
src/pyams_security/utility.py
--- 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):