Fixed ALF-4803: Anyone can cancel a workflow: Service version

The DELETE /api/workflow-instances/{id} now returns a 403 response if the user is not the workflow initiator

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22706 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2010-09-27 08:55:55 +00:00
parent 3c5baa175f
commit 7662e18b01
2 changed files with 67 additions and 9 deletions

View File

@@ -20,14 +20,21 @@ package org.alfresco.repo.web.scripts.workflow;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author unknown
* Web Script implementation of delete or cancel workflow instance.
*
* @author Gavin Cornwell
* @since 3.4
*
*/
public class WorkflowInstanceDelete extends AbstractWorkflowWebscript
{
@@ -41,19 +48,28 @@ public class WorkflowInstanceDelete extends AbstractWorkflowWebscript
// getting workflow instance id from request parameters
String workflowInstanceId = params.get("workflow_instance_id");
boolean forced = getForced(req);
if (forced)
// determine if instance should be cancelled or deleted
boolean forced = getForced(req);
if (canUserEndWorkflow(workflowInstanceId))
{
workflowService.deleteWorkflow(workflowInstanceId);
if (forced)
{
workflowService.deleteWorkflow(workflowInstanceId);
}
else
{
workflowService.cancelWorkflow(workflowInstanceId);
}
return null;
}
else
{
workflowService.cancelWorkflow(workflowInstanceId);
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Failed to " +
(forced ? "delete" : "cancel") + " workflow instance with id: " + workflowInstanceId);
}
return null;
}
private boolean getForced(WebScriptRequest req)
@@ -74,4 +90,36 @@ public class WorkflowInstanceDelete extends AbstractWorkflowWebscript
// Defaults to false.
return false;
}
/**
* Determines if the current user can cancel or delete the
* workflow instance with the given id.
*
* @param instanceId The id of the workflow instance to check
* @return true if the user can end the workflow, false otherwise
*/
private boolean canUserEndWorkflow(String instanceId)
{
boolean canEnd = false;
// get the initiator
WorkflowInstance wi = workflowService.getWorkflowById(instanceId);
NodeRef initiator = wi.getInitiator();
if (initiator != null)
{
// determine if the current user is the initiator of the workflow
String currentUserName = authenticationService.getCurrentUserName();
// get the username of the initiator
String userName = (String)nodeService.getProperty(initiator, ContentModel.PROP_USERNAME);
// if the current user started the workflow allow the cancel action
if (currentUserName.equals(userName))
{
canEnd = true;
}
}
return canEnd;
}
}

View File

@@ -701,7 +701,17 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
startTask = workflowService.endTask(startTask.getId(), null);
WorkflowInstance adhocInstance = startTask.getPath().getInstance();
// attempt to delete workflow as a user that is not the initiator
personManager.setUser(USER3);
Response unauthResponse = sendRequest(new DeleteRequest(URL_WORKFLOW_INSTANCES + "/" + adhocInstance.getId()), 403);
assertEquals(Status.STATUS_FORBIDDEN, unauthResponse.getStatus());
// make sure workflow instance is still present
assertNotNull(workflowService.getWorkflowById(adhocInstance.getId()));
// now delete as initiator of workflow
personManager.setUser(USER1);
Response response = sendRequest(new DeleteRequest(URL_WORKFLOW_INSTANCES + "/" + adhocInstance.getId()), 200);
assertEquals(Status.STATUS_OK, response.getStatus());