misc: keep track of user that changed a workflow in snapshot (#87843)
gitea/wcs/pipeline/head This commit looks good
Details
gitea/wcs/pipeline/head This commit looks good
Details
This commit is contained in:
parent
36e1f16a31
commit
23e66ec078
|
@ -765,7 +765,7 @@ def test_form_workflow_link(pub):
|
|||
|
||||
def test_form_workflow_remapping(pub):
|
||||
AfterJob.wipe()
|
||||
create_superuser(pub)
|
||||
user = create_superuser(pub)
|
||||
create_role(pub)
|
||||
|
||||
FormDef.wipe()
|
||||
|
@ -872,6 +872,8 @@ def test_form_workflow_remapping(pub):
|
|||
resp = resp.follow() # -> to job processing page
|
||||
resp = resp.click('Back')
|
||||
assert resp.pyquery('[href="workflow"] .offset').text() == 'Workflow Three'
|
||||
assert pub.snapshot_class.select_object_history(formdef)[0].comment == 'Workflow change'
|
||||
assert pub.snapshot_class.select_object_history(formdef)[0].user_id == str(user.id)
|
||||
|
||||
# run a SQL SELECT and we known all columns are defined.
|
||||
FormDef.get(formdef.id).data_class().select()
|
||||
|
|
|
@ -1140,7 +1140,12 @@ class FormDefPage(Directory, TempfileDirectoryMixin):
|
|||
# there are existing formdata, status will have to be mapped
|
||||
return redirect('workflow-status-remapping?new=%s' % workflow_id)
|
||||
|
||||
job = WorkflowChangeJob(formdef=self.formdef, new_workflow_id=workflow_id, status_mapping={})
|
||||
job = WorkflowChangeJob(
|
||||
formdef=self.formdef,
|
||||
new_workflow_id=workflow_id,
|
||||
status_mapping={},
|
||||
user_id=get_session().user,
|
||||
)
|
||||
job.store()
|
||||
get_response().add_after_job(job)
|
||||
return redirect(job.get_processing_url())
|
||||
|
@ -1230,7 +1235,10 @@ class FormDefPage(Directory, TempfileDirectoryMixin):
|
|||
return self.workflow_status_remapping()
|
||||
|
||||
job = WorkflowChangeJob(
|
||||
formdef=self.formdef, new_workflow_id=new_workflow.id, status_mapping=status_mapping
|
||||
formdef=self.formdef,
|
||||
new_workflow_id=new_workflow.id,
|
||||
status_mapping=status_mapping,
|
||||
user_id=get_session().user,
|
||||
)
|
||||
job.store()
|
||||
get_response().add_after_job(job)
|
||||
|
@ -2042,19 +2050,20 @@ class FormsDirectory(AccessControlled, Directory):
|
|||
|
||||
|
||||
class WorkflowChangeJob(AfterJob):
|
||||
def __init__(self, formdef, new_workflow_id, status_mapping):
|
||||
def __init__(self, formdef, new_workflow_id, status_mapping, user_id):
|
||||
super().__init__(
|
||||
label=_('Updating data for new workflow'),
|
||||
formdef_class=formdef.__class__,
|
||||
formdef_id=formdef.id,
|
||||
new_workflow_id=new_workflow_id,
|
||||
status_mapping=status_mapping,
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
def execute(self):
|
||||
formdef = self.kwargs['formdef_class'].get(self.kwargs['formdef_id'])
|
||||
workflow = Workflow.get(self.kwargs['new_workflow_id'])
|
||||
formdef.change_workflow(workflow, self.kwargs['status_mapping'])
|
||||
formdef.change_workflow(workflow, self.kwargs['status_mapping'], user_id=self.kwargs.get('user_id'))
|
||||
|
||||
def done_action_url(self):
|
||||
formdef = self.kwargs['formdef_class'].get(self.kwargs['formdef_id'])
|
||||
|
|
|
@ -1967,7 +1967,7 @@ class FormDef(StorableObject):
|
|||
# chunk contains the fields.
|
||||
return pickle.dumps(object, protocol=2) + pickle.dumps(object.fields, protocol=2)
|
||||
|
||||
def change_workflow(self, new_workflow, status_mapping=None):
|
||||
def change_workflow(self, new_workflow, status_mapping=None, user_id=None):
|
||||
old_workflow = self.get_workflow()
|
||||
|
||||
formdata_count = self.data_class().count()
|
||||
|
@ -2003,7 +2003,7 @@ class FormDef(StorableObject):
|
|||
if function_key not in new_workflow.roles:
|
||||
del self.workflow_roles[function_key]
|
||||
removed_functions.add(function_key)
|
||||
self.store(comment=_('Workflow change'))
|
||||
self.store(comment=_('Workflow change'), snapshot_store_user=user_id)
|
||||
if formdata_count:
|
||||
# instruct formdef to update its security rules
|
||||
self.data_class().rebuild_security()
|
||||
|
|
|
@ -150,13 +150,21 @@ class Snapshot:
|
|||
]
|
||||
|
||||
@classmethod
|
||||
def snap(cls, instance, comment=None, label=None, store_user=True, application=None):
|
||||
def snap(cls, instance, comment=None, label=None, store_user=None, application=None):
|
||||
obj = cls()
|
||||
obj.object_type = instance.xml_root_node
|
||||
obj.object_id = instance.id
|
||||
obj.timestamp = now()
|
||||
if get_session() and store_user:
|
||||
obj.user_id = get_session().user
|
||||
# store_user:
|
||||
# None/True: get user from active session
|
||||
# False: do not store user
|
||||
# any value: consider it as user id
|
||||
# (store_user is explicitely checked to be a boolean, to avoid the "1" integer being treated as True)
|
||||
if store_user is None or (isinstance(store_user, bool) and store_user is True):
|
||||
if get_session():
|
||||
obj.user_id = get_session().user
|
||||
elif store_user:
|
||||
obj.user_id = store_user
|
||||
|
||||
tree = instance.export_to_xml(include_id=True)
|
||||
# remove position for categories
|
||||
|
|
Loading…
Reference in New Issue