diff --git a/config/alfresco/form-services-context.xml b/config/alfresco/form-services-context.xml index 90f160774f..c441008672 100644 --- a/config/alfresco/form-services-context.xml +++ b/config/alfresco/form-services-context.xml @@ -156,7 +156,7 @@ + parent="baseFormProcessor"> @@ -167,8 +167,9 @@ - + + task diff --git a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java index 800341cf4b..8ad0a15283 100644 --- a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java +++ b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java @@ -35,6 +35,7 @@ import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint; import org.alfresco.repo.forms.processor.node.FormFieldConstants; import org.alfresco.repo.forms.processor.node.TypeFormProcessor; import org.alfresco.repo.jscript.ClasspathScriptLocation; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ContentData; @@ -114,9 +115,11 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest private static String LABEL_CONTAINS = "Contains"; private static final String USER_ONE = "UserOne_FormServiceImplTest"; + private static final String USER_TWO = "UserTwo_FormServiceImplTest"; private static final String NODE_FORM_ITEM_KIND = "node"; private static final String TYPE_FORM_ITEM_KIND = "type"; private static final String WORKFLOW_FORM_ITEM_KIND = "workflow"; + private static final String TASK_FORM_ITEM_KIND = "task"; /** * Called during the transaction setup @@ -135,8 +138,11 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest this.contentService = (ContentService)this.applicationContext.getBean("ContentService"); this.workflowService = (WorkflowService)this.applicationContext.getBean("WorkflowService"); - // Do the tests as userOne + // create users createUser(USER_ONE); + createUser(USER_TWO); + + // Do the tests as userOne authenticationComponent.setCurrentUser(USER_ONE); String guid = GUID.generate(); @@ -1304,7 +1310,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest return fields; } - public void testWorkflowForm() throws Exception + public void testWorkflowForms() throws Exception { // generate a form for a well known workflow-definition supplying // a legitimate set of fields for the workflow @@ -1374,6 +1380,33 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest // check workflow instance details assertEquals("jbpm$wf:adhoc", workflow.definition.name); + + // update the first task in the users list + String taskId = tasks.get(0).getId(); + String comment = "This is a comment"; + data = new FormData(); + data.addFieldData("prop_bpm_comment", comment); + this.formService.saveForm(new Item(TASK_FORM_ITEM_KIND, taskId), data); + + // check the comment was updated + WorkflowTask task = workflowService.getTaskById(taskId); + String taskComment = (String)task.getProperties().get(WorkflowModel.PROP_COMMENT); + assertEquals(comment, taskComment); + + // make sure unauthorized user can not update the task + authenticationComponent.setCurrentUser(USER_TWO); + + try + { + // try and update task + this.formService.saveForm(new Item(TASK_FORM_ITEM_KIND, taskId), data); + + fail("Task was updated by an unauthorized user"); + } + catch (AccessDeniedException ade) + { + // expected + } } public void testNoForm() throws Exception diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormPersister.java b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormPersister.java index 520443c8ce..b204d13137 100644 --- a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormPersister.java +++ b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormPersister.java @@ -24,10 +24,12 @@ import java.util.List; import org.alfresco.repo.forms.FormData.FieldData; import org.alfresco.repo.forms.processor.node.ContentModelItemData; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.workflow.TaskUpdater; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.namespace.NamespaceService; @@ -50,10 +52,18 @@ public class TaskFormPersister extends ContentModelFormPersister DictionaryService dictionaryService, WorkflowService workflowService, NodeService nodeService, + AuthenticationService authenticationService, Log logger) { super(itemData, namespaceService, dictionaryService, logger); WorkflowTask item = itemData.getItem(); + + // make sure the current user is able to edit the task + if (!workflowService.isTaskEditable(item, authenticationService.getCurrentUserName())) + { + throw new AccessDeniedException("Failed to update task with id '" + item.getId() + "'."); + } + this.updater = new TaskUpdater(item.id, workflowService, nodeService); } diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java index b12bb68b86..6ba6f1016f 100644 --- a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java +++ b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java @@ -38,7 +38,10 @@ import org.alfresco.repo.forms.processor.node.ContentModelItemData; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.TypeDefinition; +import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTransition; @@ -58,6 +61,8 @@ public class TaskFormProcessor extends AbstractWorkflowFormProcessor makeFormPersister(WorkflowTask item) { ContentModelItemData itemData = makeItemData(item); - return new TaskFormPersister(itemData, namespaceService, dictionaryService, workflowService, nodeService, LOGGER); + return new TaskFormPersister(itemData, namespaceService, dictionaryService, + workflowService, nodeService, authenticationService, LOGGER); } } diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java index 4e280bc46a..b67b7caa13 100644 --- a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java +++ b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java @@ -76,6 +76,7 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowException; import org.alfresco.service.cmr.workflow.WorkflowInstance; @@ -119,6 +120,7 @@ public class TaskFormProcessorTest extends TestCase private TaskFormProcessor processor; private WorkflowTask task; private NamespaceService namespaceService; + private AuthenticationService authenticationService; private WorkflowTask newTask; private Map actualProperties = null; private Map> actualAdded= null; @@ -523,6 +525,7 @@ public class TaskFormProcessorTest extends TestCase nodeService = makeNodeService(); DictionaryService dictionaryService = makeDictionaryService(); namespaceService = makeNamespaceService(); + authenticationService = makeAuthenticationService(); MockFieldProcessorRegistry fieldProcessorRegistry = new MockFieldProcessorRegistry(namespaceService, dictionaryService); DefaultFieldProcessor defaultProcessor = makeDefaultFieldProcessor(dictionaryService); @@ -537,6 +540,7 @@ public class TaskFormProcessorTest extends TestCase processor1.setNodeService(nodeService); processor1.setNamespaceService(namespaceService); processor1.setDictionaryService(dictionaryService); + processor1.setAuthenticationService(authenticationService); processor1.setFieldProcessorRegistry(fieldProcessorRegistry); return processor1; } @@ -670,6 +674,13 @@ public class TaskFormProcessorTest extends TestCase return mock; } + private AuthenticationService makeAuthenticationService() + { + AuthenticationService mock = mock(AuthenticationService.class); + when(mock.getCurrentUserName()).thenReturn("admin"); + return mock; + } + @SuppressWarnings("unchecked") private WorkflowService makeWorkflowService() { @@ -707,6 +718,9 @@ public class TaskFormProcessorTest extends TestCase when(service.endTask(eq(TASK_ID), anyString())) .thenReturn(newTask); + + when(service.isTaskEditable((WorkflowTask)any(), anyString())).thenReturn(true); + return service; }