From c566864b0331830a4e37ac93ef6138df7450864c Mon Sep 17 00:00:00 2001 From: Jean-Paul Smets <jp@nexedi.com> Date: Mon, 16 Aug 2004 08:06:30 +0000 Subject: [PATCH] uses security cache git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1357 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Catalog/CatalogTool.py | 61 +++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/product/ERP5Catalog/CatalogTool.py b/product/ERP5Catalog/CatalogTool.py index 6aa0a0eb64..f394b1d2ee 100755 --- a/product/ERP5Catalog/CatalogTool.py +++ b/product/ERP5Catalog/CatalogTool.py @@ -36,6 +36,7 @@ from Products.CMFCore.utils import _mergedLocalRoles from Globals import InitializeClass, DTMLFile, PersistentMapping from Acquisition import aq_base, aq_inner, aq_parent from DateTime.DateTime import DateTime +from BTrees.OIBTree import OIBTree from AccessControl.PermissionRole import rolesForPermissionOn @@ -326,7 +327,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool): limit the results to what the user is allowed to see. """ user = _getAuthenticatedUser(self) - kw[ 'allowedRolesAndUsers' ] = self._listAllowedRolesAndUsers( user ) + kw[ 'allowedRolesAndUsers' ] = self._listAllowedRolesAndUsers( user ) # XXX allowedRolesAndUsers naming is wrong # Patch for ERP5 by JP Smets in order # to implement worklists and search of local roles @@ -399,6 +400,13 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool): else: vars = {} w = IndexableObjectWrapper(vars, object) + (security_uid, optimised_roles_and_users) = self.getSecurityUid(object, w) + #LOG('catalog_object optimised_roles_and_users', 0, str(optimised_roles_and_users)) + if optimised_roles_and_users is not None: + vars['optimised_roles_and_users'] = optimised_roles_and_users + else: + vars['optimised_roles_and_users'] = None + vars['security_uid'] = security_uid #LOG("IndexableObjectWrapper", 0,str(w.allowedRolesAndUsers())) #try: ZCatalog.catalog_object(self, w, uid, idxs=idxs, is_object_moved=is_object_moved) @@ -443,5 +451,54 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool): url = self.__url(object) self.catalog_object(object, url, idxs=idxs, is_object_moved=1) - + security.declarePrivate('getSecurityUid') + def getSecurityUid(self, object, w): + """ + Cache a uid for each security permission + + We try to create a unique security (to reduce number of lines) + and to assign security only to root document + """ + # Find parent document (XXX this extra step should be deactivated on complex ERP5 installations) + object_path = object.getPhysicalPath() + portal_path = object.portal_url.getPortalObject().getPhysicalPath() + if len(object_path) > len(portal_path) + 2: + # We are now in the case of a subobject of a root document + # We want to return single security information + document_object = aq_inner(object) + for i in range(0, len(object_path) - len(portal_path) - 2): + document_object = document_object.aq_parent + document_w = IndexableObjectWrapper({}, document_object) + return self.getSecurityUid(document_object, document_w) + # Get security information + allowed_roles_and_users = w.allowedRolesAndUsers() + # Sort it + allowed_roles_and_users = list(allowed_roles_and_users) + allowed_roles_and_users.sort() + allowed_roles_and_users = tuple(allowed_roles_and_users) + # Make sure no diplicates + if not hasattr(aq_base(self), 'security_uid_dict'): + self._clearSecurityCache() + if self.security_uid_dict.has_key(allowed_roles_and_users): + return (self.security_uid_dict[allowed_roles_and_users], None) + self.security_uid_index = self.security_uid_index + 1 + self.security_uid_dict[allowed_roles_and_users] = self.security_uid_index + return (self.security_uid_index, allowed_roles_and_users) + + # Overriden methods + def _clearSecurityCache(self): + self.security_uid_dict = OIBTree() + self.security_uid_index = 0 + + def refreshCatalog(self, clear=0): + """ clear security cache and re-index everything we can find """ + self._clearSecurityCache() + return ZCatalog.refreshCatalog(self, clear=clear) + + def manage_catalogClear(self, REQUEST=None, RESPONSE=None, URL1=None): + """ clear security cache and the rest """ + self._clearSecurityCache() + return ZCatalog.manage_catalogClear(self, REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL1) + + InitializeClass(CatalogTool) -- 2.30.9