From c964d757159cfd8973ad1cf0b35b0d49501b0cde Mon Sep 17 00:00:00 2001
From: Sebastien Robin <seb@nexedi.com>
Date: Thu, 22 Sep 2005 12:21:21 +0000
Subject: [PATCH] allow to do an AND operation if 2 workflows define security
 settings

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@3826 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Type/ZopePatch.py | 46 +++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py
index d23154ff9ba..ba6ce15f551 100755
--- a/product/ERP5Type/ZopePatch.py
+++ b/product/ERP5Type/ZopePatch.py
@@ -640,6 +640,52 @@ def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None):
 
 
 DCWorkflowDefinition._executeTransition = DCWorkflowDefinition_executeTransition
+from Products.DCWorkflow.utils import modifyRolesForPermission
+
+# Patch updateRoleMappingsFor so that if 2 workflows define security, then we
+# should do an AND operation between each permission
+def updateRoleMappingsFor(self, ob):
+    '''
+    Changes the object permissions according to the current
+    state.
+    '''
+    changed = 0
+    sdef = self._getWorkflowStateOf(ob)
+
+    tool = aq_parent(aq_inner(self))
+    other_workflow_list = \
+       [x for x in tool.getWorkflowsFor(ob) if x.id != self.id and isinstance(x,DCWorkflowDefinition)]
+    other_data_list = []
+    for other_workflow in other_workflow_list:
+      other_sdef = other_workflow._getWorkflowStateOf(ob)
+      if other_sdef is not None and other_sdef.permission_roles is not None:
+        other_data_list.append((other_workflow,other_sdef))
+
+    # Be carefull, permissions_roles should not change
+    # from list to tuple or vice-versa
+    if sdef is not None and self.permissions:
+        for p in self.permissions:
+            roles = []
+            role_type = 'list'
+            if sdef.permission_roles is not None:
+                roles = sdef.permission_roles.get(p, roles)
+                if type(roles) is type(()):
+                  role_type='tuple'
+                roles = list(roles)
+            # We will check that each role is activated
+            # in each DCWorkflow
+            for other_workflow,other_sdef in other_data_list:
+              if p in other_workflow.permissions:
+                for role in roles:
+                  if role not in other_sdef.permission_roles.get(p,[]):
+                    roles.remove(role)
+            if role_type=='tuple':
+              roles = tuple(roles)
+            if modifyRolesForPermission(ob, p, roles):
+                changed = 1
+    return changed
+
+DCWorkflowDefinition.updateRoleMappingsFor = updateRoleMappingsFor
 
 # This patch allows to use workflowmethod as an after_script
 # However, the right way of doing would be to have a combined state of TRIGGER_USER_ACTION and TRIGGER_WORKFLOW_METHOD
-- 
2.30.9