added script to get process initiator w/ burnettk

This commit is contained in:
jasquat 2023-02-27 14:28:19 -05:00
parent 6a4dc0f14e
commit 29ada38904
16 changed files with 133 additions and 29 deletions

View File

@ -34,7 +34,9 @@ class HumanTaskModel(SpiffworkflowBaseDBModel):
lane_assignment_id: int | None = db.Column(ForeignKey(GroupModel.id))
completed_by_user_id: int = db.Column(ForeignKey(UserModel.id), nullable=True) # type: ignore
completed_by_user = relationship("UserModel", foreign_keys=[completed_by_user_id])
completed_by_user = relationship(
"UserModel", foreign_keys=[completed_by_user_id], viewonly=True
)
actual_owner_id: int = db.Column(ForeignKey(UserModel.id)) # type: ignore
# actual_owner: RelationshipProperty[UserModel] = relationship(UserModel)

View File

@ -2,6 +2,7 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
import jwt
import marshmallow
@ -82,6 +83,13 @@ class UserModel(SpiffworkflowBaseDBModel):
#
# return instance
def as_dict(self) -> dict[str, Any]:
# dump the user using our json encoder and then load it back up as a dict
# to remove unwanted field types
user_as_json_string = current_app.json.dumps(self)
user_dict: dict[str, Any] = current_app.json.loads(user_as_json_string)
return user_dict
class UserModelSchema(Schema):
"""UserModelSchema."""

View File

@ -1,8 +1,6 @@
"""Get current user."""
from typing import Any
from flask import current_app
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
@ -38,14 +36,13 @@ class GetLastUserCompletingTask(Script):
human_task = (
HumanTaskModel.query.filter_by(
bpmn_process_identifier=bpmn_process_identifier, task_name=task_name
process_instance_id=script_attributes_context.process_instance_id,
bpmn_process_identifier=bpmn_process_identifier,
task_name=task_name,
)
.order_by(HumanTaskModel.id.desc()) # type: ignore
.join(UserModel, UserModel.id == HumanTaskModel.completed_by_user_id)
.first()
)
# dump the user using our json encoder and then load it back up as a dict
# to remove unwanted field types
user_as_json_string = current_app.json.dumps(human_task.completed_by_user)
return current_app.json.loads(user_as_json_string)
return human_task.completed_by_user.as_dict()

View File

@ -0,0 +1,36 @@
"""Get current user."""
from typing import Any
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
)
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.scripts.script import Script
class GetProcessInitiatorUser(Script):
@staticmethod
def requires_privileged_permissions() -> bool:
"""We have deemed this function safe to run without elevated permissions."""
return False
def get_description(self) -> str:
return """Return the user that initiated the process instance."""
def run(
self,
script_attributes_context: ScriptAttributesContext,
*_args: Any,
**kwargs: Any,
) -> Any:
"""Run."""
process_instance = (
ProcessInstanceModel.query.filter_by(
id=script_attributes_context.process_instance_id
)
.join(UserModel, UserModel.id == ProcessInstanceModel.process_initiator_id)
.first()
)
return process_instance.process_initiator.as_dict()

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Proccess_0e253c6" isExecutable="true">
<bpmn:process id="Process_0e253c6" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1my9ag5</bpmn:outgoing>
</bpmn:startEvent>
@ -28,7 +28,7 @@ form_ui_hidden_fields = ["veryImportantFieldButOnlySometimes", "building.floor"]
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_0e253c6">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0e253c6">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="159" width="36" height="36" />
</bpmndi:BPMNShape>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0">
<bpmn:process id="Proccess_With_Bad_Form" name="Process With Form" isExecutable="true">
<bpmn:process id="Process_With_Bad_Form" name="Process With Form" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0smvjir</bpmn:outgoing>
</bpmn:startEvent>
@ -21,7 +21,7 @@ Department: {{ department }}
</bpmn:manualTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_With_Bad_Form">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_With_Bad_Form">
<bpmndi:BPMNEdge id="Flow_1boyhcj_di" bpmnElement="Flow_1boyhcj">
<di:waypoint x="340" y="117" />
<di:waypoint x="382" y="117" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Proccess_LocalTime" name="Get LocalTime" isExecutable="true">
<bpmn:process id="Process_LocalTime" name="Get LocalTime" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0ijucqh</bpmn:outgoing>
</bpmn:startEvent>
@ -40,7 +40,7 @@ localtime = get_localtime(some_time, timezone)</bpmn:script>
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_LocalTime">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_LocalTime">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="159" width="36" height="36" />
</bpmndi:BPMNShape>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Proccess_ManualTask" name="Manual Task" isExecutable="true">
<bpmn:process id="Process_ManualTask" name="Manual Task" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1xlck7g</bpmn:outgoing>
</bpmn:startEvent>
@ -18,7 +18,7 @@
</bpmn:manualTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_ManualTask">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_ManualTask">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="159" width="36" height="36" />
</bpmndi:BPMNShape>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:collaboration id="Collaboration_0iyw0q7">
<bpmn:participant id="Participant_17eqap4" processRef="Proccess_yhito9d" />
<bpmn:participant id="Participant_17eqap4" processRef="Process_yhito9d" />
</bpmn:collaboration>
<bpmn:process id="Proccess_yhito9d" isExecutable="true">
<bpmn:process id="Process_yhito9d" isExecutable="true">
<bpmn:laneSet id="LaneSet_17rankp">
<bpmn:lane id="process_initiator" name="Process Initiator">
<bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:collaboration id="Collaboration_0iyw0q7">
<bpmn:participant id="Participant_17eqap4" processRef="Proccess_yhito9d" />
<bpmn:participant id="Participant_17eqap4" processRef="Process_yhito9d" />
</bpmn:collaboration>
<bpmn:process id="Proccess_yhito9d" isExecutable="true">
<bpmn:process id="Process_yhito9d" isExecutable="true">
<bpmn:laneSet id="LaneSet_17rankp">
<bpmn:lane id="process_initiator" name="Process Initiator">
<bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef>

