source: WAeUP_SRP/trunk/patches/PatchCPSWorkflowWorkflowDefinition.py @ 16153

Last change on this file since 16153 was 3673, checked in by jens, 16 years ago
  • unclutter package by moving all patch files into a dedicated subfolder and importing it.
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1import logging
2from ZODB.loglevels import TRACE
3
4from AccessControl import ClassSecurityInfo
5from AccessControl import getSecurityManager
6from Acquisition import aq_parent
7from Acquisition import aq_inner
8from Globals import InitializeClass
9
10from Products.CMFCore.utils import getToolByName
11from Products.CMFCore.WorkflowCore import ObjectMoved
12from Products.CMFCore.WorkflowCore import ObjectDeleted
13from Products.CMFCore.WorkflowCore import WorkflowException
14
15from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
16from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION
17
18#from expression import CPSStateChangeInfo as StateChangeInfo
19#from expression import createExprContext
20
21#from zope.interface import implements
22#from Products.CPSWorkflow.interfaces import ICPSWorkflowDefinition
23
24from Products.CPSCore.ProxyBase import ProxyBase
25from Products.CPSCore.EventServiceTool import getEventService
26
27#from constants import TRANSITION_FLAGS_EXPORT
28
29#
30# Backwards compatibility with CPS3 <= 3.2.x
31# Importing transition flags from here before.
32#
33
34from Products.CPSWorkflow.transitions import *
35from Products.CPSWorkflow.states import *
36
37
38logger = logging.getLogger('CPSWorkflow.workflow')
39security = ClassSecurityInfo()
40
41security.declarePrivate('updateStackDefinitionsRoleMappingFor')
42def updateStackDefinitionsRoleMappingsFor(self, ob, **kw):
43    """Update local roles for delegatees that are within workflow stacks
44    """
45    current_wf_var_id = kw.get('current_wf_var_id', '')
46
47    wftool = getToolByName(self, 'portal_workflow')
48    stackdefs = wftool.getStackDefinitionsFor(ob)
49
50    changed = 0
51
52    #
53    # First save the former local roles maping They will be
54    # overriden if defined on the state just after.  For the other
55    # ones, we need to keep the flrm's since the stackdef might be
56    # defined on another state further within the process
57    # definition or called by a stack flaged transition.
58    #
59    tdef = kw.get('tdef')
60    history = wftool.getHistoryOf(self.id, ob)
61    if history is not None:
62        try:
63            former_status = history[-2]
64        except IndexError:
65            # Virgin instance ;)
66            pass
67        else:
68            sflrm = former_status.get('sflrm', {})
69            for k, v in sflrm.items():
70                wftool.updateFormerLocalRoleMappingForStack(ob, self.id,
71                                                            k, v)
72
73    #
74    # Let's ask the stack definition for the list of local roles
75    #
76
77    for stackdef in stackdefs.keys():
78
79        # Update only the variable on wich the transition just applied
80        if not stackdef == current_wf_var_id:
81            continue
82
83        ds = wftool.getInfoFor(ob, stackdef, self.id)
84        former_mapping = wftool.getFormerLocalRoleMappingForStack(
85            ob, self.id, stackdef)
86        mapping = stackdefs[stackdef]._getLocalRolesMapping(ds)
87
88        #
89        # First remove associated local roles to the ones who are not
90        # supposed to have any (not a single one)
91        #
92
93        for id in former_mapping.keys():
94            old_local_roles = former_mapping[id]
95
96            # Remove all previous local roles in this case
97            if id not in mapping.keys():
98                roles_to_remove = old_local_roles
99
100            # Remove only local roles that are only within the
101            # previous mapping
102            else:
103                roles_to_remove = []
104                for old_role in old_local_roles:
105                    if old_role not in mapping[id]:
106                        roles_to_remove.append(old_role)
107
108
109            # Check that no other stack distributes currently this role
110            # to the current member
111            roles_to_keep = ()
112            for old_local_role in roles_to_remove:
113                stacks = wftool.getStacks(ob)
114                for stack_id, stack in stacks.items():
115                    if stack_id != current_wf_var_id:
116                        # The current transition is already
117                        # executed on ob thus we can take the
118                        # former mapping for this other given
119                        if (old_local_role in
120                            wftool.getFormerLocalRoleMappingForStack(
121                            ob, self.id, stack_id).get(id, ())):
122                            roles_to_keep += (old_local_role,)
123
124            # Do the actual job to remove absolete roles
125            for old_local_role in roles_to_remove:
126
127                # Don't remove those already managed by another stack
128                if old_local_role in roles_to_keep:
129                    continue
130
131                if not id.startswith('group:'):
132                    current_roles = list(
133                        ob.get_local_roles_for_userid(userid=id))
134                    new_roles = [role for role in current_roles
135                                 if role != old_local_role]
136                    ob.manage_delLocalRoles(userids=[id])
137                    if new_roles:
138                        ob.manage_setLocalRoles(id, new_roles)
139                else:
140                    id = id[len('group:'):]
141                    current_roles = list(
142                        ob.get_local_roles_for_groupid(groupid=id))
143                    new_roles = [role for role in current_roles
144                                 if role != old_local_role]
145                    ob.manage_delLocalGroupRoles(groupids=[id])
146                    if new_roles:
147                        ob.manage_setLocalGroupRoles(id, new_roles)
148
149            # Update ?
150            if roles_to_remove:
151                changed = 1
152
153        #
154        # Add local roles to member / groups within the mapping if
155        # they don't have the roles already in their merged local roles
156        #
157
158        for id in mapping.keys():
159            changed = 1
160            local_roles = mapping[id]
161            if not id.startswith('group:'):
162                current_roles = ob.get_local_roles_for_userid(userid=id)
163                new_roles = list(current_roles)
164                for role in local_roles:
165                    if role not in new_roles:
166                        new_roles.append(role)
167                ob.manage_setLocalRoles(id, new_roles)
168            else:
169                id = id[len('group:'):]
170                current_roles = ob.get_local_roles_for_groupid(groupid=id)
171                new_roles = list(current_roles)
172                for role in local_roles:
173                    if role not in new_roles:
174                        new_roles.append(role)
175                ob.manage_setLocalGroupRoles(id, new_roles)
176
177        # Update the former local role mapping
178        wftool.updateFormerLocalRoleMappingForStack(ob, self.id, stackdef,
179                                                    mapping)
180    return changed
181
182from Products.CPSWorkflow.workflow import WorkflowDefinition
183WorkflowDefinition.updateStackDefinitionsRoleMappingsFor = updateStackDefinitionsRoleMappingsFor
Note: See TracBrowser for help on using the repository browser.