Skip to content

Commit

Permalink
CLOUD-1927: Start-task permissions take into account workflow-involve…
Browse files Browse the repository at this point in the history
…ment + added test for this behaviour

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@53990 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
  • Loading branch information
Frederik Heremans committed Aug 13, 2013
1 parent d9ef854 commit 0a36e2a
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@

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;
Expand Down Expand Up @@ -147,6 +149,68 @@ public void testGetWorkflowTaskDefinitionsWithMultiInstanceTask()
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<QName, Serializable> params = new HashMap<QName, Serializable>();
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<WorkflowTask> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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;
Expand All @@ -55,11 +56,12 @@ public Object invoke(MethodInvocation invocation) throws Throwable

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;
}
Expand All @@ -70,6 +72,23 @@ public Object invoke(MethodInvocation invocation) throws Throwable
}

}

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"))
{
Expand All @@ -95,7 +114,8 @@ public Object invoke(MethodInvocation invocation) throws Throwable

for (WorkflowTask wt : rawList)
{
if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser))
if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser)
|| isStartTaskOfProcessInvolvedIn(wt, currentUser))
{
resultList.add(wt);
}
Expand Down Expand Up @@ -149,6 +169,11 @@ private boolean isInitiatorOrAssignee(WorkflowTask wt, String userName)
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
Expand All @@ -171,6 +196,25 @@ private boolean fromSameParallelReviewWorkflow(WorkflowTask wt, String userName)
}
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<WorkflowTask> 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)
{
Expand Down

0 comments on commit 0a36e2a

Please sign in to comment.