Beispiel #1
0
 def __call__(self):
     entity = self.entity
     if self.event == 'before_delete_entity' and entity.name == 'owners':
         raise validation_error(entity, {None: _("can't be deleted")})
     elif self.event == 'before_update_entity' \
              and 'name' in entity.cw_edited:
         oldname, newname = entity.cw_edited.oldnewvalue('name')
         if oldname == 'owners' and newname != oldname:
             raise validation_error(
                 entity, {('name', 'subject'): _("can't be changed")})
Beispiel #2
0
 def precommit_event(self):
     # notice that enforcement that new workflow apply to the entity's type is
     # done by schema rule, no need to check it here
     cnx = self.cnx
     pendingeids = cnx.transaction_data.get('pendingeids', ())
     if self.eid in pendingeids:
         return
     entity = cnx.entity_from_eid(self.eid)
     iworkflowable = entity.cw_adapt_to('IWorkflowable')
     # check custom workflow has not been rechanged to another one in the same
     # transaction
     mainwf = iworkflowable.main_workflow
     if mainwf.eid == self.wfeid:
         deststate = mainwf.initial
         if not deststate:
             msg = _('workflow has no initial state')
             raise validation_error(entity,
                                    {('custom_workflow', 'subject'): msg})
         if mainwf.state_by_eid(iworkflowable.current_state.eid):
             # nothing to do
             return
         # if there are no history, simply go to new workflow's initial state
         if not iworkflowable.workflow_history:
             if iworkflowable.current_state.eid != deststate.eid:
                 _change_state(cnx, entity.eid,
                               iworkflowable.current_state.eid,
                               deststate.eid)
                 _FireAutotransitionOp(cnx, eid=entity.eid)
             return
         msg = cnx._('workflow changed to "%s"')
         msg %= cnx._(mainwf.name)
         cnx.transaction_data[(entity.eid, 'customwf')] = self.wfeid
         iworkflowable.change_state(deststate, msg, u'text/plain')
Beispiel #3
0
    def __call__(self):
        if self.entity.type not in SOURCE_TYPES:
            msg = _('Unknown source type')
            raise validation_error(self.entity, {('type', 'subject'): msg})

        source = self.get_source(self.entity)
        source.check_urls(self.entity)
        source.check_config(self.entity)
Beispiel #4
0
 def __call__(self):
     key, value = self.entity.pkey, self.entity.value
     if key.startswith('sources.'):
         return
     cnx = self._cw
     try:
         value = cnx.vreg.typed_value(key, value)
     except UnknownProperty:
         msg = _('unknown property key %s')
         raise validation_error(self.entity, {('pkey', 'subject'): msg},
                                (key, ))
     except ValueError as ex:
         raise validation_error(self.entity,
                                {('value', 'subject'): str(ex)})
     if cnx.user.matching_groups('managers'):
         _ChangeSiteWideCWPropertyOp(cnx, cwprop=self.entity)
     else:
         cnx.add_relation(self.entity.eid, 'for_user', cnx.user.eid)
Beispiel #5
0
 def precommit_event(self):
     tr = self.cnx.entity_from_eid(self.treid)
     outputs = set()
     for ep in tr.subworkflow_exit:
         if ep.subwf_state.eid in outputs:
             msg = _("can't have multiple exits on the same state")
             raise validation_error(self.treid,
                                    {('subworkflow_exit', 'subject'): msg})
         outputs.add(ep.subwf_state.eid)
Beispiel #6
0
 def __call__(self):
     cnx = self._cw
     eidfrom = self.eidfrom
     if not cnx.entity_type(eidfrom) == 'CWProperty':
         return
     key, value = cnx.execute(
         'Any K,V WHERE P eid %(x)s,P pkey K,P value V', {'x': eidfrom})[0]
     if cnx.vreg.property_info(key)['sitewide']:
         msg = _("site-wide property can't be set for user")
         raise validation_error(eidfrom, {('for_user', 'subject'): msg})
