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
This commit is contained in:
Frederik Heremans
2013-08-13 09:46:53 +00:00
parent d9ef85464d
commit 0a36e2af67
2 changed files with 111 additions and 3 deletions

View File

@@ -21,10 +21,12 @@ package org.alfresco.repo.workflow.activiti;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.workflow.AbstractWorkflowServiceIntegrationTest; import org.alfresco.repo.workflow.AbstractWorkflowServiceIntegrationTest;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition;
@@ -147,6 +149,68 @@ public class ActivitiWorkflowServiceIntegrationTest extends AbstractWorkflowServ
assertEquals("wf:activitiReviewTask", taskDef.getId()); 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 @Override
protected void checkTaskQueryStartTaskCompleted(String workflowInstanceId, WorkflowTask startTask) protected void checkTaskQueryStartTaskCompleted(String workflowInstanceId, WorkflowTask startTask)

View File

@@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.workflow.WorkflowModel; 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.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
@@ -55,11 +56,29 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor
String methodName = invocation.getMethod().getName(); String methodName = invocation.getMethod().getName();
if (methodName.equals("getTaskById") || methodName.equals("getStartTask")) if (methodName.equals("getTaskById"))
{ {
Object result = invocation.proceed(); Object result = invocation.proceed();
WorkflowTask wt = (WorkflowTask) result; WorkflowTask wt = (WorkflowTask) result;
if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser)) if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser) ||
isStartTaskOfProcessInvolvedIn(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("getStartTask"))
{
Object result = invocation.proceed();
WorkflowTask wt = (WorkflowTask) result;
if (isInitiatorOrAssignee(wt, currentUser) || isUserPartOfProcess(wt, currentUser))
{ {
return result; return result;
} }
@@ -95,7 +114,8 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor
for (WorkflowTask wt : rawList) for (WorkflowTask wt : rawList)
{ {
if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser)) if (isInitiatorOrAssignee(wt, currentUser) || fromSameParallelReviewWorkflow(wt, currentUser)
|| isStartTaskOfProcessInvolvedIn(wt, currentUser))
{ {
resultList.add(wt); resultList.add(wt);
} }
@@ -149,6 +169,11 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor
return false; 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) private boolean fromSameParallelReviewWorkflow(WorkflowTask wt, String userName)
{ {
// check whether this is parallel review workflow, "parallel" will match all jbpm and activity parallel workflows // check whether this is parallel review workflow, "parallel" will match all jbpm and activity parallel workflows
@@ -172,6 +197,25 @@ public class WorkflowPermissionInterceptor implements MethodInterceptor
return false; 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) private NodeRef getUserGroupRef(Object o)
{ {
NodeRef result = null; NodeRef result = null;