From f6342cb780dd209cb0e8945fd7aab778814e9cd2 Mon Sep 17 00:00:00 2001
From: Alexandre Boeglin <alex@nexedi.com>
Date: Fri, 2 Dec 2005 13:43:36 +0000
Subject: [PATCH] Fixed indentation. Now uses Person reference instead of id as
 login. Can be extended through a Python Script.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@4468 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Security/ERP5GroupManager.py | 162 ++++++++++++++---------
 1 file changed, 99 insertions(+), 63 deletions(-)

diff --git a/product/ERP5Security/ERP5GroupManager.py b/product/ERP5Security/ERP5GroupManager.py
index 4d1a757fc0..41ad3f2be6 100755
--- a/product/ERP5Security/ERP5GroupManager.py
+++ b/product/ERP5Security/ERP5GroupManager.py
@@ -24,81 +24,117 @@ from Products.PluggableAuthService.utils import classImplements
 from Products.PluggableAuthService.interfaces.plugins import IGroupsPlugin
 from Products.ERP5Type.Cache import CachingMethod
 
+from pickle import dumps, loads
+
 from zLOG import LOG
 
 manage_addERP5GroupManagerForm = PageTemplateFile(
     'www/ERP5Security_addERP5GroupManager', globals(), __name__='manage_addERP5GroupManagerForm' )
 
 def addERP5GroupManager( dispatcher, id, title=None, REQUEST=None ):
-    """ Add a ERP5GroupManager to a Pluggable Auth Service. """
+  """ Add a ERP5GroupManager to a Pluggable Auth Service. """
 
-    egm = ERP5GroupManager(id, title)
-    dispatcher._setObject(egm.getId(), egm)
+  egm = ERP5GroupManager(id, title)
+  dispatcher._setObject(egm.getId(), egm)
 
-    if REQUEST is not None:
-        REQUEST['RESPONSE'].redirect(
-                                '%s/manage_workspace'
-                                '?manage_tabs_message='
-                                'ERP5GroupManager+added.'
-                            % dispatcher.absolute_url())
+  if REQUEST is not None:
+    REQUEST['RESPONSE'].redirect(
+                              '%s/manage_workspace'
+                              '?manage_tabs_message='
+                              'ERP5GroupManager+added.'
+                          % dispatcher.absolute_url())
 
 class ERP5GroupManager(BasePlugin):
 
