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