ERP5GroupManager.py 6.12 KB
Newer Older
Jean-Paul Smets's avatar
Jean-Paul Smets committed
1 2
##############################################################################
#
3 4
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights
# Reserved.
Jean-Paul Smets's avatar
Jean-Paul Smets committed
5
#
6 7 8 9 10 11 12
# 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.
Jean-Paul Smets's avatar
Jean-Paul Smets committed
13 14 15 16 17 18 19
#
##############################################################################
""" Classes: ERP5GroupManager
"""

from Globals import InitializeClass
from AccessControl import ClassSecurityInfo
20 21
from AccessControl.SecurityManagement import newSecurityManager,\
    getSecurityManager, setSecurityManager
Jean-Paul Smets's avatar
Jean-Paul Smets committed
22 23 24 25 26
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
from Products.PluggableAuthService.utils import classImplements
from Products.PluggableAuthService.interfaces.plugins import IGroupsPlugin
from Products.ERP5Type.Cache import CachingMethod
27
from Products.PluggableAuthService.PropertiedUser import PropertiedUser
Jean-Paul Smets's avatar
Jean-Paul Smets committed
28

Alexandre Boeglin's avatar
Alexandre Boeglin committed
29 30
from pickle import dumps, loads

Jean-Paul Smets's avatar
Jean-Paul Smets committed
31 32
from zLOG import LOG

33 34
from ERP5UserManager import SUPER_USER

Jean-Paul Smets's avatar
Jean-Paul Smets committed
35 36 37 38
manage_addERP5GroupManagerForm = PageTemplateFile(
    'www/ERP5Security_addERP5GroupManager', globals(), __name__='manage_addERP5GroupManagerForm' )

def addERP5GroupManager( dispatcher, id, title=None, REQUEST=None ):
Alexandre Boeglin's avatar
Alexandre Boeglin committed
39
  """ Add a ERP5GroupManager to a Pluggable Auth Service. """
Jean-Paul Smets's avatar
Jean-Paul Smets committed
40

Alexandre Boeglin's avatar
Alexandre Boeglin committed
41 42
  egm = ERP5GroupManager(id, title)
  dispatcher._setObject(egm.getId(), egm)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
43

Alexandre Boeglin's avatar
Alexandre Boeglin committed
44 45 46 47 48 49
  if REQUEST is not None:
    REQUEST['RESPONSE'].redirect(
                              '%s/manage_workspace'
                              '?manage_tabs_message='
                              'ERP5GroupManager+added.'
                          % dispatcher.absolute_url())
Jean-Paul Smets's avatar
Jean-Paul Smets committed
50 51 52

class ERP5GroupManager(BasePlugin):

Alexandre Boeglin's avatar
Alexandre Boeglin committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
  """ 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.
Jean-Paul Smets's avatar
Jean-Paul Smets committed
70
    """
71 72 73 74
    # If this is the super user, skip the check.
    if principal.getId() == SUPER_USER:
      return ()

Alexandre Boeglin's avatar
Alexandre Boeglin committed
75 76 77 78
    def _getGroupsForPrincipal(user_name, path):
      security_category_dict = {} # key is the base_category_list,
                                  # value is the list of fetched categories
      security_group_list = []
79
      security_definition_list = ()
Alexandre Boeglin's avatar
Alexandre Boeglin committed
80 81 82

      # because we aren't logged in, we have to create our own
      # SecurityManager to be able to access the Catalog
83
      sm = getSecurityManager()
84 85
      if sm.getUser() != SUPER_USER:
        newSecurityManager(self, self.getUser(SUPER_USER))
Alexandre Boeglin's avatar
Alexandre Boeglin committed
86 87

      # To get the complete list of groups, we try to call the
88 89 90 91 92 93
      # ERP5Type_getSecurityCategoryMapping which should return a list
      # of lists of two elements (script, base_category_list) like :
      # (
      #   ('script_1', ['base_category_1', 'base_category_2', ...]),
      #   ('script_2', ['base_category_1', 'base_category_3', ...])
      # )
Alexandre Boeglin's avatar
Alexandre Boeglin committed
94
      #
95 96 97 98
      # else, if the script does not exist, falls back to a list containng
      # only one list :
      # (('ERP5Type_getSecurityCategoryFromAssignment',
      #   self.getPortalAssignmentBaseCategoryList() ),)
Alexandre Boeglin's avatar
Alexandre Boeglin committed
99 100 101 102

      mapping_method = getattr(self,
          'ERP5Type_getSecurityCategoryMapping', None)
      if mapping_method is None:
103 104
        security_definition_list = ((
            'ERP5Type_getSecurityCategoryFromAssignment',
Alexandre Boeglin's avatar
Alexandre Boeglin committed
105
            self.getPortalAssignmentBaseCategoryList()
106
        ),)
Alexandre Boeglin's avatar
Alexandre Boeglin committed
107
      else:
108
        security_definition_list = mapping_method()
Alexandre Boeglin's avatar
Alexandre Boeglin committed
109 110

      # get the person from its reference
111 112
      catalog_result = self.portal_catalog(
          portal_type="Person", reference=user_name)
Alexandre Boeglin's avatar
Alexandre Boeglin committed
113 114 115 116 117 118
      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
119
          setSecurityManager(sm)
Alexandre Boeglin's avatar
Alexandre Boeglin committed
120 121 122 123 124
          return ()
      person_object = catalog_result[0].getObject()
      person_id = person_object.getId()

      # Fetch category values from defined scripts
125 126
      for (method_name, base_category_list) in \
          security_definition_list:
127
        base_category_list = tuple(base_category_list)
Alexandre Boeglin's avatar
Alexandre Boeglin committed
128
        method = getattr(self, method_name)
129 130
        security_category_list = security_category_dict.setdefault(base_category_list, [])
        security_category_list.extend(method(base_category_list, person_id, person_object, ''))
Alexandre Boeglin's avatar
Alexandre Boeglin committed
131 132

      # Get group names from category values
133 134 135 136 137 138 139 140 141 142 143 144 145 146
      group_id_list_generator = getattr(self, 'ERP5Type_asSecurityGroupIdList', None)
      if group_id_list_generator is not None:
        for base_category_list, category_value_list in \
            security_category_dict.items():
          for category_dict in category_value_list:
            security_group_list.extend(group_id_list_generator(
                category_order=base_category_list, **category_dict))
      else:
        group_id_generator = getattr(self, 'ERP5Type_asSecurityGroupId')
        for base_category_list, category_value_list in \
            security_category_dict.items():
          for category_dict in category_value_list:
            security_group_list.append(group_id_generator(
                category_order=base_category_list, **category_dict))
Alexandre Boeglin's avatar
Alexandre Boeglin committed
147

148
      setSecurityManager(sm)
Alexandre Boeglin's avatar
Alexandre Boeglin committed
149 150 151 152 153 154 155
      return tuple(security_group_list)

    _getGroupsForPrincipal = CachingMethod(_getGroupsForPrincipal, id='ERP5GroupManager_getGroupsForPrincipal')
    return _getGroupsForPrincipal(user_name=principal.getId(), path=self.getPhysicalPath())



Jean-Paul Smets's avatar
Jean-Paul Smets committed
156 157 158 159 160
classImplements( ERP5GroupManager
               , IGroupsPlugin
               )

InitializeClass(ERP5GroupManager)