11 from yams.buildobjs import (EntityType, RelationType, SubjectRelation, |
11 from yams.buildobjs import (EntityType, RelationType, SubjectRelation, |
12 ObjectRelation, RichString, String) |
12 ObjectRelation, RichString, String) |
13 from cubicweb.schema import RQLConstraint |
13 from cubicweb.schema import RQLConstraint |
14 from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS, HOOKS_RTYPE_PERMS |
14 from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS, HOOKS_RTYPE_PERMS |
15 |
15 |
|
16 class Workflow(EntityType): |
|
17 permissions = META_ETYPE_PERMS |
|
18 |
|
19 name = String(required=True, indexed=True, internationalizable=True, |
|
20 maxsize=256) |
|
21 description = RichString(fulltextindexed=True, default_format='text/rest', |
|
22 description=_('semantic description of this workflow')) |
|
23 |
|
24 workflow_of = SubjectRelation('CWEType', cardinality='+*', |
|
25 description=_('entity types which may use this workflow'), |
|
26 constraints=[RQLConstraint('O final FALSE')]) |
|
27 |
|
28 default_workflow_of = SubjectRelation('CWEType', cardinality='*?', |
|
29 description=_('which entity types use this workflow by default'), |
|
30 constraints=[RQLConstraint('O final FALSE')]) |
|
31 |
|
32 initial_state = SubjectRelation('State', cardinality='?*', |
|
33 # S initial_state O, O state_of S |
|
34 constraints=[RQLConstraint('O state_of S')], |
|
35 description=_('initial state for this workflow')) |
|
36 |
|
37 # XXX ensure state/transition name is unique in a given workflow |
|
38 |
16 class State(EntityType): |
39 class State(EntityType): |
17 """used to associate simple states to an entity type and/or to define |
40 """used to associate simple states to an entity type and/or to define |
18 workflows |
41 workflows |
19 """ |
42 """ |
20 permissions = META_ETYPE_PERMS |
43 permissions = META_ETYPE_PERMS |
22 name = String(required=True, indexed=True, internationalizable=True, |
45 name = String(required=True, indexed=True, internationalizable=True, |
23 maxsize=256) |
46 maxsize=256) |
24 description = RichString(fulltextindexed=True, default_format='text/rest', |
47 description = RichString(fulltextindexed=True, default_format='text/rest', |
25 description=_('semantic description of this state')) |
48 description=_('semantic description of this state')) |
26 |
49 |
27 state_of = SubjectRelation('CWEType', cardinality='+*', |
50 state_of = SubjectRelation('Workflow', cardinality='+*', |
28 description=_('entity types which may use this state'), |
51 description=_('workflow to which this state belongs')) |
29 constraints=[RQLConstraint('O final FALSE')]) |
52 # XXX should be on BaseTransition w/ AND/OR selectors when we will |
30 allowed_transition = SubjectRelation('Transition', cardinality='**', |
53 # implements #345274 |
31 constraints=[RQLConstraint('S state_of ET, O transition_of ET')], |
54 allowed_transition = SubjectRelation('BaseTransition', cardinality='**', |
|
55 constraints=[RQLConstraint('S state_of WF, O transition_of WF')], |
32 description=_('allowed transitions from this state')) |
56 description=_('allowed transitions from this state')) |
33 |
57 |
34 initial_state = ObjectRelation('CWEType', cardinality='?*', |
58 |
35 # S initial_state O, O state_of S |
59 class BaseTransition(EntityType): |
36 constraints=[RQLConstraint('O state_of S')], |
60 """abstract base class for transitions""" |
37 description=_('initial state for entities of this type')) |
|
38 |
|
39 |
|
40 class Transition(EntityType): |
|
41 """use to define a transition from one or multiple states to a destination |
|
42 states in workflow's definitions. |
|
43 """ |
|
44 permissions = META_ETYPE_PERMS |
61 permissions = META_ETYPE_PERMS |
45 |
62 |
46 name = String(required=True, indexed=True, internationalizable=True, |
63 name = String(required=True, indexed=True, internationalizable=True, |
47 maxsize=256) |
64 maxsize=256) |
48 description = RichString(fulltextindexed=True, |
65 description = RichString(fulltextindexed=True, |
55 'the current entity and the current user')) |
72 'the current entity and the current user')) |
56 |
73 |
57 require_group = SubjectRelation('CWGroup', cardinality='**', |
74 require_group = SubjectRelation('CWGroup', cardinality='**', |
58 description=_('group in which a user should be to be ' |
75 description=_('group in which a user should be to be ' |
59 'allowed to pass this transition')) |
76 'allowed to pass this transition')) |
60 transition_of = SubjectRelation('CWEType', cardinality='+*', |
77 transition_of = SubjectRelation('Workflow', cardinality='+*', |
61 description=_('entity types which may use this transition'), |
78 description=_('workflow to which this transition belongs')) |
62 constraints=[RQLConstraint('O final FALSE')]) |
79 |
|
80 |
|
81 class Transition(BaseTransition): |
|
82 """use to define a transition from one or multiple states to a destination |
|
83 states in workflow's definitions. |
|
84 """ |
|
85 __specializes_schema__ = True |
|
86 |
63 destination_state = SubjectRelation('State', cardinality='1*', |
87 destination_state = SubjectRelation('State', cardinality='1*', |
64 constraints=[RQLConstraint('S transition_of ET, O state_of ET')], |
88 constraints=[RQLConstraint('S transition_of WF, O state_of WF')], |
65 description=_('destination state for this transition')) |
89 description=_('destination state for this transition')) |
66 |
90 |
67 |
91 |
|
92 class WorkflowTransition(BaseTransition): |
|
93 """special transition allowing to go through a sub-workflow""" |
|
94 __specializes_schema__ = True |
|
95 |
|
96 subworkflow = SubjectRelation('Workflow', cardinality='1*', |
|
97 constraints=[RQLConstraint('S transition_of WF, WF workflow_of ET, O workflow_of ET')]) |
|
98 subworkflow_exit = SubjectRelation('SubWorkflowExitPoint', cardinality='+1', |
|
99 composite='subject') |
|
100 |
|
101 |
|
102 class SubWorkflowExitPoint(EntityType): |
|
103 """define how we get out from a sub-workflow""" |
|
104 subworkflow_state = SubjectRelation('State', cardinality='1*', |
|
105 constraints=[RQLConstraint('T subworkflow_exit S, T subworkflow WF, O state_of WF')], |
|
106 description=_('subworkflow state')) |
|
107 destination_state = SubjectRelation('State', cardinality='1*', |
|
108 constraints=[RQLConstraint('T subworkflow_exit S, T transition_of WF, O state_of WF')], |
|
109 description=_('destination state')) |
|
110 |
|
111 |
|
112 # XXX should we allow managers to delete TrInfo? |
|
113 |
68 class TrInfo(EntityType): |
114 class TrInfo(EntityType): |
69 permissions = META_ETYPE_PERMS |
115 """workflow history item""" |
70 |
116 # 'add' security actually done by hooks |
71 from_state = SubjectRelation('State', cardinality='?*') |
117 permissions = { |
|
118 'read': ('managers', 'users', 'guests',), # XXX U has_read_permission O ? |
|
119 'add': ('managers', 'users', 'guests',), |
|
120 'delete': (), |
|
121 'update': ('managers', 'owners',), |
|
122 } |
|
123 |
|
124 from_state = SubjectRelation('State', cardinality='1*') |
72 to_state = SubjectRelation('State', cardinality='1*') |
125 to_state = SubjectRelation('State', cardinality='1*') |
|
126 # make by_transition optional because we want to allow managers to set |
|
127 # entity into an arbitrary state without having to respect wf transition |
|
128 by_transition = SubjectRelation('Transition', cardinality='?*') |
73 comment = RichString(fulltextindexed=True) |
129 comment = RichString(fulltextindexed=True) |
74 # get actor and date time using owned_by and creation_date |
130 # get actor and date time using owned_by and creation_date |
75 |
131 |
76 |
|
77 class from_state(RelationType): |
132 class from_state(RelationType): |
78 permissions = HOOKS_RTYPE_PERMS |
133 permissions = HOOKS_RTYPE_PERMS.copy() |
79 inlined = True |
134 inlined = True |
|
135 |
80 class to_state(RelationType): |
136 class to_state(RelationType): |
81 permissions = HOOKS_RTYPE_PERMS |
137 permissions = { |
82 inlined = True |
138 'read': ('managers', 'users', 'guests',), |
83 |
139 'add': ('managers',), |
84 class wf_info_for(RelationType): |
140 'delete': (), |
85 """link a transition information to its object""" |
141 } |
86 permissions = { |
142 inlined = True |
87 'read': ('managers', 'users', 'guests',),# RRQLExpression('U has_read_permission O')), |
143 |
88 'add': (), # handled automatically, no one should add one explicitly |
144 class by_transition(RelationType): |
89 'delete': ('managers',), # RRQLExpression('U has_delete_permission O') |
145 # 'add' security actually done by hooks |
90 } |
146 permissions = { |
91 inlined = True |
147 'read': ('managers', 'users', 'guests',), |
92 composite = 'object' |
148 'add': ('managers', 'users', 'guests',), |
93 fulltext_container = composite |
149 'delete': (), |
|
150 } |
|
151 inlined = True |
|
152 |
|
153 class workflow_of(RelationType): |
|
154 """link a workflow to one or more entity type""" |
|
155 permissions = META_RTYPE_PERMS |
94 |
156 |
95 class state_of(RelationType): |
157 class state_of(RelationType): |
96 """link a state to one or more entity type""" |
158 """link a state to one or more workflow""" |
97 permissions = META_RTYPE_PERMS |
159 permissions = META_RTYPE_PERMS |
|
160 |
98 class transition_of(RelationType): |
161 class transition_of(RelationType): |
99 """link a transition to one or more entity type""" |
162 """link a transition to one or more workflow""" |
100 permissions = META_RTYPE_PERMS |
163 permissions = META_RTYPE_PERMS |
|
164 |
|
165 class subworkflow(RelationType): |
|
166 """link a transition to one or more workflow""" |
|
167 permissions = META_RTYPE_PERMS |
|
168 inlined = True |
|
169 |
|
170 class exit_point(RelationType): |
|
171 """link a transition to one or more workflow""" |
|
172 permissions = META_RTYPE_PERMS |
|
173 |
|
174 class subworkflow_state(RelationType): |
|
175 """link a transition to one or more workflow""" |
|
176 permissions = META_RTYPE_PERMS |
|
177 inlined = True |
101 |
178 |
102 class initial_state(RelationType): |
179 class initial_state(RelationType): |
103 """indicate which state should be used by default when an entity using |
180 """indicate which state should be used by default when an entity using |
104 states is created |
181 states is created |
105 """ |
182 """ |
113 |
190 |
114 class allowed_transition(RelationType): |
191 class allowed_transition(RelationType): |
115 """allowed transition from this state""" |
192 """allowed transition from this state""" |
116 permissions = META_RTYPE_PERMS |
193 permissions = META_RTYPE_PERMS |
117 |
194 |
|
195 |
|
196 # "abstract" relations, set by WorkflowableEntityType ########################## |
|
197 |
|
198 class custom_workflow(RelationType): |
|
199 """allow to set a specific workflow for an entity""" |
|
200 permissions = META_RTYPE_PERMS |
|
201 |
|
202 cardinality = '?*' |
|
203 constraints = [RQLConstraint('S is ET, O workflow_of ET')] |
|
204 object = 'Workflow' |
|
205 |
|
206 |
|
207 class wf_info_for(RelationType): |
|
208 """link a transition information to its object""" |
|
209 # 'add' security actually done by hooks |
|
210 permissions = { |
|
211 'read': ('managers', 'users', 'guests',), |
|
212 'add': ('managers', 'users', 'guests',), |
|
213 'delete': (), |
|
214 } |
|
215 inlined = True |
|
216 |
|
217 cardinality='1*' |
|
218 composite = 'object' |
|
219 fulltext_container = composite |
|
220 subject = 'TrInfo' |
|
221 |
|
222 |
118 class in_state(RelationType): |
223 class in_state(RelationType): |
119 """indicate the current state of an entity""" |
224 """indicate the current state of an entity""" |
|
225 permissions = HOOKS_RTYPE_PERMS |
|
226 |
120 # not inlined intentionnaly since when using ldap sources, user'state |
227 # not inlined intentionnaly since when using ldap sources, user'state |
121 # has to be stored outside the CWUser table |
228 # has to be stored outside the CWUser table |
122 inlined = False |
229 inlined = False |
123 # add/delete perms given to managers/users, after what most of the job |
230 |
124 # is done by workflow enforcment |
231 cardinality = '1*' |
125 permissions = { |
232 constraints = [RQLConstraint('S is ET, O state_of WF, WF workflow_of ET')] |
126 'read': ('managers', 'users', 'guests',), |
233 object = 'State' |
127 'add': ('managers', 'users',), # XXX has_update_perm |
|
128 'delete': ('managers', 'users',), |
|
129 } |
|
130 |
|