View File

@ -26,6 +26,7 @@ Department: {{ department }}
<spiffworkflow:property name="formJsonSchemaFilename" value="simple_form.json" />
<spiffworkflow:property name="formUiSchemaFilename" value="simple_form_ui.json" />
</spiffworkflow:properties>
<spiffworkflow:postScript>process_initiator_user = get_process_initiator_user()</spiffworkflow:postScript>
</bpmn:extensionElements>
<bpmn:incoming>Flow_0smvjir</bpmn:incoming>
<bpmn:outgoing>Flow_1ly1khd</bpmn:outgoing>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Proccess_With_Bad_Form" name="Process With Form" isExecutable="true">
<bpmn:process id="Process_With_Bad_Form" name="Process With Form" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0smvjir</bpmn:outgoing>
</bpmn:startEvent>
@ -31,7 +31,7 @@ Department: {{ department }}
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_WithForm">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_WithForm">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="159" width="36" height="36" />
</bpmndi:BPMNShape>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Proccess_SimpleScript" name="Simple Script" isExecutable="true">
<bpmn:process id="Process_SimpleScript" name="Simple Script" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0r3ua0i</bpmn:outgoing>
</bpmn:startEvent>
@ -48,7 +48,7 @@ b = 2</bpmn:script>
<bpmn:sequenceFlow id="Flow_1vqk60p" sourceRef="Activity_DisplayData" targetRef="Event_19fiqu4" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_SimpleScript">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_SimpleScript">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="159" width="36" height="36" />
</bpmndi:BPMNShape>

View File

@ -583,7 +583,7 @@ class TestProcessApi(BaseTest):
# We should get 5 back, as one of the items in the cache is a decision.
assert len(response.json) == 5
simple_form = next(
p for p in response.json if p["identifier"] == "Proccess_WithForm"
p for p in response.json if p["identifier"] == "Process_WithForm"
)
assert simple_form["display_name"] == "Process With Form"
assert simple_form["process_model_id"] == "test_group_one/simple_form"

View File

@ -1,12 +1,11 @@
"""Test_get_localtime."""
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
from flask.app import Flask
from flask.testing import FlaskClient
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,
)
@ -16,7 +15,6 @@ from spiffworkflow_backend.services.process_instance_service import (
class TestGetLastUserCompletingTask(BaseTest):
def test_get_last_user_completing_task_script_works(
self,
app: Flask,

View File

@ -0,0 +1,62 @@
"""Test_get_localtime."""
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
from flask.app import Flask
from flask.testing import FlaskClient
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,
)
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
class TestGetProcessInitiatorUser(BaseTest):
def test_get_process_initiator_user(
self,
app: Flask,
client: FlaskClient,
with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel,
) -> None:
"""Test_sets_permission_correctly_on_human_task."""
self.create_process_group(
client, with_super_admin_user, "test_group", "test_group"
)
initiator_user = self.find_or_create_user("initiator_user")
assert initiator_user.principal is not None
AuthorizationService.import_permissions_from_yaml_file()
process_model = load_test_spec(
process_model_id="misc/category_number_one/simple_form",
# bpmn_file_name="simp.bpmn",
process_model_source_directory="simple_form",
)
process_instance = self.create_process_instance_from_process_model(
process_model=process_model, user=initiator_user
)
processor = ProcessInstanceProcessor(process_instance)
processor.do_engine_steps(save=True)
assert len(process_instance.active_human_tasks) == 1
human_task = process_instance.active_human_tasks[0]
assert len(human_task.potential_owners) == 1
assert human_task.potential_owners[0] == initiator_user
spiff_task = processor.__class__.get_task_by_bpmn_identifier(
human_task.task_name, processor.bpmn_process_instance
)
ProcessInstanceService.complete_form_task(
processor, spiff_task, {"name": "HEY"}, initiator_user, human_task
)
assert spiff_task is not None
assert (
initiator_user.username
== spiff_task.get_data("process_initiator_user")["username"]
)