From 39f73b760771eef9fd11302db6111efc20a8c957 Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida <leonardo@nexedi.com> Date: Fri, 5 Aug 2011 16:23:40 +0200 Subject: [PATCH] Make before-commit interactions immune to security changes --- product/ERP5/InteractionWorkflow.py | 18 ++++++++++++++---- product/ERP5/tests/testInteractionWorkflow.py | 3 +++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/product/ERP5/InteractionWorkflow.py b/product/ERP5/InteractionWorkflow.py index 4df51bf540..2463d71189 100644 --- a/product/ERP5/InteractionWorkflow.py +++ b/product/ERP5/InteractionWorkflow.py @@ -22,6 +22,7 @@ from Products.ERP5Type import Globals import App from types import StringTypes from AccessControl import getSecurityManager, ClassSecurityInfo +from AccessControl.SecurityManagement import setSecurityManager from Acquisition import aq_base from Products.CMFCore.utils import getToolByName from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition @@ -290,10 +291,11 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject): # Pass lots of info to the script in a single parameter. script(sci) # May throw an exception - # Execute Before Commit + # Queue the "Before Commit" scripts + sm = getSecurityManager() for script_name in tdef.before_commit_script_name: transaction.get().addBeforeCommitHook(self._before_commit, - (sci, script_name)) + (sci, script_name, sm)) # Execute "activity" scripts for script_name in tdef.activate_script_name: @@ -301,14 +303,22 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject): .activeScript(script_name, ob.getRelativeUrl(), status, tdef.id) - def _before_commit(self, sci, script_name): + def _before_commit(self, sci, script_name, security_manager): # check the object still exists before calling the script ob = sci.object while ob.isTempObject(): ob = ob.getParentValue() if aq_base(self.unrestrictedTraverse(ob.getPhysicalPath(), None)) is \ aq_base(ob): - self.scripts[script_name](sci) + current_security_manager = getSecurityManager() + try: + # Who knows what happened to the authentication context + # between here and when the interaction was executed... So we + # need to switch to the security manager as it was back then + setSecurityManager(security_manager) + self.scripts[script_name](sci) + finally: + setSecurityManager(current_security_manager) security.declarePrivate('activeScript') def activeScript(self, script_name, ob_url, status, tdef_id): diff --git a/product/ERP5/tests/testInteractionWorkflow.py b/product/ERP5/tests/testInteractionWorkflow.py index d67cc06101..4dab707318 100644 --- a/product/ERP5/tests/testInteractionWorkflow.py +++ b/product/ERP5/tests/testInteractionWorkflow.py @@ -531,7 +531,10 @@ context.setDescription('%s,%s,%s' % (d, args, result)) self.assertEqual(organisation.getDescription(), 'bad') organisation.getProperty('description', d='toto') self.assertEqual(organisation.getDescription(), 'bad') + # before-commit interactions should be immune to security changes + self.logout() transaction.commit() + self.login() self.assertEqual(organisation.getDescription(), "toto,('description',),bad") def test_17_activity_interaction(self, quiet=0, run=run_all_test): -- 2.30.9