From ab66bf28196c16477e118805961ddf116961ba40 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 19 May 2023 10:50:55 -0400 Subject: [PATCH] added elevated permission macro --- .../src/spiffworkflow_backend/api.yml | 2 +- .../config/permissions/example_read_only.yml | 69 +++---------------- .../services/authorization_service.py | 33 +++++++-- .../unit/test_authorization_service.py | 28 ++++++++ 4 files changed, 66 insertions(+), 66 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index 7dcb81ce..a4483f6b 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -1122,7 +1122,7 @@ paths: - Process Instances responses: "200": - description: Empty ok true response on successful resume. + description: Empty ok true response on successful reset. content: application/json: schema: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/example_read_only.yml b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/example_read_only.yml index b6facc64..10a22088 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/example_read_only.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/example_read_only.yml @@ -1,70 +1,17 @@ - groups: admin: users: [admin@spiffworkflow.org] permissions: - admin: + process-groups-ro: groups: [admin] allowed_permissions: [read] - uri: /* - - tasks-crud: + uri: PG:ALL + basic: groups: [admin] - allowed_permissions: [create, update, delete] - uri: /tasks/* - - process-instances-crud: - groups: [ admin ] - allowed_permissions: [create, update, delete] - uri: /process-instances/* - - suspend: + allowed_permissions: [ALL] + uri: BASIC + elevated-operations: groups: [admin] - allowed_permissions: [create] - uri: /v1.0/process-instance-suspend - - terminate: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/process-instance-terminate - - resume: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/process-instance-resume - - reset: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/process-instance-reset - - users-exist: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/users/exists/by-username - - send-event: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/send-event/* - - task-complete: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/task-complete/* - - messages: - groups: [admin] - allowed_permissions: [create] - uri: /v1.0/messages/* - - secrets: - groups: [admin] - allowed_permissions: [create, update, delete] - uri: /v1.0/secrets/* - - task-data: - groups: [admin] - allowed_permissions: [update] - uri: /v1.0/task-data/* + allowed_permissions: [ALL] + uri: ELEVATED diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/authorization_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/authorization_service.py index 1ff58394..0f63531c 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/authorization_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/authorization_service.py @@ -438,10 +438,6 @@ class AuthorizationService: process_related_path_segment: str, target_uris: list[str], ) -> list[PermissionToAssign]: - permissions = permission_set.split(",") - if permission_set == "all": - permissions = ["create", "read", "update", "delete"] - permissions_to_assign: list[PermissionToAssign] = [] # we were thinking that if you can start an instance, you ought to be able to: @@ -472,7 +468,9 @@ class AuthorizationService: ]: permissions_to_assign.append(PermissionToAssign(permission="read", target_uri=target_uri)) else: + permissions = permission_set.split(",") if permission_set == "all": + permissions = ["create", "read", "update", "delete"] for path_segment_dict in PATH_SEGMENTS_FOR_PERMISSION_ALL: target_uri = f"{path_segment_dict['path']}/{process_related_path_segment}" relevant_permissions = path_segment_dict["relevant_permissions"] @@ -512,6 +510,29 @@ class AuthorizationService: permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri="/tasks/*")) return permissions_to_assign + @classmethod + def set_elevated_permissions(cls) -> list[PermissionToAssign]: + permissions_to_assign: list[PermissionToAssign] = [] + for process_instance_action in ["resume", "terminate", "suspend", "reset"]: + permissions_to_assign.append( + PermissionToAssign(permission="create", target_uri=f"/process-instances-{process_instance_action}/*") + ) + + # FIXME: we need to fix so that user that can start a process-model + # can also start through messages as well + permissions_to_assign.append(PermissionToAssign(permission="create", target_uri="/messages/*")) + + permissions_to_assign.append(PermissionToAssign(permission="create", target_uri="/send-event/*")) + permissions_to_assign.append(PermissionToAssign(permission="create", target_uri="/task-complete/*")) + + # read comes from PG and PM permissions + permissions_to_assign.append(PermissionToAssign(permission="update", target_uri="/task-data/*")) + + for permission in ["create", "read", "update", "delete"]: + permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri="/process-instances/*")) + permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri="/secrets/*")) + return permissions_to_assign + @classmethod def set_process_group_permissions(cls, target: str, permission_set: str) -> list[PermissionToAssign]: permissions_to_assign: list[PermissionToAssign] = [] @@ -557,6 +578,8 @@ class AuthorizationService: * affects given process-model BASIC * Basic access to complete tasks and use the site + ELEVATED + * Operations that require elevated permissions Permission Macros: all @@ -579,6 +602,8 @@ class AuthorizationService: elif target.startswith("BASIC"): permissions_to_assign += cls.set_basic_permissions() + elif target.startswith("ELEVATED"): + permissions_to_assign += cls.set_elevated_permissions() elif target == "ALL": for permission in permissions: permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri="/*")) 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 a1f41d3e..a96b3017 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_authorization_service.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_authorization_service.py @@ -301,6 +301,34 @@ class TestAuthorizationService(BaseTest): permissions_to_assign_tuples = sorted([(p.target_uri, p.permission) for p in permissions_to_assign]) assert permissions_to_assign_tuples == expected_permissions + def test_explode_permissions_elevated( + self, + app: Flask, + client: FlaskClient, + with_db_and_bpmn_file_cleanup: None, + ) -> None: + expected_permissions = [ + ("/messages/*", "create"), + ("/process-instances-reset/*", "create"), + ("/process-instances-resume/*", "create"), + ("/process-instances-suspend/*", "create"), + ("/process-instances-terminate/*", "create"), + ("/process-instances/*", "create"), + ("/process-instances/*", "delete"), + ("/process-instances/*", "read"), + ("/process-instances/*", "update"), + ("/secrets/*", "create"), + ("/secrets/*", "delete"), + ("/secrets/*", "read"), + ("/secrets/*", "update"), + ("/send-event/*", "create"), + ("/task-complete/*", "create"), + ("/task-data/*", "update"), + ] + permissions_to_assign = AuthorizationService.explode_permissions("all", "ELEVATED") + permissions_to_assign_tuples = sorted([(p.target_uri, p.permission) for p in permissions_to_assign]) + assert permissions_to_assign_tuples == expected_permissions + def test_explode_permissions_all( self, app: Flask,