diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java b/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java index 3f434663c15..3e21349e824 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java +++ b/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java @@ -141,6 +141,13 @@ public boolean canCallSaveData(LoggedUser loggedUser, String taskId) { return loggedUser.getSelfOrImpersonated().isAdmin() || isAssignee(loggedUser, taskId); } + @Override + public boolean canCallGetData(LoggedUser loggedUser, String taskId) { + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.VIEW); + Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.VIEW); + return loggedUser.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + } + @Override public boolean canCallSaveFile(LoggedUser loggedUser, String taskId) { return loggedUser.getSelfOrImpersonated().isAdmin() || isAssignee(loggedUser, taskId); diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java b/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java index e65e9a3d013..db79954bc09 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java +++ b/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java @@ -31,6 +31,8 @@ public interface ITaskAuthorizationService { boolean canCallSaveData(LoggedUser loggedUser, String taskId); + boolean canCallGetData(LoggedUser loggedUser, String taskId); + boolean canCallSaveFile(LoggedUser loggedUser, String taskId); } diff --git a/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java b/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java index 02818262191..e1f244d9d4f 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java +++ b/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java @@ -110,7 +110,7 @@ public EntityModel cancel(@PathVariable("id") String ta return super.cancel(loggedUser, taskId, locale); } - @Override + @PreAuthorize("@taskAuthorizationService.canCallGetData(@userService.getAnonymousLogged(), #taskId)") @GetMapping(value = "/{id}/data", produces = MediaTypes.HAL_JSON_VALUE) @Operation(summary = "Get all task data") public EntityModel getData(@PathVariable("id") String taskId, Locale locale) { diff --git a/src/main/java/com/netgrif/application/engine/workflow/web/TaskController.java b/src/main/java/com/netgrif/application/engine/workflow/web/TaskController.java index 593f37ce4ee..70509da528f 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/web/TaskController.java +++ b/src/main/java/com/netgrif/application/engine/workflow/web/TaskController.java @@ -176,10 +176,10 @@ public CountResponse count(@RequestBody SingleElasticTaskSearchRequestAsList que return super.count(query, operation, auth, locale); } - @Override + @PreAuthorize("@taskAuthorizationService.canCallGetData(#auth.getPrincipal(), #taskId)") @Operation(summary = "Get all task data", security = {@SecurityRequirement(name = "BasicAuth")}) @GetMapping(value = "/{id}/data", produces = MediaTypes.HAL_JSON_VALUE) - public EntityModel getData(@PathVariable("id") String taskId, Locale locale) { + public EntityModel getData(@PathVariable("id") String taskId, Authentication auth, Locale locale) { return super.getData(taskId, locale); } diff --git a/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/DataGroupsResource.java b/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/DataGroupsResource.java index 3b37ed432d4..08a5efb98b9 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/DataGroupsResource.java +++ b/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/DataGroupsResource.java @@ -18,11 +18,16 @@ public DataGroupsResource(Collection id != null && !id.isBlank()) + .findFirst() + .orElse(null); + buildLinks(taskId); } - private void buildLinks() { + private void buildLinks(String taskId) { add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(TaskController.class) - .getData("", null)).withSelfRel()); + .getData(taskId, null, null)).withSelfRel()); } } diff --git a/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/LocalisedTaskResource.java b/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/LocalisedTaskResource.java index 36b0ce5d636..f9e74c5ab6f 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/LocalisedTaskResource.java +++ b/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/LocalisedTaskResource.java @@ -34,7 +34,7 @@ private void buildLinks() { add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(TaskController.class) .cancel((Authentication) null, task.getStringId(), null)).withRel("cancel")); add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(TaskController.class) - .getData(task.getStringId(), null)).withRel("data")); + .getData(task.getStringId(), null, null)).withRel("data")); add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(TaskController.class) .setData(task.getStringId(), null, null)).withRel("data-edit")); try { diff --git a/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy b/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy index 6b1271c6439..5e47ee44982 100644 --- a/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy +++ b/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy @@ -479,4 +479,53 @@ class TaskAuthorizationServiceTest { workflowService.deleteCase(case_.stringId) } + @Test + void testCanGetDataWithPosViewRole() { + ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "view_pos_role") + userService.addRole(testUser, positiveRole.getStringId()) + Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test get data", "", testUser.transformToLoggedUser()).getCase() + assert taskAuthorizationService.canCallGetData(testUser.transformToLoggedUser(), (new ArrayList<>(case_.getTasks())).get(0).task) + userService.removeRole(testUser, positiveRole.getStringId()) + workflowService.deleteCase(case_.stringId) + } + + @Test + void testCannotGetDataWithNegViewRole() { + ProcessRole negativeRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "view_neg_role") + userService.addRole(testUser, negativeRole.getStringId()) + Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test get data", "", testUser.transformToLoggedUser()).getCase() + assert !taskAuthorizationService.canCallGetData(testUser.transformToLoggedUser(), (new ArrayList<>(case_.getTasks())).get(0).task) + userService.removeRole(testUser, negativeRole.getStringId()) + workflowService.deleteCase(case_.stringId) + } + + @Test + void testCanGetDataWithPosViewUserRef() { + Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test get data", "", testUser.transformToLoggedUser()).getCase() + String taskId = (new ArrayList<>(case_.getTasks())).get(0).task + dataService.setData(taskId, ImportHelper.populateDataset([ + "view_pos_ul": [ + "value": [testUser.stringId], + "type": "userList" + ] + ] as Map)).getCase() + + assert taskAuthorizationService.canCallGetData(testUser.transformToLoggedUser(), taskId) + workflowService.deleteCase(case_.stringId) + } + + @Test + void testCannotGetDataWithNegViewUserRef() { + Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test get data", "", testUser.transformToLoggedUser()).getCase() + String taskId = (new ArrayList<>(case_.getTasks())).get(0).task + dataService.setData(taskId, ImportHelper.populateDataset([ + "view_neg_ul": [ + "value": [testUser.stringId], + "type": "userList" + ] + ] as Map)).getCase() + + assert !taskAuthorizationService.canCallGetData(testUser.transformToLoggedUser(), taskId) + workflowService.deleteCase(case_.stringId) + } } diff --git a/src/test/resources/task_authorization_service_test_with_userRefs.xml b/src/test/resources/task_authorization_service_test_with_userRefs.xml index ef5c5f338d7..fa6b93beeb0 100644 --- a/src/test/resources/task_authorization_service_test_with_userRefs.xml +++ b/src/test/resources/task_authorization_service_test_with_userRefs.xml @@ -4,6 +4,10 @@ wst_usersRef WSU WorkflowAuthorizationService test + + view_pos_role + view pos role + assign_pos_role assign pos role @@ -12,6 +16,10 @@ finish_pos_role finish pos role + + view_neg_role + view neg role + assign_neg_role assign neg role @@ -20,6 +28,10 @@ finish_neg_role finish neg role + + view_pos_ul + + </data> <data type="userList"> <id>assign_pos_ul</id> <title/> @@ -40,6 +52,10 @@ <id>cancel_pos_ul</id> <title/> </data> + <data type="userList"> + <id>view_neg_ul</id> + <title/> + </data> <data type="userList"> <id>cancel_neg_ul</id> <title/> @@ -66,6 +82,18 @@ <x>1</x> <y>1</y> <label>Transition</label> + <roleRef> + <id>view_pos_role</id> + <logic> + <view>true</view> + </logic> + </roleRef> + <roleRef> + <id>view_neg_role</id> + <logic> + <view>false</view> + </logic> + </roleRef> <roleRef> <id>assign_pos_role</id> <logic> @@ -90,6 +118,18 @@ <finish>false</finish> </logic> </roleRef> + <userRef> + <id>view_pos_ul</id> + <logic> + <view>true</view> + </logic> + </userRef> + <userRef> + <id>view_neg_ul</id> + <logic> + <view>false</view> + </logic> + </userRef> <userRef> <id>assign_pos_ul</id> <logic>