From 1ae1df890848d22617cd10c611e5d496428db790 Mon Sep 17 00:00:00 2001 From: ryzheboka <25465835+ryzheboka@users.noreply.github.com> Date: Mon, 16 May 2022 16:49:28 +0200 Subject: [PATCH] TSK-1889: create TASK_ROUTER role --- .../pro/taskana/common/api/TaskanaRole.java | 5 +-- .../task/internal/TaskServiceImpl.java | 8 +++-- .../internal/WorkbasketServiceImpl.java | 12 +++++-- .../config/TaskanaRoleConfigAccTest.java | 6 +++- .../task/claim/ClaimTaskAccTest.java | 8 +++++ .../task/complete/CancelTaskAccTest.java | 8 +++++ .../task/complete/CompleteTaskAccTest.java | 8 +++++ .../task/complete/TerminateTaskAccTest.java | 4 +-- .../task/create/CreateTaskAccTest.java | 32 +++++++++++++++++++ .../task/delete/DeleteTaskAccTest.java | 9 ++++++ .../acceptance/task/get/GetTaskAccTest.java | 9 ++++++ .../task/query/QueryTasksByRoleAccTest.java | 4 +++ .../task/transfer/TransferTaskAccTest.java | 11 +++++++ .../task/update/UpdateTaskAccTest.java | 15 +++++++++ .../src/test/resources/taskana.properties | 1 + 15 files changed, 130 insertions(+), 10 deletions(-) diff --git a/common/taskana-common/src/main/java/pro/taskana/common/api/TaskanaRole.java b/common/taskana-common/src/main/java/pro/taskana/common/api/TaskanaRole.java index 3f59a2b0e..e19b52f95 100644 --- a/common/taskana-common/src/main/java/pro/taskana/common/api/TaskanaRole.java +++ b/common/taskana-common/src/main/java/pro/taskana/common/api/TaskanaRole.java @@ -6,13 +6,14 @@ import java.util.stream.Collectors; import pro.taskana.common.api.exceptions.SystemException; -/** This enum contains all roles that are known to taskana. */ +/** The TaskanaRole enum contains all roles that are known to TASKANA. */ public enum TaskanaRole { USER("taskana.roles.user"), BUSINESS_ADMIN("taskana.roles.businessadmin"), ADMIN("taskana.roles.admin"), MONITOR("taskana.roles.monitor"), - TASK_ADMIN("taskana.roles.taskadmin"); + TASK_ADMIN("taskana.roles.taskadmin"), + TASK_ROUTER("taskana.roles.taskrouter"); private final String propertyName; diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java index c578f8f1a..442cb6993 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java @@ -226,10 +226,12 @@ public class TaskServiceImpl implements TaskService { task.setWorkbasketSummary(workbasket.asSummary()); task.setDomain(workbasket.getDomain()); - workbasketService.checkAuthorization( - task.getWorkbasketSummary().getId(), WorkbasketPermission.APPEND); + if (!taskanaEngine.getEngine().isUserInRole(TaskanaRole.TASK_ROUTER)) { + workbasketService.checkAuthorization( + task.getWorkbasketSummary().getId(), WorkbasketPermission.APPEND); + } - // we do use the key and not the ID to make sure that we use the classification from the right + // we do use the key and not the id to make sure that we use the classification from the right // domain. // otherwise we would have to check the classification and its domain for validity. String classificationKey = task.getClassificationKey(); diff --git a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java index a07a06297..3d04d077b 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java @@ -92,7 +92,11 @@ public class WorkbasketServiceImpl implements WorkbasketService { if (!taskanaEngine .getEngine() - .isUserInRole(TaskanaRole.ADMIN, TaskanaRole.BUSINESS_ADMIN, TaskanaRole.TASK_ADMIN)) { + .isUserInRole( + TaskanaRole.ADMIN, + TaskanaRole.BUSINESS_ADMIN, + TaskanaRole.TASK_ADMIN, + TaskanaRole.TASK_ROUTER)) { this.checkAuthorization(workbasketId, WorkbasketPermission.READ); } return result; @@ -106,7 +110,11 @@ public class WorkbasketServiceImpl implements WorkbasketService { throws WorkbasketNotFoundException, NotAuthorizedException { if (!taskanaEngine .getEngine() - .isUserInRole(TaskanaRole.ADMIN, TaskanaRole.BUSINESS_ADMIN, TaskanaRole.TASK_ADMIN)) { + .isUserInRole( + TaskanaRole.ADMIN, + TaskanaRole.BUSINESS_ADMIN, + TaskanaRole.TASK_ADMIN, + TaskanaRole.TASK_ROUTER)) { this.checkAuthorization(workbasketKey, domain, WorkbasketPermission.READ); } diff --git a/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java b/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java index 7b94581b8..1b15d0f4a 100644 --- a/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java @@ -15,7 +15,7 @@ import pro.taskana.TaskanaEngineConfiguration; import pro.taskana.common.api.TaskanaRole; import pro.taskana.common.test.config.DataSourceGenerator; -/** Test taskana's role configuration. */ +/** Test the role configuration of TASKANA. */ class TaskanaRoleConfigAccTest { @TempDir Path tempDir; @@ -61,6 +61,10 @@ class TaskanaRoleConfigAccTest { Set monitorAccessIds = taskanaEngineConfiguration.getRoleMap().get(TaskanaRole.MONITOR); assertThat(monitorAccessIds) .containsExactlyInAnyOrder("monitor", "cn=monitor-users,cn=groups,ou=test,o=taskana"); + + Set taskRouters = taskanaEngineConfiguration.getRoleMap().get(TaskanaRole.TASK_ROUTER); + assertThat(taskRouters) + .containsExactlyInAnyOrder("cn=routers,cn=groups,ou=test,o=taskana", "user-taskrouter"); } @Test diff --git a/lib/taskana-core/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java index c1e604553..76ff43ec0 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import pro.taskana.common.api.BulkOperationResults; +import pro.taskana.common.api.exceptions.NotAuthorizedException; import pro.taskana.common.api.exceptions.TaskanaException; import pro.taskana.common.test.security.JaasExtension; import pro.taskana.common.test.security.WithAccessId; @@ -81,6 +82,13 @@ class ClaimTaskAccTest extends AbstractAccTest { assertThatThrownBy(call).isInstanceOf(InvalidOwnerException.class); } + @WithAccessId(user = "user-taskrouter") + @Test + void should_ThrowNotAuthorizedException_When_UserHasNoReadPermission() throws Exception { + assertThatThrownBy(() -> taskService.claim("TKI:000000000000000000000000000000000000")) + .isInstanceOf(NotAuthorizedException.class); + } + @WithAccessId(user = "user-1-2") @Test void testCancelClaimTask() throws Exception { diff --git a/lib/taskana-core/src/test/java/acceptance/task/complete/CancelTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/complete/CancelTaskAccTest.java index d5abade08..b199c7870 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/complete/CancelTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/complete/CancelTaskAccTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; +import pro.taskana.common.api.exceptions.NotAuthorizedException; import pro.taskana.common.test.security.JaasExtension; import pro.taskana.common.test.security.WithAccessId; import pro.taskana.task.api.TaskState; @@ -80,6 +81,13 @@ class CancelTaskAccTest extends AbstractAccTest { assertThat(newNumTasksCancelled).isEqualTo(numTasksCancelled + 1); } + @WithAccessId(user = "user-taskrouter") + @Test + void should_ThrowException_When_UserNotAuthorized() { + assertThatThrownBy(() -> taskService.cancelTask("TKI:000000000000000000000000000000000001")) + .isInstanceOf(NotAuthorizedException.class); + } + @WithAccessId(user = "admin") @Test void testCancelCompletedTask() { diff --git a/lib/taskana-core/src/test/java/acceptance/task/complete/CompleteTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/complete/CompleteTaskAccTest.java index f110f29c2..82ef9787c 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/complete/CompleteTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/complete/CompleteTaskAccTest.java @@ -128,6 +128,14 @@ class CompleteTaskAccTest extends AbstractAccTest { assertThatThrownBy(call).isInstanceOf(TaskNotFoundException.class); } + @WithAccessId(user = "user-taskrouter") + @Test + void should_ThrowException_When_UserIsNotAuthorized() { + ThrowingCallable call = + () -> taskService.completeTask("TKI:000000000000000000000000000000000001"); + assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class); + } + @WithAccessId(user = "user-1-1") @Test void should_ThrowException_When_UserIsNotAuthorizedOnTask() { diff --git a/lib/taskana-core/src/test/java/acceptance/task/complete/TerminateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/complete/TerminateTaskAccTest.java index a37865b8f..daab5d370 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/complete/TerminateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/complete/TerminateTaskAccTest.java @@ -78,9 +78,9 @@ class TerminateTaskAccTest extends AbstractAccTest { } @WithAccessId(user = "user-1-2") - @Test + @WithAccessId(user = "user-taskrouter") + @TestTemplate void should_ThrowException_When_UserIsNotInAdministrativeRole() { - ThrowingCallable taskanaCall = () -> taskService.terminateTask("TKI:000000000000000000000000000000000000"); diff --git a/lib/taskana-core/src/test/java/acceptance/task/create/CreateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/create/CreateTaskAccTest.java index ec49da813..b371e6d2f 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/create/CreateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/create/CreateTaskAccTest.java @@ -59,6 +59,38 @@ class CreateTaskAccTest extends AbstractAccTest { assertThat(task.asSummary().getAttachmentSummaries()).isNotNull(); } + @WithAccessId(user = "user-taskrouter") + @Test + void should_CreateTask_When_UserIsMemberOfTaskRouterRole() throws Exception { + TaskService taskService = taskanaEngine.getTaskService(); + Task newTask = taskService.newTask("WBI:100000000000000000000000000000000006"); + newTask.setClassificationKey("T2100"); + ObjectReferenceImpl objectReference = + createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"); + objectReference.setTaskId(newTask.getId()); + newTask.setPrimaryObjRef(objectReference); + + Task createdTask = taskService.createTask(newTask); + + assertThat(createdTask).isNotNull(); + } + + @WithAccessId(user = "user-1-1", groups = "cn=routers,cn=groups,OU=Test,O=TASKANA") + @Test + void should_CreateTask_When_UserIsMemberOfGroupWithTaskRouterRole() throws Exception { + TaskService taskService = taskanaEngine.getTaskService(); + Task newTask = taskService.newTask("WBI:100000000000000000000000000000000010"); + newTask.setClassificationKey("T2100"); + ObjectReferenceImpl objectReference = + createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"); + objectReference.setTaskId(newTask.getId()); + newTask.setPrimaryObjRef(objectReference); + + Task createdTask = taskService.createTask(newTask); + + assertThat(createdTask).isNotNull(); + } + @WithAccessId(user = "user-1-1") @Test void should_BeAbleToCreateNewTask_When_TaskCopy() throws Exception { diff --git a/lib/taskana-core/src/test/java/acceptance/task/delete/DeleteTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/delete/DeleteTaskAccTest.java index d19756bbc..e04cf5528 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/delete/DeleteTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/delete/DeleteTaskAccTest.java @@ -29,6 +29,15 @@ class DeleteTaskAccTest extends AbstractAccTest { @WithAccessId(user = "user-1-2") @Test void testDeleteSingleTaskNotAuthorized() { + ThrowingCallable call = + () -> taskService.deleteTask("TKI:000000000000000000000000000000000037"); + + assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class); + } + + @WithAccessId(user = "user-taskrouter") + @Test + void should_ThrowNotAuthorizedException_When_UserIsMemberOfTaskRouterRole() { ThrowingCallable call = () -> taskService.deleteTask("TKI:000000000000000000000000000000000037"); assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class); diff --git a/lib/taskana-core/src/test/java/acceptance/task/get/GetTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/get/GetTaskAccTest.java index af6582068..c8343d165 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/get/GetTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/get/GetTaskAccTest.java @@ -127,6 +127,15 @@ class GetTaskAccTest extends AbstractAccTest { assertThatThrownBy(getTaskCall).isInstanceOf(NotAuthorizedException.class); } + @WithAccessId(user = "user-taskrouter") + @Test + void should_ThrowException_When_UserIsNotAuthorizedToGetTaskAndMemberOfTaskRouterRole() { + ThrowingCallable getTaskCall = + () -> taskService.getTask("TKI:000000000000000000000000000000000000"); + + assertThatThrownBy(getTaskCall).isInstanceOf(NotAuthorizedException.class); + } + @WithAccessId(user = "admin") @WithAccessId(user = "taskadmin") @TestTemplate diff --git a/lib/taskana-core/src/test/java/acceptance/task/query/QueryTasksByRoleAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/query/QueryTasksByRoleAccTest.java index def51b281..1768c7e9c 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/query/QueryTasksByRoleAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/query/QueryTasksByRoleAccTest.java @@ -37,6 +37,7 @@ class QueryTasksByRoleAccTest extends AbstractAccTest { @WithAccessId(user = "monitor") @WithAccessId(user = "teamlead-1") @WithAccessId(user = "user-1-1") + @WithAccessId(user = "user-taskrouter") @TestTemplate void should_FindAllAccessibleTasksDependentOnTheUser_When_MakingTaskQuery() { TaskService taskService = taskanaEngine.getTaskService(); @@ -59,6 +60,9 @@ class QueryTasksByRoleAccTest extends AbstractAccTest { case "user-1-1": expectedSize = 7; break; + case "user-taskrouter": + expectedSize = 0; + break; default: throw new SystemException( String.format( diff --git a/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java index 75c665705..e50d53bcf 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java @@ -107,6 +107,17 @@ class TransferTaskAccTest extends AbstractAccTest { assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class); } + @WithAccessId(user = "user-1-1", groups = "cn=routers,cn=groups,OU=Test,O=TASKANA") + @Test + void should_ThrowException_When_UserHasNoTransferAuthorizationAndIsMemeberOfTaskRouterRole() + throws Exception { + Task task = taskService.getTask("TKI:000000000000000000000000000000000001"); + + assertThatThrownBy( + () -> taskService.transfer(task.getId(), "WBI:100000000000000000000000000000000005")) + .isInstanceOf(NotAuthorizedException.class); + } + @WithAccessId(user = "teamlead-1", groups = GROUP_1_DN) @Test void should_ThrowException_When_DestinationWorkbasketDoesNotExist() throws Exception { diff --git a/lib/taskana-core/src/test/java/acceptance/task/update/UpdateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/update/UpdateTaskAccTest.java index 385fc7804..88df3cf34 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/update/UpdateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/update/UpdateTaskAccTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import pro.taskana.classification.api.models.ClassificationSummary; import pro.taskana.common.api.exceptions.ConcurrencyException; import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; import pro.taskana.common.test.security.JaasExtension; import pro.taskana.common.test.security.WithAccessId; import pro.taskana.task.api.TaskCustomField; @@ -162,6 +163,20 @@ class UpdateTaskAccTest extends AbstractAccTest { .isInstanceOf(InvalidArgumentException.class); } + @WithAccessId(user = "user-taskrouter") + @Test + void should_ThrowException_When_UserIsNotAuthorized() { + TaskImpl task = new TaskImpl(); + task.setId("TKI:000000000000000000000000000000000000"); + task.setPrimaryObjRef( + taskService.newObjectReference("company", "system", "instance", "value", "type")); + task.setClassificationKey("L1050"); + task.setWorkbasketKey("USER-1-2"); + + assertThatThrownBy(() -> taskService.updateTask(task)) + .isInstanceOf(NotAuthorizedException.class); + } + @WithAccessId(user = "user-1-1") @Test void should_ThrowException_When_TaskHasAlreadyBeenUpdated() throws Exception { diff --git a/lib/taskana-core/src/test/resources/taskana.properties b/lib/taskana-core/src/test/resources/taskana.properties index efe937009..87334f97e 100644 --- a/lib/taskana-core/src/test/resources/taskana.properties +++ b/lib/taskana-core/src/test/resources/taskana.properties @@ -3,6 +3,7 @@ taskana.roles.admin=admin | uid=admin,cn=users,OU=Test,O=TASKANA taskana.roles.businessadmin=businessadmin | cn=business-admins,cn=groups,OU=Test,O=TASKANA taskana.roles.monitor=monitor | cn=monitor-users,cn=groups,OU=Test,O=TASKANA taskana.roles.taskadmin=taskadmin +taskana.roles.taskrouter=cn=routers,cn=groups,OU=Test,O=TASKANA | user-taskrouter taskana.domains=Domain_A , DOMAIN_B taskana.classification.types=TASK , document taskana.classification.categories.task=EXTERNAL, manual, autoMAtic, Process