Commit c7783906 authored by Vincent Pelletier's avatar Vincent Pelletier Committed by Your Name

Base._getAcquireLocalRoles: Optimise.

This is called when checking access permission on objects, which happens
very often. CachingMethod has a hit cost which is too high for this use.
Instead, generate this method as part of the portal type class, removing
all call-time logic.
parent b2670748
......@@ -61,6 +61,7 @@
<string>_setTypeInterface.*</string>
<string>_setTypePropertySheet.*</string>
<string>_setTypeBaseCategory.*</string>
<string>_setTypeAcquireLocalRole</string>
</list>
</value>
</item>
......
......@@ -1609,8 +1609,8 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
# Check that Owner is not catalogued when he can't view the
# object and when the portal type does not acquire the local roles.
sub_portal_type.acquire_local_roles = False
self.portal.portal_caches.clearAllCache()
sub_portal_type.setTypeAcquireLocalRole(False)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
logout()
self.loginByUserName('super_owner')
obj = folder.newContent(portal_type='Organisation')
......@@ -1625,8 +1625,8 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
# Check that Owner is catalogued when he can view the
# object and when the portal type does not acquire the local roles.
sub_portal_type.acquire_local_roles = False
self.portal.portal_caches.clearAllCache()
sub_portal_type.setTypeAcquireLocalRole(False)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
logout()
self.loginByUserName('super_owner')
obj = folder.newContent(portal_type='Organisation')
......@@ -1642,8 +1642,8 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
# Check that Owner is catalogued when he can view the
# object because permissions are acquired and when the portal type does not
# acquire the local roles.
sub_portal_type.acquire_local_roles = False
self.portal.portal_caches.clearAllCache()
sub_portal_type.setTypeAcquireLocalRole(False)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
logout()
self.loginByUserName('super_owner')
obj = folder.newContent(portal_type='Organisation')
......@@ -1658,8 +1658,8 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
# Check that Owner is not catalogued when he can't view the
# object and when the portal type acquires the local roles.
sub_portal_type.acquire_local_roles = True
self.portal.portal_caches.clearAllCache()
sub_portal_type.setTypeAcquireLocalRole(True)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
logout()
self.loginByUserName('super_owner')
obj = folder.newContent(portal_type='Organisation')
......@@ -1674,8 +1674,8 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
# Check that Owner is catalogued when he can view the
# object and when the portal type acquires the local roles.
sub_portal_type.acquire_local_roles = True
self.portal.portal_caches.clearAllCache()
sub_portal_type.setTypeAcquireLocalRole(True)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
logout()
self.loginByUserName('super_owner')
obj = folder.newContent(portal_type='Organisation')
......@@ -1691,8 +1691,8 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
# Check that Owner is catalogued when he can view the
# object because permissions are acquired and when the portal type
# acquires the local roles.
sub_portal_type.acquire_local_roles = True
self.portal.portal_caches.clearAllCache()
sub_portal_type.setTypeAcquireLocalRole(True)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
logout()
self.loginByUserName('super_owner')
obj = folder.newContent(portal_type='Organisation')
......@@ -1840,14 +1840,13 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
person_module = portal.person_module
person = 'Person'
person_portal_type = portal_types._getOb(person)
person_portal_type.acquire_local_roles = False
person_portal_type.setTypeAcquireLocalRole(False)
# Organisation stuff
organisation_module = portal.organisation_module
organisation = 'Organisation'
organisation_portal_type = portal_types._getOb(organisation)
organisation_portal_type.acquire_local_roles = True
self.portal.portal_caches.clearAllCache()
organisation_portal_type.setTypeAcquireLocalRole(True)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
def newContent(container, portal_type, acquire_view_permission, view_role_list, local_role_dict):
document = container.newContent(portal_type=portal_type)
......
......@@ -1008,7 +1008,8 @@ class TestLocalRoleManagement(RoleManagementTestCase):
"""Tests that document does not acquire loal roles from their parents if
"acquire local roles" is not checked."""
ti = self._getTypeInfo()
ti.acquire_local_roles = False
ti.setTypeAcquireLocalRole(False)
self.commit() # So dynamic class gets updated for setTypeAcquireLocalRole change
self._getModuleTypeInfo().newContent(portal_type='Role Information',
role_name='Assignor',
description='desc.',
......
......@@ -3042,16 +3042,13 @@ class Base( CopyContainer,
- False means that the role acquisition chain is cut.
The code to support this is on the user class, see
ERP5Security.ERP5UserFactory.ERP5User
"""
def cached_getAcquireLocalRoles(portal_type):
ti = self._getTypesTool().getTypeInfo(portal_type)
return ti is None or ti.getTypeAcquireLocalRole()
ERP5Type.patches.User and ERP5Type.patches.PropertiedUser .
cached_getAcquireLocalRoles = CachingMethod(cached_getAcquireLocalRoles,
id='Base__getAcquireLocalRoles',
cache_factory='erp5_content_short')
return cached_getAcquireLocalRoles(portal_type=self.getPortalType())
This specific implementation of this method should only be reached when
processing an object with a missing portal type, otherwise portal type
class should hold such accessor.
"""
return True
security.declareProtected(Permissions.AccessContentsInformation,
'get_local_permissions')
......
......@@ -534,12 +534,12 @@ class ERP5TypeInformation(XMLObject,
return getPropertySheetValueList(self.getPortalObject(),
property_sheet_name_set)
# XXX these methods, _baseGetTypeClass, getTypeMixinList, and
# getTypeInterfaceList, are required for a bootstrap issue that
# the portal type class Base Type is required for _aq_dynamic on
# Base Type. So surpress calling _aq_dynamic when obtaining information
# required for generating a portal type class by declaring these methods
# explicitly.
# XXX these methods, _baseGetTypeClass, getTypeMixinList,
# getTypeAcquireLocalRole and getTypeInterfaceList, are required for a
# bootstrap issue that the portal type class Base Type is required for
# _aq_dynamic on Base Type. So surpress calling _aq_dynamic when obtaining
# information required for generating a portal type class by declaring
# these methods explicitly.
def _baseGetTypeClass(self):
return getattr(aq_base(self), 'type_class', None)
......@@ -553,6 +553,11 @@ class ERP5TypeInformation(XMLObject,
def getTypeMixinList(self):
return getattr(aq_base(self), 'type_mixin', ())
security.declareProtected(Permissions.AccessContentsInformation,
'getTypeAcquireLocalRole')
def getTypeAcquireLocalRole(self):
return getattr(aq_base(self), 'acquire_local_roles', None)
security.declareProtected(Permissions.AccessContentsInformation,
'getTypeInterfaceList')
def getTypeInterfaceList(self):
......
......@@ -39,10 +39,13 @@ from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type.Utils import setDefaultClassProperties
from Products.ERP5Type import document_class_registry, mixin_class_registry
from Products.ERP5Type.dynamic.accessor_holder import createAllAccessorHolderList
from Products.ERP5Type.Accessor.Constant import Getter as ConstantGetter
from Products.ERP5Type.TransactionalVariable import TransactionalResource
from zLOG import LOG, ERROR, INFO, WARNING, PANIC
ACQUIRE_LOCAL_ROLE_GETTER_ID = '_getAcquireLocalRoles'
def _importClass(classpath):
try:
module_path, class_name = classpath.rsplit('.', 1)
......@@ -153,6 +156,11 @@ def generatePortalTypeClass(site, portal_type_name):
interface_list = portal_type.getTypeInterfaceList()
portal_type_category_list = portal_type.getTypeBaseCategoryList()
attribute_dict['_categories'] = portal_type_category_list[:]
attribute_dict[ACQUIRE_LOCAL_ROLE_GETTER_ID] = ConstantGetter(
id=ACQUIRE_LOCAL_ROLE_GETTER_ID,
key=None,
value=bool(portal_type.getTypeAcquireLocalRole()),
)
else:
LOG("ERP5Type.dynamic", WARNING,
"Cannot find a portal type definition for '%s', trying to guess..."
......
......@@ -146,8 +146,7 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor):
# set Person.acquire_local_roles back.
if getattr(self, 'person_acquire_local_roles', None) is not None:
self.getTypesTool().getTypeInfo('Person').acquire_local_roles = self.person_acquire_local_roles
self.portal.portal_caches.clearAllCache()
self.getTypesTool().getTypeInfo('Person').setTypeAcquireLocalRole(self.person_acquire_local_roles)
# restore workflows for other tests
self.getWorkflowTool().setChainForPortalTypes(
......@@ -1653,9 +1652,8 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor):
# turn on Person.acquire_local_roles
person = self.getTypesTool().getTypeInfo('Person')
self.person_acquire_local_roles = person.acquire_local_roles
person.acquire_local_roles = True
portal.portal_caches.clearAllCache()
self.person_acquire_local_roles = person.getTypeAcquireLocalRole()
person.setTypeAcquireLocalRole(True)
# Make a plain user.
uf = portal.acl_users
......
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