Beispiel #7
0
    def __call__(self):
        if 'name' in self.entity.cw_edited:
            oldname, newname = self.entity.cw_edited.oldnewvalue('name')
            if oldname == 'system':
                msg = _("You cannot rename the system source")
                raise validation_error(self.entity, {('name', 'subject'): msg})

        source = self.get_source(self.entity)
        if 'url' in self.entity.cw_edited:
            source.check_urls(self.entity)
        if 'config' in self.entity.cw_edited:
            source.check_config(self.entity)
Beispiel #8
0
 def signalerror(etype, eid, rtype, role):
     msg = _(
         'at least one relation %(rtype)s is required on %(etype)s (%(eid)s)'
     )
     errors.append({
         etype:
         str(
             validation_error(eid, {(rtype, role): msg}, {
                                        'rtype': rtype,
                                        'etype': etype,
                                        'eid': eid
                                    }, ['rtype', 'etype']))
     })
Beispiel #9
0
 def __call__(self):
     cnx = self._cw
     nocheck = cnx.transaction_data.get('skip-security', ())
     if (self.eidfrom, 'in_state', self.eidto) in nocheck:
         # state changed through TrInfo insertion, so we already know it's ok
         return
     entity = cnx.entity_from_eid(self.eidfrom)
     iworkflowable = entity.cw_adapt_to('IWorkflowable')
     mainwf = iworkflowable.main_workflow
     if mainwf is None:
         msg = _('entity has no workflow set')
         raise validation_error(entity, {None: msg})
     for wf in mainwf.iter_workflows():
         if wf.state_by_eid(self.eidto):
             break
     else:
         msg = _("state doesn't belong to entity's workflow. You may "
                 "want to set a custom workflow for this entity first.")
         raise validation_error(self.eidfrom,
                                {('in_state', 'subject'): msg})
     if iworkflowable.current_workflow and wf.eid != iworkflowable.current_workflow.eid:
         msg = _("state doesn't belong to entity's current workflow")
         raise validation_error(self.eidfrom,
                                {('in_state', 'subject'): msg})
Beispiel #10
0
 def __call__(self):
     entity = self.entity
     if not ('pkey' in entity.cw_edited or 'value' in entity.cw_edited):
         return
     key, value = entity.pkey, entity.value
     if key.startswith('sources.'):
         return
     cnx = self._cw
     try:
         value = cnx.vreg.typed_value(key, value)
     except UnknownProperty:
         return
     except ValueError as ex:
         raise validation_error(entity, {('value', 'subject'): str(ex)})
     if not entity.for_user:
         _ChangeSiteWideCWPropertyOp(cnx, cwprop=self.entity)
Beispiel #11
0
 def precommit_event(self):
     cnx = self.cnx
     forentity = cnx.entity_from_eid(self.foreid)
     iworkflowable = forentity.cw_adapt_to('IWorkflowable')
     trinfo = self.trinfo
     # we're in a subworkflow, check if we've reached an exit point
     wftr = iworkflowable.subworkflow_input_transition()
     if wftr is None:
         # inconsistency detected
         msg = _("state doesn't belong to entity's current workflow")
         raise validation_error(self.trinfo, {('to_state', 'subject'): msg})
     tostate = wftr.get_exit_point(forentity,
                                   trinfo.cw_attr_cache['to_state'])
     if tostate is not None:
         # reached an exit point
         msg = _('exiting from subworkflow %s')
         msg %= cnx._(iworkflowable.current_workflow.name)
         cnx.transaction_data[(forentity.eid, 'subwfentrytr')] = True
         iworkflowable.change_state(tostate, msg, u'text/plain', tr=wftr)
Beispiel #12
0
 def precommit_event(self):
     cnx = self.cnx
     pendingeids = cnx.transaction_data.get('pendingeids', ())
     pendingrtypes = cnx.transaction_data.get('pendingrtypes', ())
     for eid, rtype in self.get_data():
         # recheck pending eids / relation types
         if eid in pendingeids:
             continue
         if rtype in pendingrtypes:
             continue
         if not cnx.execute(self.base_rql % rtype, {'x': eid}):
             etype = cnx.entity_type(eid)
             msg = _('at least one relation %(rtype)s is required on '
                     '%(etype)s (%(eid)s)')
             raise validation_error(eid, {(rtype, self.role): msg}, {
                                              'rtype': rtype,
                                              'etype': etype,
                                              'eid': eid
                                          }, ['rtype', 'etype'])
