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