Commit 80453523 authored by Julien Muchembled's avatar Julien Muchembled

Base: do not check security for unrestricted category value getters

parent 16bedb73
...@@ -1678,11 +1678,14 @@ class CategoryTool( UniqueObject, Folder, Base ): ...@@ -1678,11 +1678,14 @@ class CategoryTool( UniqueObject, Folder, Base ):
display_id = 'title') display_id = 'title')
security.declarePublic('resolveCategory') security.declarePublic('resolveCategory')
def resolveCategory(self, relative_url, default=_marker): def resolveCategory(self, relative_url):
""" """
Finds an object from a relative_url Finds an object from a relative_url
Method is public since we use restrictedTraverse Method is public since we use restrictedTraverse
""" """
return self._resolveCategory(relative_url, True)
def _resolveCategory(self, relative_url, restricted=False):
if not isinstance(relative_url, str): if not isinstance(relative_url, str):
# Handle parent base category is a special way # Handle parent base category is a special way
return relative_url return relative_url
...@@ -1759,15 +1762,16 @@ class CategoryTool( UniqueObject, Folder, Base ): ...@@ -1759,15 +1762,16 @@ class CategoryTool( UniqueObject, Folder, Base ):
stack.reverse() stack.reverse()
__traceback_info__ = relative_url __traceback_info__ = relative_url
validate = getSecurityManager().validate if restricted:
def restrictedGetOb(container): validate = getSecurityManager().validate
obj = container._getOb(key, None) def getOb(container):
if obj is None or validate(container, container, key, obj): obj = container._getOb(key, None)
return obj if obj is None or validate(container, container, key, obj):
# if user can't access object try to return default passed return obj
if default is _marker:
raise Unauthorized('unauthorized access to element %s' % key) raise Unauthorized('unauthorized access to element %s' % key)
return default else:
def getOb(container):
return container._getOb(key, None)
# XXX Currently, resolveCategory accepts that a category might # XXX Currently, resolveCategory accepts that a category might
# not start with a Base Category, but with a Module. This is # not start with a Base Category, but with a Module. This is
...@@ -1778,32 +1782,32 @@ class CategoryTool( UniqueObject, Folder, Base ): ...@@ -1778,32 +1782,32 @@ class CategoryTool( UniqueObject, Folder, Base ):
if stack: if stack:
portal = aq_inner(self.getPortalObject()) portal = aq_inner(self.getPortalObject())
key = stack.pop() key = stack.pop()
obj = restrictedGetOb(self) obj = getOb(self)
if obj is None: if obj is None:
obj = restrictedGetOb(portal) obj = getOb(portal)
if obj is not None: if obj is not None:
obj = obj.__of__(self) obj = obj.__of__(self)
else: else:
while stack: while stack:
container = obj container = obj
key = stack.pop() key = stack.pop()
obj = restrictedGetOb(container) obj = getOb(container)
if obj is not None: if obj is not None:
break break
obj = restrictedGetOb(self) obj = getOb(self)
if obj is None: if obj is None:
obj = restrictedGetOb(portal) obj = getOb(portal)
if obj is not None: if obj is not None:
obj = obj.__of__(container) obj = obj.__of__(container)
break break
while obj is not None and stack: while obj is not None and stack:
key = stack.pop() key = stack.pop()
obj = restrictedGetOb(obj) obj = getOb(obj)
if obj is None: if obj is None:
LOG('CMFCategory', WARNING, LOG('CMFCategory', WARNING,
'Could not access object %s' % relative_url) 'Could not get object %s' % relative_url)
if cache is not None: if cache is not None:
cache[cache_key] = obj cache[cache_key] = obj
......
...@@ -122,7 +122,7 @@ class DefaultGetter(BaseGetter): ...@@ -122,7 +122,7 @@ class DefaultGetter(BaseGetter):
LOG("ERP5Type Deprecated Getter Id:",0, self._id) LOG("ERP5Type Deprecated Getter Id:",0, self._id)
if args: if args:
kw['default'] = args[0] kw['default'] = args[0]
return instance._getDefaultAcquiredValue(self._key, **kw) return instance.getDefaultAcquiredValue(self._key, **kw)
psyco.bind(__call__) psyco.bind(__call__)
...@@ -153,7 +153,7 @@ class ListGetter(BaseGetter): ...@@ -153,7 +153,7 @@ class ListGetter(BaseGetter):
LOG("ERP5Type Deprecated Getter Id:",0, self._id) LOG("ERP5Type Deprecated Getter Id:",0, self._id)
if args: if args:
kw['default'] = args[0] kw['default'] = args[0]
return instance._getAcquiredValueList(self._key, **kw) return instance.getAcquiredValueList(self._key, **kw)
psyco.bind(__call__) psyco.bind(__call__)
......
...@@ -1002,8 +1002,8 @@ class Base( CopyContainer, ...@@ -1002,8 +1002,8 @@ class Base( CopyContainer,
#LOG("Get Acquired Property self",0,str(self)) #LOG("Get Acquired Property self",0,str(self))
#LOG("Get Acquired Property portal_type",0,str(portal_type)) #LOG("Get Acquired Property portal_type",0,str(portal_type))
#LOG("Get Acquired Property base_category",0,str(base_category)) #LOG("Get Acquired Property base_category",0,str(base_category))
#super_list = self._getValueList(base_category, portal_type=portal_type) # We only do a single jump #super_list = self.getValueList(base_category, portal_type=portal_type) # We only do a single jump
super_list = self._getAcquiredValueList(base_category, portal_type=portal_type, super_list = self.getAcquiredValueList(base_category, portal_type=portal_type,
checked_permission=checked_permission) # Full acquisition checked_permission=checked_permission) # Full acquisition
super_list = [o for o in super_list if o.getPhysicalPath() != self.getPhysicalPath()] # Make sure we do not create stupid loop here super_list = [o for o in super_list if o.getPhysicalPath() != self.getPhysicalPath()] # Make sure we do not create stupid loop here
#LOG("Get Acquired Property super_list",0,str(super_list)) #LOG("Get Acquired Property super_list",0,str(super_list))
...@@ -1131,11 +1131,11 @@ class Base( CopyContainer, ...@@ -1131,11 +1131,11 @@ class Base( CopyContainer,
super_list.append(acquisition_object) super_list.append(acquisition_object)
except (KeyError, AttributeError): except (KeyError, AttributeError):
pass pass
super_list.extend(self._getAcquiredValueList( super_list += self.getAcquiredValueList(
base_category, base_category,
portal_type=portal_type, portal_type=portal_type,
checked_permission=checked_permission)) checked_permission=checked_permission,
# Full acquisition ) # Full acquisition
super_list = [o for o in super_list if o.getPhysicalPath() != self.getPhysicalPath()] # Make sure we do not create stupid loop here super_list = [o for o in super_list if o.getPhysicalPath() != self.getPhysicalPath()] # Make sure we do not create stupid loop here
if len(super_list) > 0: if len(super_list) > 0:
value = [] value = []
...@@ -1891,60 +1891,111 @@ class Base( CopyContainer, ...@@ -1891,60 +1891,111 @@ class Base( CopyContainer,
checked_permission=None) checked_permission=None)
self.reindexObject() self.reindexObject()
# Unrestricted category value getters
def _getDefaultValue(self, id, spec=(), filter=None, default=_MARKER, **kw): def _getDefaultValue(self, id, spec=(), filter=None, default=_MARKER, **kw):
path = self._getDefaultCategoryMembership(id, base=1, spec=spec, path = self._getDefaultCategoryMembership(id, base=1, spec=spec,
filter=filter, **kw) filter=filter, **kw)
if path: if path:
return self._getCategoryTool().resolveCategory(path) return self._getCategoryTool()._resolveCategory(path)
if default is not _MARKER: if default is not _MARKER:
return default return default
security.declareProtected(Permissions.AccessContentsInformation,
'getDefaultValue')
getDefaultValue = _getDefaultValue
def _getValueList(self, id, spec=(), filter=None, default=_MARKER, **kw): def _getValueList(self, id, spec=(), filter=None, default=_MARKER, **kw):
ref_list = [] ref_list = self._getCategoryMembershipList(id, base=1, spec=spec,
for path in self._getCategoryMembershipList(id, base=1, spec=spec, filter=filter, **kw)
filter=filter, **kw): if ref_list:
category = self._getCategoryTool().resolveCategory(path) resolveCategory = self._getCategoryTool()._resolveCategory
if category is not None: value_list = []
ref_list.append(category) for path in ref_list:
return ref_list if ref_list or default is _MARKER else default value = resolveCategory(path)
if value is not None:
security.declareProtected(Permissions.AccessContentsInformation, value_list.append(value)
'getValueList') return value_list if value_list or default is _MARKER else default
getValueList = _getValueList return ref_list if default is _MARKER else default
def _getDefaultAcquiredValue(self, id, spec=(), filter=None, portal_type=(), def _getDefaultAcquiredValue(self, id, spec=(), filter=None, portal_type=(),
evaluate=1, checked_permission=None, evaluate=1, checked_permission=None,
default=None, **kw): default=None, **kw):
path = self._getDefaultAcquiredCategoryMembership(id, spec=spec, filter=filter, path = self._getDefaultAcquiredCategoryMembership(
portal_type=portal_type, base=1, id, spec=spec, filter=filter, portal_type=portal_type,
checked_permission=checked_permission, base=1, checked_permission=checked_permission, **kw)
**kw) if path:
return self._getCategoryTool()._resolveCategory(path)
if default is not _MARKER:
return default
def _getAcquiredValueList(self, id, spec=(), filter=None, default=_MARKER,
**kw):
ref_list = self._getAcquiredCategoryMembershipList(id, base=1, spec=spec,
filter=filter, **kw)
if ref_list:
resolveCategory = self._getCategoryTool()._resolveCategory
value_list = []
for path in ref_list:
value = resolveCategory(path)
if value is not None:
value_list.append(value)
return value_list if value_list or default is _MARKER else default
return ref_list if default is _MARKER else default
# Restricted category value getters
security.declareProtected(Permissions.AccessContentsInformation,
'getDefaultValue')
def getDefaultValue(self, id, spec=(), filter=None, default=_MARKER, **kw):
path = self._getDefaultCategoryMembership(id, base=1, spec=spec,
filter=filter, **kw)
if path: if path:
return self._getCategoryTool().resolveCategory(path) return self._getCategoryTool().resolveCategory(path)
if default is not _MARKER: if default is not _MARKER:
return default return default
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getDefaultAcquiredValue') 'getValueList')
getDefaultAcquiredValue = _getDefaultAcquiredValue def getValueList(self, id, spec=(), filter=None, default=_MARKER, **kw):
ref_list = self._getCategoryMembershipList(id, base=1, spec=spec,
filter=filter, **kw)
if ref_list:
resolveCategory = self._getCategoryTool().resolveCategory
value_list = []
for path in ref_list:
value = resolveCategory(path)
if value is not None:
value_list.append(value)
return value_list if value_list or default is _MARKER else default
return ref_list if default is _MARKER else default
def _getAcquiredValueList(self, id, spec=(), filter=None, default=_MARKER, security.declareProtected(Permissions.AccessContentsInformation,
**kw): 'getDefaultAcquiredValue')
ref_list = [] def getDefaultAcquiredValue(self, id, spec=(), filter=None, portal_type=(),
for path in self._getAcquiredCategoryMembershipList(id, base=1, evaluate=1, checked_permission=None,
spec=spec, filter=filter, **kw): default=None, **kw):
category = self._getCategoryTool().resolveCategory(path) path = self._getDefaultAcquiredCategoryMembership(
if category is not None: id, spec=spec, filter=filter, portal_type=portal_type,
ref_list.append(category) base=1, checked_permission=checked_permission, **kw)
return ref_list if ref_list or default is _MARKER else default if path:
return self._getCategoryTool().resolveCategory(path)
if default is not _MARKER:
return default
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getAcquiredValueList') 'getAcquiredValueList')
getAcquiredValueList = _getAcquiredValueList def getAcquiredValueList(self, id, spec=(), filter=None, default=_MARKER,
**kw):
ref_list = self._getAcquiredCategoryMembershipList(id, base=1, spec=spec,
filter=filter, **kw)
if ref_list:
resolveCategory = self._getCategoryTool().resolveCategory
value_list = []
for path in ref_list:
value = resolveCategory(path)
if value is not None:
value_list.append(value)
return value_list if value_list or default is _MARKER else default
return ref_list if default is _MARKER else default
###
def _getDefaultRelatedValue(self, id, spec=(), filter=None, portal_type=(), def _getDefaultRelatedValue(self, id, spec=(), filter=None, portal_type=(),
strict_membership=0, strict="deprecated", strict_membership=0, strict="deprecated",
......
...@@ -33,8 +33,6 @@ from warnings import warn ...@@ -33,8 +33,6 @@ from warnings import warn
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Acquisition import aq_base, aq_inner from Acquisition import aq_base, aq_inner
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Document import newTempBase from Products.ERP5Type.Document import newTempBase
...@@ -44,7 +42,6 @@ from Products.ERP5Type.Cache import readOnlyTransactionCache ...@@ -44,7 +42,6 @@ from Products.ERP5Type.Cache import readOnlyTransactionCache
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ZSQLCatalog.SQLCatalog import SQLQuery from Products.ZSQLCatalog.SQLCatalog import SQLQuery
from Products.ERP5Type.Globals import PersistentMapping from Products.ERP5Type.Globals import PersistentMapping
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.ERP5Type.UnrestrictedMethod import unrestricted_apply from Products.ERP5Type.UnrestrictedMethod import unrestricted_apply
from Products.CMFCore.Expression import Expression from Products.CMFCore.Expression import Expression
...@@ -199,13 +196,6 @@ class Predicate(XMLObject): ...@@ -199,13 +196,6 @@ class Predicate(XMLObject):
result = expression(createExpressionContext(context)) result = expression(createExpressionContext(context))
return result return result
@UnrestrictedMethod
def _unrestrictedResolveCategory(self, *args):
# Categories used on predicate can be not available to user query, which
# shall be applied with predicate.
portal_categories = getToolByName(self, 'portal_categories')
return portal_categories.resolveCategory(*args)
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
'buildSQLQuery' ) 'buildSQLQuery' )
def buildSQLQuery(self, strict_membership=0, table='category', def buildSQLQuery(self, strict_membership=0, table='category',
...@@ -248,7 +238,8 @@ class Predicate(XMLObject): ...@@ -248,7 +238,8 @@ class Predicate(XMLObject):
f = (i,) if i in f else () f = (i,) if i in f else ()
catalog_kw[p] = list(f) catalog_kw[p] = list(f)
portal_catalog = getToolByName(self, 'portal_catalog') portal = self.getPortalObject()
resolveCategory = portal.portal_categories._resolveCategory
from_table_dict = {} from_table_dict = {}
...@@ -260,7 +251,7 @@ class Predicate(XMLObject): ...@@ -260,7 +251,7 @@ class Predicate(XMLObject):
for category in self.getMembershipCriterionCategoryList(): for category in self.getMembershipCriterionCategoryList():
base_category = category.split('/')[0] # Retrieve base category base_category = category.split('/')[0] # Retrieve base category
if membership_dict.has_key(base_category): if membership_dict.has_key(base_category):
category_value = self._unrestrictedResolveCategory(category, None) category_value = resolveCategory(category)
if category_value is not None: if category_value is not None:
table_alias = "single_%s_%s" % (table, base_category) table_alias = "single_%s_%s" % (table, base_category)
from_table_dict[table_alias] = 'category' from_table_dict[table_alias] = 'category'
...@@ -282,7 +273,7 @@ class Predicate(XMLObject): ...@@ -282,7 +273,7 @@ class Predicate(XMLObject):
for category in self.getMembershipCriterionCategoryList(): for category in self.getMembershipCriterionCategoryList():
base_category = category.split('/')[0] # Retrieve base category base_category = category.split('/')[0] # Retrieve base category
if multimembership_dict.has_key(base_category): if multimembership_dict.has_key(base_category):
category_value = self._unrestrictedResolveCategory(category) category_value = resolveCategory(category)
if category_value is not None: if category_value is not None:
join_count += 1 join_count += 1
table_alias = "multi_%s_%s" % (table, join_count) table_alias = "multi_%s_%s" % (table, join_count)
...@@ -317,7 +308,7 @@ class Predicate(XMLObject): ...@@ -317,7 +308,7 @@ class Predicate(XMLObject):
catalog_kw['where_expression'] = SQLQuery(sql_text) catalog_kw['where_expression'] = SQLQuery(sql_text)
# force implicit join # force implicit join
catalog_kw['implicit_join'] = True catalog_kw['implicit_join'] = True
sql_query = portal_catalog.buildSQLQuery(**catalog_kw) sql_query = portal.portal_catalog.buildSQLQuery(**catalog_kw)
# XXX from_table_list is None most of the time after the explicit_join work # XXX from_table_list is None most of the time after the explicit_join work
for alias, table in sql_query['from_table_list']: for alias, table in sql_query['from_table_list']:
if from_table_dict.has_key(alias): if from_table_dict.has_key(alias):
...@@ -359,15 +350,15 @@ class Predicate(XMLObject): ...@@ -359,15 +350,15 @@ class Predicate(XMLObject):
def searchResults(self, **kw): def searchResults(self, **kw):
""" """
""" """
portal_catalog = getToolByName(self, 'portal_catalog') return self.getPortalObject().portal_catalog.searchResults(
return portal_catalog.searchResults(build_sql_query_method=self.buildSQLQuery,**kw) build_sql_query_method=self.buildSQLQuery, **kw)
security.declareProtected(Permissions.AccessContentsInformation, 'countResults') security.declareProtected(Permissions.AccessContentsInformation, 'countResults')
def countResults(self, REQUEST=None, used=None, **kw): def countResults(self, REQUEST=None, used=None, **kw):
""" """
""" """
portal_catalog = getToolByName(self, 'portal_catalog') return self.getPortalObject().portal_catalog.countResults(
return portal_catalog.countResults(build_sql_query_method=self.buildSQLQuery,**kw) build_sql_query_method=self.buildSQLQuery, **kw)
security.declareProtected( Permissions.AccessContentsInformation, 'getCriterionList' ) security.declareProtected( Permissions.AccessContentsInformation, 'getCriterionList' )
def getCriterionList(self, **kw): def getCriterionList(self, **kw):
......
...@@ -2347,7 +2347,7 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor): ...@@ -2347,7 +2347,7 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor):
self._ignore_log_errors() self._ignore_log_errors()
logged_errors = [ logrecord for logrecord in self.logged logged_errors = [ logrecord for logrecord in self.logged
if logrecord.name == 'CMFCategory' ] if logrecord.name == 'CMFCategory' ]
self.assertEqual('Could not access object region/gamma', self.assertEqual('Could not get object region/gamma',
logged_errors[0].getMessage()) logged_errors[0].getMessage())
def test_list_accessors(self): def test_list_accessors(self):
......
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