Commit 80844559 authored by Vincent Pelletier's avatar Vincent Pelletier

ERP5Catalog: Reduce reliance on user lookup.

Use Owner role to help filling user_set: owners must be users, never
groups.
Only look for users among group_ids when they are candidate for indexation
into a catalog_role column. This should very significantly reduce the
number of user lookups, even bringing it to zero on instance with default
catalog setting of catalog_role_set = set(["viewable_owner"]) .
Finally, only look for users if there are candidate for lookup.
parent e5b4f73b
...@@ -118,19 +118,31 @@ class IndexableObjectWrapper(object): ...@@ -118,19 +118,31 @@ class IndexableObjectWrapper(object):
if role[:1] == '-': if role[:1] == '-':
skip_role(role[1:]) skip_role(role[1:])
elif role not in skip_role_set: elif role not in skip_role_set:
if role == 'Owner':
# Owner role may only be granted to users, not to groups so we
# can immediately know this security group id is a user.
self.__user_set.add(group_id)
new_role(role) new_role(role)
if new_role_list: if new_role_list:
local_role_dict[group_id] = new_role_list local_role_dict[group_id] = new_role_list
self.__local_role_cache = local_role_dict self.__local_role_cache = local_role_dict
return local_role_dict return local_role_dict
def _getSecurityGroupIdList(self): def _getSecurityGroupIdGenerator(self):
""" """
Return the list of security group identifiers this document is Return the list of security group identifiers this document is
interested in. They may be actual user identifiers or not. interested in knowing whether they are users or groups: this only matters
for security group ids which are granted at least one role mapping to a
role column.
They may be user identifiers or group identifiers.
Supposed to be accessed by CatalogTool. Supposed to be accessed by CatalogTool.
""" """
return self.__getLocalRoleDict().keys() return (
group_id
for group_id, role_list in self.__getLocalRoleDict().iteritems()
if group_id not in self.__user_set and
any(role in self.__catalog_role_set for role in role_list)
)
def _getSecurityParameterList(self): def _getSecurityParameterList(self):
result = self.__security_parameter_cache result = self.__security_parameter_cache
...@@ -197,6 +209,8 @@ class IndexableObjectWrapper(object): ...@@ -197,6 +209,8 @@ class IndexableObjectWrapper(object):
catalog_role_set = self.__catalog_role_set catalog_role_set = self.__catalog_role_set
user_set = self.__user_set user_set = self.__user_set
for group_id, role_list in self.__getLocalRoleDict().iteritems(): for group_id, role_list in self.__getLocalRoleDict().iteritems():
# Warning: only valid when group_id is candidate for indexation in a
# catalog_role column !
group_id_is_user = group_id in user_set group_id_is_user = group_id in user_set
prefix = 'user:' + group_id prefix = 'user:' + group_id
for role in role_list: for role in role_list:
...@@ -855,7 +869,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject): ...@@ -855,7 +869,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
document_object = aq_inner(object_value) document_object = aq_inner(object_value)
w = IndexableObjectWrapper(document_object, user_set, catalog_role_set) w = IndexableObjectWrapper(document_object, user_set, catalog_role_set)
w.predicate_property_dict = getPredicatePropertyDict(object_value) or {} w.predicate_property_dict = getPredicatePropertyDict(object_value) or {}
security_group_set.update(w._getSecurityGroupIdList()) security_group_set.update(w._getSecurityGroupIdGenerator())
# Find the parent definition for security # Find the parent definition for security
is_acquired = 0 is_acquired = 0
...@@ -871,20 +885,22 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject): ...@@ -871,20 +885,22 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
break break
if is_acquired: if is_acquired:
document_w = IndexableObjectWrapper(document_object, user_set, catalog_role_set) document_w = IndexableObjectWrapper(document_object, user_set, catalog_role_set)
security_group_set.update(document_w._getSecurityGroupIdList()) security_group_set.update(document_w._getSecurityGroupIdGenerator())
else: else:
document_w = w document_w = w
wrapper_list.append((document_object, w, document_w)) wrapper_list.append((document_object, w, document_w))
# Note: we mutate the set, so all related wrappers get (purposedly) security_group_set.difference_update(user_set)
# affected by this, which must happen before _getSecurityParameterList if security_group_set:
# is called (which happens when calling getSecurityUidDict below). # Note: we mutate the set, so all related wrappers get (purposedly)
user_set.update( # affected by this, which must happen before _getSecurityParameterList
x['id'] for x in portal.acl_users.searchUsers( # is called (which happens when calling getSecurityUidDict below).
id=list(security_group_set), user_set.update(
exact_match=True, x['id'] for x in portal.acl_users.searchUsers(
id=list(security_group_set),
exact_match=True,
)
) )
)
getSecurityUidDict = catalog_value.getSecurityUidDict getSecurityUidDict = catalog_value.getSecurityUidDict
getSubjectSetUid = catalog_value.getSubjectSetUid getSubjectSetUid = catalog_value.getSubjectSetUid
......
...@@ -2827,9 +2827,6 @@ VALUES ...@@ -2827,9 +2827,6 @@ VALUES
sql_catalog.sql_search_tables = current_sql_search_tables sql_catalog.sql_search_tables = current_sql_search_tables
self.commit() self.commit()
# Low priority bug, which needs a lot of time to be fixed
# Marked as expectedFailure
@expectedFailure
def test_PersonDocumentWithMonovaluedLocalRole(self): def test_PersonDocumentWithMonovaluedLocalRole(self):
"""Test when user is added, which has local roles on own Person Document """Test when user is added, which has local roles on own Person Document
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment