Make before-commit interactions immune to security changes

parent a3230950
...@@ -22,6 +22,7 @@ from Products.ERP5Type import Globals ...@@ -22,6 +22,7 @@ from Products.ERP5Type import Globals
import App import App
from types import StringTypes from types import StringTypes
from AccessControl import getSecurityManager, ClassSecurityInfo from AccessControl import getSecurityManager, ClassSecurityInfo
from AccessControl.SecurityManagement import setSecurityManager
from Acquisition import aq_base from Acquisition import aq_base
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
...@@ -290,10 +291,11 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject): ...@@ -290,10 +291,11 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject):
# Pass lots of info to the script in a single parameter. # Pass lots of info to the script in a single parameter.
script(sci) # May throw an exception 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: for script_name in tdef.before_commit_script_name:
transaction.get().addBeforeCommitHook(self._before_commit, transaction.get().addBeforeCommitHook(self._before_commit,
(sci, script_name)) (sci, script_name, sm))
# Execute "activity" scripts # Execute "activity" scripts
for script_name in tdef.activate_script_name: for script_name in tdef.activate_script_name:
...@@ -301,14 +303,22 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject): ...@@ -301,14 +303,22 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject):
.activeScript(script_name, ob.getRelativeUrl(), .activeScript(script_name, ob.getRelativeUrl(),
status, tdef.id) 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 # check the object still exists before calling the script
ob = sci.object ob = sci.object
while ob.isTempObject(): while ob.isTempObject():
ob = ob.getParentValue() ob = ob.getParentValue()
if aq_base(self.unrestrictedTraverse(ob.getPhysicalPath(), None)) is \ if aq_base(self.unrestrictedTraverse(ob.getPhysicalPath(), None)) is \
aq_base(ob): aq_base(ob):
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) self.scripts[script_name](sci)
finally:
setSecurityManager(current_security_manager)
security.declarePrivate('activeScript') security.declarePrivate('activeScript')
def activeScript(self, script_name, ob_url, status, tdef_id): def activeScript(self, script_name, ob_url, status, tdef_id):
......
...@@ -531,7 +531,10 @@ context.setDescription('%s,%s,%s' % (d, args, result)) ...@@ -531,7 +531,10 @@ context.setDescription('%s,%s,%s' % (d, args, result))
self.assertEqual(organisation.getDescription(), 'bad') self.assertEqual(organisation.getDescription(), 'bad')
organisation.getProperty('description', d='toto') organisation.getProperty('description', d='toto')
self.assertEqual(organisation.getDescription(), 'bad') self.assertEqual(organisation.getDescription(), 'bad')
# before-commit interactions should be immune to security changes
self.logout()
transaction.commit() transaction.commit()
self.login()
self.assertEqual(organisation.getDescription(), "toto,('description',),bad") self.assertEqual(organisation.getDescription(), "toto,('description',),bad")
def test_17_activity_interaction(self, quiet=0, run=run_all_test): def test_17_activity_interaction(self, quiet=0, run=run_all_test):
......
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