from Products.ERP5Type.Utils import cartesianProduct def asSecurityGroupIdList(self, category_order=None, **kw): # category_order : list of base_categories we want to use to generate the group id # kw : keys should be base categories, # values should be value of corresponding relative urls (obtained by getBaseCategory()) # # Example call : self.ERP5TypeSecurity_asGroupId(category_order=('site', 'group', 'function'), # site='france/lille', group='nexedi', function='accounting/accountant') # This will generate a string like 'LIL_NXD_ACT' where "LIL", "NXD" and "ACT" are the codification # of respecively "france/lille", "nexedi" and "accounting/accountant" categories # # ERP5Type_asSecurityGroupId can also return a list of users whenever a category points # to a Person instance. This is useful to implement user based local role assignments code_list = [] user_list = [] # sort the category list lexicographically # this prevents us to choose the exact order we want, # but also prevents some human mistake to break everything by creating site_function instead of function_site if category_order not in (None, ''): category_order = list(category_order) category_order.sort() else: category_order = [] code_dict = {} for base_category in category_order: code_dict[base_category] = [] category_list = kw[base_category] if isinstance(category_list, str): category_list = [category_list] for category in category_list: category_path = '%s/%s' % (base_category, category) category_object = self.portal_categories.getCategoryValue(category_path) if category_object in (None, ''): raise RuntimeError, "Category '%s' doesn't exist" % (category_path) if category_object.getPortalType() == 'Person': # We define a person here user_name = category_object.getReference() if user_name is not None: user_list.append(user_name) else: # We define a group item here try: category_code = category_object.getCodification() except AttributeError: category_code = category_object.getReference() if category_code not in code_dict[base_category]: code_dict[base_category].append(category_code) if base_category=='site': category_object = category_object.getParentValue() while category_object.getPortalType()!='Base Category': # LOG('checking category_object:',0,category_object.getRelativeUrl()) category_code = category_object.getCodification() if category_code is not None and category_code not in code_dict[base_category]: code_dict[base_category].append(category_code) category_object = category_object.getParentValue() #code_list.append(category_code) # Return a list of users or a single group #LOG('asSecurityGroupIdList, user_list',0,user_list) if user_list: return user_list # LOG('asSecurityGroupIdList, code_dict',0,code_dict) def getCombinationList(item_list): if len(item_list): result = getCombinationList(item_list[1:]) return [item_list[:1] + x for x in result] + result return [[]] code_list_of_list = [] for base_category in category_order: code_list_of_list.append(code_dict[base_category]) full_code_list = [] for code_list in cartesianProduct(code_list_of_list): for x in getCombinationList(code_list): if len(x): # we have to sort it to match these in object local roles x.sort() full_code_list.extend(['_'.join(x) ]) #LOG('asSecurityGroupIdList, result',0,['_'.join(x) for x in getCombinationList(code_list) if len(x)]) #return ['_'.join(x) for x in getCombinationList(code_list) if len(x)] #LOG('asSecurityGroupIdList', 0, 'return full_code_list = %s' %(full_code_list,)) #self.log('full_code_list',full_code_list) return full_code_list