Added task update protection to the task form processor and changed the check in TaskInstancePut to use the new isTaskEditable method on the WorkflowService.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21918 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2010-08-23 07:24:12 +00:00
parent 4cad8ab1fd
commit 96b61bae8c
5 changed files with 82 additions and 6 deletions

View File

@@ -169,6 +169,7 @@
parent="baseFormProcessor"> parent="baseFormProcessor">
<property name="filterRegistry" ref="taskFilterRegistry" /> <property name="filterRegistry" ref="taskFilterRegistry" />
<property name="workflowService" ref="workflowServiceImpl" /> <property name="workflowService" ref="workflowServiceImpl" />
<property name="authenticationService" ref="AuthenticationService" />
<property name="matchPattern"> <property name="matchPattern">
<value>task</value> <value>task</value>
</property> </property>

View File

@@ -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.FormFieldConstants;
import org.alfresco.repo.forms.processor.node.TypeFormProcessor; import org.alfresco.repo.forms.processor.node.TypeFormProcessor;
import org.alfresco.repo.jscript.ClasspathScriptLocation; import org.alfresco.repo.jscript.ClasspathScriptLocation;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
@@ -114,9 +115,11 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
private static String LABEL_CONTAINS = "Contains"; private static String LABEL_CONTAINS = "Contains";
private static final String USER_ONE = "UserOne_FormServiceImplTest"; 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 NODE_FORM_ITEM_KIND = "node";
private static final String TYPE_FORM_ITEM_KIND = "type"; private static final String TYPE_FORM_ITEM_KIND = "type";
private static final String WORKFLOW_FORM_ITEM_KIND = "workflow"; private static final String WORKFLOW_FORM_ITEM_KIND = "workflow";
private static final String TASK_FORM_ITEM_KIND = "task";
/** /**
* Called during the transaction setup * Called during the transaction setup
@@ -135,8 +138,11 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
this.contentService = (ContentService)this.applicationContext.getBean("ContentService"); this.contentService = (ContentService)this.applicationContext.getBean("ContentService");
this.workflowService = (WorkflowService)this.applicationContext.getBean("WorkflowService"); this.workflowService = (WorkflowService)this.applicationContext.getBean("WorkflowService");
// Do the tests as userOne // create users
createUser(USER_ONE); createUser(USER_ONE);
createUser(USER_TWO);
// Do the tests as userOne
authenticationComponent.setCurrentUser(USER_ONE); authenticationComponent.setCurrentUser(USER_ONE);
String guid = GUID.generate(); String guid = GUID.generate();
@@ -1304,7 +1310,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
return fields; return fields;
} }
public void testWorkflowForm() throws Exception public void testWorkflowForms() throws Exception
{ {
// generate a form for a well known workflow-definition supplying // generate a form for a well known workflow-definition supplying
// a legitimate set of fields for the workflow // a legitimate set of fields for the workflow
@@ -1374,6 +1380,33 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
// check workflow instance details // check workflow instance details
assertEquals("jbpm$wf:adhoc", workflow.definition.name); 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 public void testNoForm() throws Exception

View File

@@ -24,10 +24,12 @@ import java.util.List;
import org.alfresco.repo.forms.FormData.FieldData; import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.processor.node.ContentModelItemData; import org.alfresco.repo.forms.processor.node.ContentModelItemData;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.workflow.TaskUpdater; import org.alfresco.repo.workflow.TaskUpdater;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; 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.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
@@ -50,10 +52,18 @@ public class TaskFormPersister extends ContentModelFormPersister<WorkflowTask>
DictionaryService dictionaryService, DictionaryService dictionaryService,
WorkflowService workflowService, WorkflowService workflowService,
NodeService nodeService, NodeService nodeService,
AuthenticationService authenticationService,
Log logger) Log logger)
{ {
super(itemData, namespaceService, dictionaryService, logger); super(itemData, namespaceService, dictionaryService, logger);
WorkflowTask item = itemData.getItem(); 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); this.updater = new TaskUpdater(item.id, workflowService, nodeService);
} }

View File

@@ -38,7 +38,10 @@ import org.alfresco.repo.forms.processor.node.ContentModelItemData;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition; 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.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.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTransition; import org.alfresco.service.cmr.workflow.WorkflowTransition;
@@ -58,6 +61,8 @@ public class TaskFormProcessor extends AbstractWorkflowFormProcessor<WorkflowTas
/** Logger */ /** Logger */
private static final Log LOGGER = LogFactory.getLog(TaskFormProcessor.class); private static final Log LOGGER = LogFactory.getLog(TaskFormProcessor.class);
protected AuthenticationService authenticationService;
// Constructor for Spring // Constructor for Spring
public TaskFormProcessor() public TaskFormProcessor()
{ {
@@ -66,14 +71,26 @@ public class TaskFormProcessor extends AbstractWorkflowFormProcessor<WorkflowTas
// Constructor for tests. // Constructor for tests.
public TaskFormProcessor(WorkflowService workflowService, NamespaceService namespaceService, public TaskFormProcessor(WorkflowService workflowService, NamespaceService namespaceService,
DictionaryService dictionaryService, FieldProcessorRegistry fieldProcessorRegistry) DictionaryService dictionaryService, AuthenticationService authenticationService,
FieldProcessorRegistry fieldProcessorRegistry)
{ {
this.workflowService = workflowService; this.workflowService = workflowService;
this.namespaceService = namespaceService; this.namespaceService = namespaceService;
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
this.authenticationService = authenticationService;
this.fieldProcessorRegistry = fieldProcessorRegistry; this.fieldProcessorRegistry = fieldProcessorRegistry;
} }
/**
* Sets the authentication service
*
* @param authenticationService The AuthenticationService instance
*/
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.repo.forms.processor.workflow.AbstractWorkflowFormProcessor#getTypedItemForDecodedId(java.lang.String) * @see org.alfresco.repo.forms.processor.workflow.AbstractWorkflowFormProcessor#getTypedItemForDecodedId(java.lang.String)
*/ */
@@ -216,6 +233,7 @@ public class TaskFormProcessor extends AbstractWorkflowFormProcessor<WorkflowTas
protected ContentModelFormPersister<WorkflowTask> makeFormPersister(WorkflowTask item) protected ContentModelFormPersister<WorkflowTask> makeFormPersister(WorkflowTask item)
{ {
ContentModelItemData<WorkflowTask> itemData = makeItemData(item); ContentModelItemData<WorkflowTask> itemData = makeItemData(item);
return new TaskFormPersister(itemData, namespaceService, dictionaryService, workflowService, nodeService, LOGGER); return new TaskFormPersister(itemData, namespaceService, dictionaryService,
workflowService, nodeService, authenticationService, LOGGER);
} }
} }

