diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/unit_testing.yml b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/unit_testing.yml index 4192d1dd..841dd481 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/unit_testing.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/unit_testing.yml @@ -29,20 +29,10 @@ permissions: allowed_permissions: [all] uri: ELEVATED - read-all: - groups: ["Finance Team", hr, admin] - allowed_permissions: [read] - uri: /* - - process-instances-find-by-id: + basic-permission: groups: [everybody] - allowed_permissions: [read] - uri: /process-instances/find-by-id/* - - tasks-crud: - groups: [everybody] - allowed_permissions: [create, read, update, delete] - uri: /tasks/* + allowed_permissions: [all] + uri: BASIC finance-admin-group: groups: ["Finance Team"] @@ -54,12 +44,7 @@ permissions: allowed_permissions: [start] uri: PG:finance - finance-admin-model-lanes: - groups: ["Finance Team"] - allowed_permissions: [create, read, update, delete] - uri: /process-models/finance:model_with_lanes/* - - finance-admin-instance-run: - groups: ["Finance Team"] - allowed_permissions: [create, read, update, delete] - uri: /process-instances/* + read-all-finance: + groups: [hr] + allowed_permissions: [read] + uri: PG:finance diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py index a0aaa107..065ad1f3 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py @@ -70,6 +70,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): bpmn_process = relationship(BpmnProcessModel, cascade="delete") tasks = relationship("TaskModel", cascade="delete") # type: ignore + task_draft_data = relationship("TaskDraftDataModel", cascade="delete") # type: ignore process_instance_events = relationship("ProcessInstanceEventModel", cascade="delete") # type: ignore process_instance_file_data = relationship("ProcessInstanceFileDataModel", cascade="delete") # type: ignore human_tasks = relationship( diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py index aac9b022..8ee6ff7d 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py @@ -281,12 +281,10 @@ def task_show(process_instance_id: int, task_guid: str = "next") -> flask.wrappe try: AuthorizationService.assert_user_can_complete_task(process_instance.id, task_model.guid, g.user) can_complete = True - except HumanTaskNotFoundError: - can_complete = False - except UserDoesNotHaveAccessToTaskError: + except (HumanTaskNotFoundError, UserDoesNotHaveAccessToTaskError, HumanTaskAlreadyCompletedError): can_complete = False - task_draft_data = TaskService.task_draft_data_from_task_model(task_model, create_if_not_exists=True) + task_draft_data = TaskService.task_draft_data_from_task_model(task_model) saved_form_data = None if task_draft_data is not None: @@ -564,6 +562,13 @@ def _task_submit_shared( human_task=human_task, ) + # delete draft data when we submit a task to ensure cycling back to the task contains the + # most up-to-date data + task_draft_data = TaskService.task_draft_data_from_task_model(human_task.task_model) + if task_draft_data is not None: + db.session.delete(task_draft_data) + db.session.commit() + next_human_task_assigned_to_me = ( HumanTaskModel.query.filter_by(process_instance_id=process_instance_id, completed=False) .order_by(asc(HumanTaskModel.id)) # type: ignore diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_openid_blueprint.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_openid_blueprint.py index 33221e7d..9751fb80 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_openid_blueprint.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_openid_blueprint.py @@ -61,7 +61,7 @@ class TestFlaskOpenId(BaseTest): "redirect_url": "http://localhost:7000/v1.0/login_return", } response = client.post("/openid/token", data=data, headers=headers) - assert response + assert response.status_code == 200 assert response.is_json assert "access_token" in response.json assert "id_token" in response.json diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_tasks_controller.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_tasks_controller.py index 5d390f18..13744b10 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_tasks_controller.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_tasks_controller.py @@ -318,3 +318,21 @@ class TestTasksController(BaseTest): assert response.status_code == 200 assert response.json is not None assert response.json["saved_form_data"] == draft_data + + response = client.put( + f"/v1.0/tasks/{process_instance_id}/{task_id}", + headers=self.logged_in_headers(with_super_admin_user), + content_type="application/json", + data=json.dumps(draft_data), + ) + assert response.status_code == 200 + + # ensure draft data is deleted after submitting the task + response = client.get( + f"/v1.0/tasks/{process_instance_id}/{task_id}", + headers=self.logged_in_headers(with_super_admin_user), + ) + assert response.status_code == 200 + assert response.json is not None + assert response.json["saved_form_data"] is None + assert response.json["data"]["HEY"] == draft_data["HEY"] diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_authorization_service.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_authorization_service.py index 3393c24b..0bfc2cc2 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_authorization_service.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_authorization_service.py @@ -48,6 +48,7 @@ class TestAuthorizationService(BaseTest): self.assert_user_has_permission(users["testuser2"], "update", "/v1.0/process-groups/finance:model1") self.assert_user_has_permission(users["testuser2"], "update", "/v1.0/process-groups", expected_result=False) self.assert_user_has_permission(users["testuser2"], "read", "/v1.0/process-groups") + self.assert_user_has_permission(users["testuser2"], "update", "/v1.0/process-groups", expected_result=False) def test_user_can_be_added_to_human_task_on_first_login( self,