Commit e300e3f6 authored by Jérome Perrin's avatar Jérome Perrin

testSecurity: don't skip portal_components in test_method_protection

We have been using `filter(lambda x:'/erp5/' in x[0], error_list)` as a
way to see only missing declarations from ERP5 code, but only ERP5
filesystem code contains /erp5/ in the filenames, in-ZODB components
filename is set to something like <portal_components/document.erp5.FTPConnector>

Change to also check methods for which filename contains <portal_components
and also to print the ignored methods
parent aebfb199
...@@ -72,21 +72,19 @@ class TestSecurityMixin(ERP5TypeTestCase): ...@@ -72,21 +72,19 @@ class TestSecurityMixin(ERP5TypeTestCase):
i.e. those who have a docstring but have no security declaration. i.e. those who have a docstring but have no security declaration.
""" """
self._prepareDocumentList() self._prepareDocumentList()
white_method_id_list = ['om_icons',] allowed_method_id_list = ['om_icons',]
app = self.portal.aq_parent app = self.portal.aq_parent
meta_type_dict = {} meta_type_set = set([None])
error_dict = {} error_set = set()
for idx, obj in app.ZopeFind(app, search_sub=1): for _, obj in app.ZopeFind(app, search_sub=1):
meta_type = getattr(obj, 'meta_type', None) meta_type = getattr(obj, 'meta_type', None)
if meta_type is None: if meta_type in meta_type_set:
continue continue
if meta_type in meta_type_dict: meta_type_set.add(meta_type)
continue
meta_type_dict[meta_type] = True
if '__roles__' in obj.__class__.__dict__: if '__roles__' in obj.__class__.__dict__:
continue continue
for method_id in dir(obj): for method_id in dir(obj):
if method_id.startswith('_') or method_id in white_method_id_list or not callable(getattr(obj, method_id, None)): if method_id.startswith('_') or method_id in allowed_method_id_list or not callable(getattr(obj, method_id, None)):
continue continue
method = getattr(obj, method_id) method = getattr(obj, method_id)
if isinstance(method, MethodType) and \ if isinstance(method, MethodType) and \
...@@ -96,16 +94,19 @@ class TestSecurityMixin(ERP5TypeTestCase): ...@@ -96,16 +94,19 @@ class TestSecurityMixin(ERP5TypeTestCase):
method.__module__: method.__module__:
if method.__module__ == 'Products.ERP5Type.Accessor.WorkflowState' and method.func_code.co_name == 'serialize': if method.__module__ == 'Products.ERP5Type.Accessor.WorkflowState' and method.func_code.co_name == 'serialize':
continue continue
func_code = method.func_code func_code = method.__code__
error_dict[(func_code.co_filename, func_code.co_firstlineno, method_id)] = True error_set.add((func_code.co_filename, func_code.co_firstlineno, method_id))
error_list = error_dict.keys()
if os.environ.get('erp5_debug_mode', None): error_list = []
pass for filename, lineno, method_id in sorted(error_set):
else: # ignore security problems with non ERP5 documents, unless running in debug mode.
error_list = filter(lambda x:'/erp5/' in x[0], error_list) if os.environ.get('erp5_debug_mode') or '/erp5/' in filename or '<portal_components' in filename:
error_list.append('%s:%s %s' % (filename, lineno, method_id))
else:
print('Ignoring missing security definition for %s in %s:%s ' % (method_id, filename, lineno))
if error_list: if error_list:
message = '\nThe following %s methods have a docstring but have no security assertions.\n\t%s' \ message = '\nThe following %s methods have a docstring but have no security assertions.\n\t%s' \
% (len(error_list), '\n\t'.join(['%s:%s %s' % x for x in sorted(error_list)])) % (len(error_list), '\n\t'.join(error_list))
self.fail(message) self.fail(message)
def test_workflow_transition_protection(self): def test_workflow_transition_protection(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