View File

@@ -76,6 +76,7 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; 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.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowException; import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.service.cmr.workflow.WorkflowInstance; import org.alfresco.service.cmr.workflow.WorkflowInstance;
@@ -119,6 +120,7 @@ public class TaskFormProcessorTest extends TestCase
private TaskFormProcessor processor; private TaskFormProcessor processor;
private WorkflowTask task; private WorkflowTask task;
private NamespaceService namespaceService; private NamespaceService namespaceService;
private AuthenticationService authenticationService;
private WorkflowTask newTask; private WorkflowTask newTask;
private Map<QName, Serializable> actualProperties = null; private Map<QName, Serializable> actualProperties = null;
private Map<QName, List<NodeRef>> actualAdded= null; private Map<QName, List<NodeRef>> actualAdded= null;
@@ -523,6 +525,7 @@ public class TaskFormProcessorTest extends TestCase
nodeService = makeNodeService(); nodeService = makeNodeService();
DictionaryService dictionaryService = makeDictionaryService(); DictionaryService dictionaryService = makeDictionaryService();
namespaceService = makeNamespaceService(); namespaceService = makeNamespaceService();
authenticationService = makeAuthenticationService();
MockFieldProcessorRegistry fieldProcessorRegistry = new MockFieldProcessorRegistry(namespaceService, MockFieldProcessorRegistry fieldProcessorRegistry = new MockFieldProcessorRegistry(namespaceService,
dictionaryService); dictionaryService);
DefaultFieldProcessor defaultProcessor = makeDefaultFieldProcessor(dictionaryService); DefaultFieldProcessor defaultProcessor = makeDefaultFieldProcessor(dictionaryService);
@@ -537,6 +540,7 @@ public class TaskFormProcessorTest extends TestCase
processor1.setNodeService(nodeService); processor1.setNodeService(nodeService);
processor1.setNamespaceService(namespaceService); processor1.setNamespaceService(namespaceService);
processor1.setDictionaryService(dictionaryService); processor1.setDictionaryService(dictionaryService);
processor1.setAuthenticationService(authenticationService);
processor1.setFieldProcessorRegistry(fieldProcessorRegistry); processor1.setFieldProcessorRegistry(fieldProcessorRegistry);
return processor1; return processor1;
} }
@@ -670,6 +674,13 @@ public class TaskFormProcessorTest extends TestCase
return mock; return mock;
} }
private AuthenticationService makeAuthenticationService()
{
AuthenticationService mock = mock(AuthenticationService.class);
when(mock.getCurrentUserName()).thenReturn("admin");
return mock;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private WorkflowService makeWorkflowService() private WorkflowService makeWorkflowService()
{ {
@@ -707,6 +718,9 @@ public class TaskFormProcessorTest extends TestCase
when(service.endTask(eq(TASK_ID), anyString())) when(service.endTask(eq(TASK_ID), anyString()))
.thenReturn(newTask); .thenReturn(newTask);
when(service.isTaskEditable((WorkflowTask)any(), anyString())).thenReturn(true);
return service; return service;
} }