From 0a36e2af673eec2cbd065abdf510eb7e07b3e539 Mon Sep 17 00:00:00 2001 From: Frederik Heremans Date: Tue, 13 Aug 2013 09:46:53 +0000 Subject: [PATCH] CLOUD-1927: Start-task permissions take into account workflow-involvement + added test for this behaviour git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@53990 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- ...ctivitiWorkflowServiceIntegrationTest.java | 64 +++++++++++++++++++ .../WorkflowPermissionInterceptor.java | 50 ++++++++++++++- 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java index 074c21d919..7fbfb3aeb0 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java @@ -21,10 +21,12 @@ package org.alfresco.repo.workflow.activiti; import java.io.Serializable; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.workflow.AbstractWorkflowServiceIntegrationTest; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.dictionary.PropertyDefinition; @@ -147,6 +149,68 @@ public class ActivitiWorkflowServiceIntegrationTest extends AbstractWorkflowServ assertEquals("wf:activitiReviewTask", taskDef.getId()); } + public void testAccessStartTaskAsAssigneeFromTaskPartOfProcess() + { + // Test added to validate fix for CLOUD-1929 - start-task can be accesses by assignee of a task + // part of that process + WorkflowDefinition definition = deployDefinition(getAdhocDefinitionPath()); + + // Start process as USER1 + personManager.setUser(USER1); + + // Create workflow parameters + Map params = new HashMap(); + Serializable wfPackage = workflowService.createPackage(null); + params.put(WorkflowModel.ASSOC_PACKAGE, wfPackage); + NodeRef assignee = personManager.get(USER2); + params.put(WorkflowModel.ASSOC_ASSIGNEE, assignee); // task instance field + + WorkflowPath path = workflowService.startWorkflow(definition.getId(), params); + String instanceId = path.getInstance().getId(); + + WorkflowTask startTask = workflowService.getStartTask(instanceId); + workflowService.endTask(startTask.getId(), null); + + List tasks = workflowService.getTasksForWorkflowPath(path.getId()); + assertEquals(1, tasks.size()); + + + // Assign task to user3 + workflowService.updateTask(tasks.get(0).getId(), Collections.singletonMap(WorkflowModel.ASSOC_ASSIGNEE, + (Serializable) personManager.get(USER3)), null, null); + + // Authenticate as user3 + personManager.setUser(USER3); + + // When fetchin the start-task, no exception should be thrown + startTask = workflowService.getStartTask(instanceId); + assertNotNull(startTask); + startTask = workflowService.getTaskById(startTask.getId()); + assertNotNull(startTask); + + // Accessing by user4 shouldn't be possible + personManager.setUser(USER4); + try + { + workflowService.getStartTask(instanceId); + fail("AccessDeniedException expected"); + } + catch(AccessDeniedException expected) + { + // Expected excaption + } + + try + { + workflowService.getTaskById(startTask.getId()); + fail("AccessDeniedException expected"); + } + catch(AccessDeniedException expected) + { + // Expected exception + } + } + @Override protected void checkTaskQueryStartTaskCompleted(String workflowInstanceId, WorkflowTask startTask) diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowPermissionInterceptor.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowPermissionInterceptor.java index d177a12b3f..16187fe17d 100644 --- a/source/java/org/alfresco/service/cmr/workflow/WorkflowPermissionInterceptor.java +++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowPermissionInterceptor.java @@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.workflow.WorkflowModel; +import org.alfresco.repo.workflow.activiti.ActivitiConstants; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.PersonService; @@ -55,11 +56,12 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor String methodName = invocation.getMethod().getName(); - if (methodName.equals("getTaskById") || methodName.equals("getStartTask")) + if (methodName.equals("getTaskById")) { Object result = invocation.proceed(); WorkflowTask wt = (WorkflowTask) result; - if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser)) + if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser) || + isStartTaskOfProcessInvolvedIn(wt, currentUser)) { return result; } @@ -70,6 +72,23 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor } } + + if(methodName.equals("getStartTask")) + { + Object result = invocation.proceed(); + WorkflowTask wt = (WorkflowTask) result; + + if (isInitiatorOrAssignee(wt, currentUser) || isUserPartOfProcess(wt, currentUser)) + { + return result; + } + else + { + String taskId = (String) invocation.getArguments()[0]; + throw new AccessDeniedException("Accessing task with id='" + taskId + "' is not allowed for user '" + currentUser + "'"); + } + + } if (methodName.equals("updateTask") || methodName.equals("endTask")) { @@ -95,7 +114,8 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor for (WorkflowTask wt : rawList) { - if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser)) + if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser) + || isStartTaskOfProcessInvolvedIn(wt, currentUser)) { resultList.add(wt); } @@ -149,6 +169,11 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor return false; } + private boolean isStartTaskOfProcessInvolvedIn(WorkflowTask wt, String userName) + { + return wt.getId().contains(ActivitiConstants.START_TASK_PREFIX) && isUserPartOfProcess(wt, userName); + } + private boolean fromSameParallelReviewWorkflow(WorkflowTask wt, String userName) { // check whether this is parallel review workflow, "parallel" will match all jbpm and activity parallel workflows @@ -171,6 +196,25 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor } return false; } + + private boolean isUserPartOfProcess(WorkflowTask wt, String userName) + { + WorkflowTaskQuery tasksQuery = new WorkflowTaskQuery(); + tasksQuery.setTaskState(null); + tasksQuery.setActive(null); + tasksQuery.setProcessId(wt.getPath().getInstance().getId()); + List allWorkflowTasks = workflowService.queryTasks(tasksQuery, true); + + for (WorkflowTask task : allWorkflowTasks) + { + if (isInitiatorOrAssignee(task, userName)) + { + // if at list one match then user has task from the same workflow + return true; + } + } + return false; + } private NodeRef getUserGroupRef(Object o) {