-    """ PAS plugin for dynamically adding Groups
-    based on Assignments in ERP5
+  """ PAS plugin for dynamically adding Groups
+  based on Assignments in ERP5
+  """
+  meta_type = 'ERP5 Group Manager'
+
+  security = ClassSecurityInfo()
+
+  def __init__(self, id, title=None):
+
+    self._id = self.id = id
+    self.title = title
+
+  #
+  #   IGroupsPlugin implementation
+  #
+  def getGroupsForPrincipal(self, principal, request=None):
+    """ See IGroupsPlugin.
     """
-    meta_type = 'ERP5 Group Manager'
-
-    security = ClassSecurityInfo()
-    
-    def __init__(self, id, title=None):
-
-        self._id = self.id = id
-        self.title = title
-
-    #
-    #   IGroupsPlugin implementation
-    #
-    def getGroupsForPrincipal(self, principal, request=None):
-        """ See IGroupsPlugin.
-        """
-        def _getGroupsForPrincipal(user_name, path):
-            security_group_list = []
-                    
-            # because we aren't logged in, we have to create our own
-            # SecurityManager to be able to access the Catalog
-            newSecurityManager(self, self.getPortalObject().getOwner())
-            base_category_list = self.getPortalObject().getPortalAssignmentBaseCategoryList()
-            
-            user_name = principal.getId()
-            
-            person_module = self.getPortalObject().getDefaultModule('Person')
-            person_object = getattr(person_module, user_name, None)
-            
-            # return no groups if the username is not registered in person module
-            if not person_object:
-                return ()
-            
-            # Fetch category values from assignment
-            category_list = self.ERP5Type_getSecurityCategoryFromAssignment(base_category_list, user_name, self, '')
-            
-            # return no groups if we there are no Security Categories
-            if not category_list:
-                return ()
-                    
-            # Get group names from category values
-            for c_dict in category_list:
-                security_group_list.append(self.ERP5Type_asSecurityGroupId(category_order=base_category_list, **c_dict))
-                
-            LOG('erp5_groups', 0, 'user %s is member of %s' %(user_name, str(security_group_list)))
-            
-            return tuple(security_group_list)
-    
-        _getGroupsForPrincipal = CachingMethod(_getGroupsForPrincipal, id='ERP5GroupManager_getGroupsForPrincipal')
-        return _getGroupsForPrincipal(user_name=principal.getId(), path=self.getPhysicalPath())
-
-
-    
+    def _getGroupsForPrincipal(user_name, path):
+      security_category_dict = {} # key is the base_category_list,
+                                  # value is the list of fetched categories
+      security_group_list = []
+      security_definition_dict = {}
+
+      # because we aren't logged in, we have to create our own
+      # SecurityManager to be able to access the Catalog
+      #FIXME here we assume that the portal owner will always have
+      #      enough rights, which might as well be wrong
+      newSecurityManager(self, self.getPortalObject().getOwner())
+
+      # To get the complete list of groups, we try to call the
+      # ERP5Type_getSecurityCategoryMapping which should return a dict
+      # like : {
+      #     'script_1':['base_category_1', 'base_category_2', ...],
+      #     'script_2':['base_category_1', 'base_category_3', ...]}
+      #
+      # else, if the script does not exist, falls back to :
+      # { 'ERP5Type_getSecurityCategoryFromAssignment':
+      #   self.getPortalAssignmentBaseCategoryList()}
+
+      mapping_method = getattr(self,
+          'ERP5Type_getSecurityCategoryMapping', None)
+      if mapping_method is None:
+        security_definition_dict = {
+            'ERP5Type_getSecurityCategoryFromAssignment':
+            self.getPortalAssignmentBaseCategoryList()
+        }
+      else:
+        security_definition_dict = mapping_method()
+
+      # get the person from its reference
+      catalog_result = self.portal_catalog(
+          portal_type="Person", reference=user_name)
+      if len(catalog_result) != 1: # we won't proceed with groups
+        if len(catalog_result) > 1: # configuration is screwed
+          raise 'ConsistencyError', 'There is more than one Person whose \
+              login is %s : %s' % (user_name,
+              repr([r.getObject() for r in catalog_result]))
+        else: # no person is linked to this user login
+          return ()
+      person_object = catalog_result[0].getObject()
+      person_id = person_object.getId()
+
+      # Fetch category values from defined scripts
+      for method_name, base_category_list in \
+          security_definition_dict.items():
+        pickled_category_list = dumps(base_category_list)
+        method = getattr(self, method_name)
+        if not security_category_dict.has_key(pickled_category_list):
+          security_category_dict[pickled_category_list] = []
+        security_category_dict[pickled_category_list].extend(
+            method(base_category_list, person_id, person_object, ''))
+
+      # Get group names from category values
+      group_id_generator = getattr(self, 'ERP5Type_asSecurityGroupId')
+      for pickled_category_list, category_value_list in \
+          security_category_dict.items():
+        base_category_list = loads(pickled_category_list)
+        for category_dict in category_value_list:
+          security_group_list.append(group_id_generator(
+              category_order=base_category_list, **category_dict))
+
+      return tuple(security_group_list)
+
+    _getGroupsForPrincipal = CachingMethod(_getGroupsForPrincipal, id='ERP5GroupManager_getGroupsForPrincipal')
+    return _getGroupsForPrincipal(user_name=principal.getId(), path=self.getPhysicalPath())
+
+
+
 classImplements( ERP5GroupManager
                , IGroupsPlugin
                )
-- 
2.30.9