Beispiel #13
0
 def __call__(self):
     if self.entity.name == 'system':
         msg = _("You cannot remove the system source")
         raise validation_error(self.entity, {None: msg})
Beispiel #14
0
 def __call__(self):
     cnx = self._cw
     entity = self.entity
     # first retreive entity to which the state change apply
     try:
         foreid = entity.cw_attr_cache['wf_info_for']
     except KeyError:
         msg = _('mandatory relation')
         raise validation_error(entity, {('wf_info_for', 'subject'): msg})
     forentity = cnx.entity_from_eid(foreid)
     # see comment in the TrInfo entity definition
     entity.cw_edited['tr_count'] = len(forentity.reverse_wf_info_for)
     iworkflowable = forentity.cw_adapt_to('IWorkflowable')
     # then check it has a workflow set, unless we're in the process of changing
     # entity's workflow
     if cnx.transaction_data.get((forentity.eid, 'customwf')):
         wfeid = cnx.transaction_data[(forentity.eid, 'customwf')]
         wf = cnx.entity_from_eid(wfeid)
     else:
         wf = iworkflowable.current_workflow
     if wf is None:
         msg = _('related entity has no workflow set')
         raise validation_error(entity, {None: msg})
     # then check it has a state set
     fromstate = iworkflowable.current_state
     if fromstate is None:
         msg = _('related entity has no state')
         raise validation_error(entity, {None: msg})
     # True if we are coming back from subworkflow
     swtr = cnx.transaction_data.pop((forentity.eid, 'subwfentrytr'), None)
     cowpowers = (cnx.user.is_in_group('managers')
                  or not cnx.write_security)
     # no investigate the requested state change...
     try:
         treid = entity.cw_attr_cache['by_transition']
     except KeyError:
         # no transition set, check user is a manager and destination state
         # is specified (and valid)
         if not cowpowers:
             msg = _('mandatory relation')
             raise validation_error(entity,
                                    {('by_transition', 'subject'): msg})
         deststateeid = entity.cw_attr_cache.get('to_state')
         if not deststateeid:
             msg = _('mandatory relation')
             raise validation_error(entity,
                                    {('by_transition', 'subject'): msg})
         deststate = wf.state_by_eid(deststateeid)
         if deststate is None:
             msg = _("state doesn't belong to entity's workflow")
             raise validation_error(entity, {('to_state', 'subject'): msg})
     else:
         # check transition is valid and allowed, unless we're coming back
         # from subworkflow
         tr = cnx.entity_from_eid(treid)
         if swtr is None:
             qname = ('by_transition', 'subject')
             if tr is None:
                 msg = _("transition doesn't belong to entity's workflow")
                 raise validation_error(entity, {qname: msg})
             if not tr.has_input_state(fromstate):
                 msg = _("transition %(tr)s isn't allowed from %(st)s")
                 raise validation_error(entity, {qname: msg}, {
                     'tr': tr.name,
                     'st': fromstate.name
                 }, ['tr', 'st'])
             if not tr.may_be_fired(foreid):
                 msg = _("transition may not be fired")
                 raise validation_error(entity, {qname: msg})
         deststateeid = entity.cw_attr_cache.get('to_state')
         if deststateeid is not None:
             if not cowpowers and deststateeid != tr.destination(
                     forentity).eid:
                 msg = _("transition isn't allowed")
                 raise validation_error(entity,
                                        {('by_transition', 'subject'): msg})
             if swtr is None:
                 deststate = cnx.entity_from_eid(deststateeid)
                 if not cowpowers and deststate is None:
                     msg = _("state doesn't belong to entity's workflow")
                     raise validation_error(entity,
                                            {('to_state', 'subject'): msg})
         else:
             deststateeid = tr.destination(forentity).eid
     # everything is ok, add missing information on the trinfo entity
     entity.cw_edited['from_state'] = fromstate.eid
     entity.cw_edited['to_state'] = deststateeid
     nocheck = cnx.transaction_data.setdefault('skip-security', set())
     nocheck.add((entity.eid, 'from_state', fromstate.eid))
     nocheck.add((entity.eid, 'to_state', deststateeid))
     _FireAutotransitionOp(cnx, eid=forentity.eid)