diff --git a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/conf/ProcessRuntimeAutoConfiguration.java b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/conf/ProcessRuntimeAutoConfiguration.java index d1b3261a1b46d95fb8b9625325af55e3e22a1654..7df48ae41edc31de046e25e67768e020f94d1ede 100644 --- a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/conf/ProcessRuntimeAutoConfiguration.java +++ b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/conf/ProcessRuntimeAutoConfiguration.java @@ -54,6 +54,7 @@ import org.activiti.core.common.spring.security.policies.ProcessSecurityPolicies import org.activiti.engine.ManagementService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; import org.activiti.engine.delegate.event.ActivitiEventType; import org.activiti.engine.impl.event.EventSubscriptionPayloadMappingProvider; import org.activiti.runtime.api.conf.impl.ProcessRuntimeConfigurationImpl; @@ -174,6 +175,7 @@ public class ProcessRuntimeAutoConfiguration { public ProcessRuntime processRuntime(RepositoryService repositoryService, APIProcessDefinitionConverter processDefinitionConverter, RuntimeService runtimeService, + TaskService taskService, ProcessSecurityPoliciesManager securityPoliciesManager, APIProcessInstanceConverter processInstanceConverter, APIVariableInstanceConverter variableInstanceConverter, @@ -185,6 +187,7 @@ public class ProcessRuntimeAutoConfiguration { return new ProcessRuntimeImpl(repositoryService, processDefinitionConverter, runtimeService, + taskService, securityPoliciesManager, processInstanceConverter, variableInstanceConverter, diff --git a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/impl/ProcessRuntimeImpl.java b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/impl/ProcessRuntimeImpl.java index 0d759c2e6e790e96a270f348e6a8ac1873928547..7126779b2c4bb3a6a9148ac13260eaee0d2a424b 100644 --- a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/impl/ProcessRuntimeImpl.java +++ b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/impl/ProcessRuntimeImpl.java @@ -58,8 +58,10 @@ import org.activiti.core.common.spring.security.policies.SecurityPolicyAccess; import org.activiti.engine.ActivitiObjectNotFoundException; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.activiti.engine.runtime.ProcessInstanceBuilder; +import org.activiti.engine.task.TaskQuery; import org.activiti.runtime.api.model.impl.APIDeploymentConverter; import org.activiti.runtime.api.model.impl.APIProcessDefinitionConverter; import org.activiti.runtime.api.model.impl.APIProcessInstanceConverter; @@ -78,6 +80,8 @@ public class ProcessRuntimeImpl implements ProcessRuntime { private final RuntimeService runtimeService; + private final TaskService taskService; + private final APIProcessInstanceConverter processInstanceConverter; private final APIVariableInstanceConverter variableInstanceConverter; @@ -97,6 +101,7 @@ public class ProcessRuntimeImpl implements ProcessRuntime { public ProcessRuntimeImpl(RepositoryService repositoryService, APIProcessDefinitionConverter processDefinitionConverter, RuntimeService runtimeService, + TaskService taskService, ProcessSecurityPoliciesManager securityPoliciesManager, APIProcessInstanceConverter processInstanceConverter, APIVariableInstanceConverter variableInstanceConverter, @@ -108,6 +113,7 @@ public class ProcessRuntimeImpl implements ProcessRuntime { this.repositoryService = repositoryService; this.processDefinitionConverter = processDefinitionConverter; this.runtimeService = runtimeService; + this.taskService = taskService; this.securityPoliciesManager = securityPoliciesManager; this.processInstanceConverter = processInstanceConverter; this.variableInstanceConverter = variableInstanceConverter; @@ -196,15 +202,9 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public ProcessInstance processInstance(String processInstanceId) { - org.activiti.engine.runtime.ProcessInstance internalProcessInstance = runtimeService - .createProcessInstanceQuery() - .processInstanceId(processInstanceId) - .singleResult(); - if (internalProcessInstance == null) { - throw new NotFoundException("Unable to find process instance for the given id:'" + processInstanceId + "'"); - } + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(processInstanceId); - if (!securityPoliciesManager.canRead(internalProcessInstance.getProcessDefinitionKey())) { + if (!canReadProcessInstance(internalProcessInstance)) { throw new ActivitiObjectNotFoundException("You cannot read the process instance with Id:'" + processInstanceId + "' due to security policies violation"); } return processInstanceConverter.from(internalProcessInstance); @@ -264,31 +264,27 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public ProcessInstance start(StartProcessPayload startProcessPayload) { - - return processInstanceConverter.from(this.createProcessInstanceBuilder(startProcessPayload).start()); } @Override public ProcessInstance startCreatedProcess(String processInstanceId, StartProcessPayload startProcessPayload) { - org.activiti.engine.runtime.ProcessInstance internalProcessInstance = runtimeService - .createProcessInstanceQuery() - .processInstanceId(processInstanceId) - .singleResult(); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(processInstanceId); + if (internalProcessInstance == null) { throw new NotFoundException("Unable to find process instance for the given id:'" + processInstanceId + "'"); } - if (!securityPoliciesManager.canRead(internalProcessInstance.getProcessDefinitionKey())) { - throw new ActivitiObjectNotFoundException("You cannot read the process instance with Id:'" + processInstanceId + "' due to security policies violation"); + if (!canWriteProcessInstance(internalProcessInstance)) { + throw new ActivitiObjectNotFoundException("You cannot start the process instance with Id:'" + processInstanceId + "' due to security policies violation"); } processVariablesValidator.checkStartProcessPayloadVariables(startProcessPayload, internalProcessInstance.getProcessDefinitionId()); return processInstanceConverter.from(runtimeService.startCreatedProcessInstance(internalProcessInstance, startProcessPayload.getVariables())); } @Override - public ProcessInstance create(CreateProcessInstancePayload startProcessPayload) { - return processInstanceConverter.from(createProcessInstanceBuilder(startProcessPayload).create()); + public ProcessInstance create(CreateProcessInstancePayload createProcessInstancePayload) { + return processInstanceConverter.from(createProcessInstanceBuilder(createProcessInstancePayload).create()); } private ProcessInstanceBuilder createProcessInstanceBuilder(StartProcessPayload startProcessPayload) { @@ -320,9 +316,9 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public ProcessInstance suspend(SuspendProcessPayload suspendProcessPayload) { - ProcessInstance processInstance = processInstance(suspendProcessPayload.getProcessInstanceId()); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(suspendProcessPayload.getProcessInstanceId()); - checkUserCanWrite(processInstance.getProcessDefinitionKey()); + checkUserCanWritePermissionOnProcessInstance(internalProcessInstance); runtimeService.suspendProcessInstanceById(suspendProcessPayload.getProcessInstanceId()); return processInstanceConverter.from(runtimeService.createProcessInstanceQuery().processInstanceId(suspendProcessPayload.getProcessInstanceId()).singleResult()); @@ -330,9 +326,9 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public ProcessInstance resume(ResumeProcessPayload resumeProcessPayload) { - ProcessInstance processInstance = processInstance(resumeProcessPayload.getProcessInstanceId()); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(resumeProcessPayload.getProcessInstanceId()); - checkUserCanWrite(processInstance.getProcessDefinitionKey()); + checkUserCanWritePermissionOnProcessInstance(internalProcessInstance); runtimeService.activateProcessInstanceById(resumeProcessPayload.getProcessInstanceId()); return processInstanceConverter.from(runtimeService.createProcessInstanceQuery() @@ -341,12 +337,14 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public ProcessInstance delete(DeleteProcessPayload deleteProcessPayload) { - ProcessInstanceImpl processInstance = (ProcessInstanceImpl) processInstance(deleteProcessPayload.getProcessInstanceId()); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(deleteProcessPayload.getProcessInstanceId()); - checkUserCanWrite(processInstance.getProcessDefinitionKey()); + checkUserCanWritePermissionOnProcessInstance(internalProcessInstance); runtimeService.deleteProcessInstance(deleteProcessPayload.getProcessInstanceId(), deleteProcessPayload.getReason()); + + ProcessInstanceImpl processInstance = (ProcessInstanceImpl) processInstanceConverter.from(internalProcessInstance); processInstance.setStatus(ProcessInstance.ProcessInstanceStatus.CANCELLED); return processInstance; } @@ -364,9 +362,9 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public void removeVariables(RemoveProcessVariablesPayload removeProcessVariablesPayload) { - ProcessInstanceImpl processInstance = (ProcessInstanceImpl) processInstance(removeProcessVariablesPayload.getProcessInstanceId()); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(removeProcessVariablesPayload.getProcessInstanceId()); - checkUserCanWrite(processInstance.getProcessDefinitionKey()); + checkUserCanWritePermissionOnProcessInstance(internalProcessInstance); runtimeService.removeVariables(removeProcessVariablesPayload.getProcessInstanceId(), removeProcessVariablesPayload.getVariableNames()); @@ -375,12 +373,12 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public void setVariables(SetProcessVariablesPayload setProcessVariablesPayload) { - ProcessInstanceImpl processInstance = (ProcessInstanceImpl) processInstance(setProcessVariablesPayload.getProcessInstanceId()); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(setProcessVariablesPayload.getProcessInstanceId()); - checkUserCanWrite(processInstance.getProcessDefinitionKey()); + checkUserCanWritePermissionOnProcessInstance(internalProcessInstance); processVariablesValidator.checkPayloadVariables(setProcessVariablesPayload, - processInstance.getProcessDefinitionId()); + internalProcessInstance.getProcessDefinitionId()); runtimeService.setVariables(setProcessVariablesPayload.getProcessInstanceId(), setProcessVariablesPayload.getVariables()); @@ -416,9 +414,9 @@ public class ProcessRuntimeImpl implements ProcessRuntime { @Override public ProcessInstance update(UpdateProcessPayload updateProcessPayload) { - ProcessInstance processInstance = processInstance(updateProcessPayload.getProcessInstanceId()); + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = internalProcessInstance(updateProcessPayload.getProcessInstanceId()); - checkUserCanWrite(processInstance.getProcessDefinitionKey()); + checkUserCanWritePermissionOnProcessInstance(internalProcessInstance); if (updateProcessPayload.getBusinessKey() != null) { runtimeService.updateBusinessKey(updateProcessPayload.getProcessInstanceId(), updateProcessPayload.getBusinessKey()); @@ -458,13 +456,20 @@ public class ProcessRuntimeImpl implements ProcessRuntime { return processInstance; } - private void checkUserCanWrite(String processDefinitionKey) { + private void checkUserCanWritePermissionOnProcessDefinition(String processDefinitionKey) { if (!securityPoliciesManager.canWrite(processDefinitionKey)) { throw new ActivitiForbiddenException("Operation not permitted for " + processDefinitionKey + " due security policy violation"); } } + private void checkUserCanWritePermissionOnProcessInstance(org.activiti.engine.runtime.ProcessInstance processInstance) { + + if (!canWriteProcessInstance(processInstance)) { + throw new ActivitiForbiddenException("Operation not permitted for on process instance " + processInstance.getProcessInstanceId() + " due security policy violation"); + } + } + protected ProcessDefinition getProcessDefinitionAndCheckUserHasRights(String processDefinitionId, String processDefinitionKey) { String checkId = processDefinitionKey != null ? processDefinitionKey : processDefinitionId; @@ -475,7 +480,7 @@ public class ProcessRuntimeImpl implements ProcessRuntime { throw new IllegalStateException("At least Process Definition Id or Key needs to be provided to start a process"); } - checkUserCanWrite(processDefinition.getKey()); + checkUserCanWritePermissionOnProcessDefinition(processDefinition.getKey()); return processDefinition; } @@ -491,4 +496,39 @@ public class ProcessRuntimeImpl implements ProcessRuntime { ); } + public org.activiti.engine.runtime.ProcessInstance internalProcessInstance(String processInstanceId) { + org.activiti.engine.runtime.ProcessInstance internalProcessInstance = runtimeService + .createProcessInstanceQuery() + .processInstanceId(processInstanceId) + .singleResult(); + + if (internalProcessInstance == null) { + throw new NotFoundException("Unable to find process instance for the given id:'" + processInstanceId + "'"); + } + return internalProcessInstance; + } + + private boolean canReadProcessInstance(org.activiti.engine.runtime.ProcessInstance processInstance) { + return securityPoliciesManager.canRead(processInstance.getProcessDefinitionKey()) && + (securityManager.getAuthenticatedUserId().equals(processInstance.getStartUserId()) || + isATaskAssigneeOrACandidate(processInstance.getProcessInstanceId())); + } + + private boolean canWriteProcessInstance(org.activiti.engine.runtime.ProcessInstance processInstance) { + return securityPoliciesManager.canWrite(processInstance.getProcessDefinitionKey()) && + securityManager.getAuthenticatedUserId().equals(processInstance.getStartUserId()); + } + + private boolean isATaskAssigneeOrACandidate(String processInstanceId) { + String authenticatedUserId = securityManager.getAuthenticatedUserId(); + TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstanceId); + taskQuery.or() + .taskCandidateOrAssigned(securityManager.getAuthenticatedUserId(), + securityManager.getAuthenticatedUserGroups()) + .taskOwner(authenticatedUserId) + .endOr(); + + return taskQuery.count() > 0; + } + } diff --git a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/ProcessRuntimeTestApp.java b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/ProcessRuntimeTestApp.java index 9bed7f986f3dbb9f1b75fb18524d286736d2ecb2..d6162b5badb3f2d3ad1e8c969938a350b56724aa 100644 --- a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/ProcessRuntimeTestApp.java +++ b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/ProcessRuntimeTestApp.java @@ -23,6 +23,7 @@ import org.activiti.core.common.spring.security.policies.ProcessSecurityPolicies import org.activiti.engine.ManagementService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -44,6 +45,11 @@ public class ProcessRuntimeTestApp { return mock(RuntimeService.class); } + @Bean + public TaskService taskService() { + return mock(TaskService.class); + } + @Bean public ManagementService managementService() { return mock(ManagementService.class); diff --git a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/impl/ProcessRuntimeImplTest.java b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/impl/ProcessRuntimeImplTest.java index c200e95a53606c495a316eec6fa18eb9301365f7..4ecafdf58b9a50d716c7a7fc7cbfcd6acda8b6dc 100644 --- a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/impl/ProcessRuntimeImplTest.java +++ b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/runtime/api/impl/ProcessRuntimeImplTest.java @@ -47,6 +47,7 @@ import org.activiti.api.runtime.shared.security.SecurityManager; import org.activiti.core.common.spring.security.policies.ProcessSecurityPoliciesManager; import org.activiti.engine.ActivitiObjectNotFoundException; import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; import org.activiti.engine.impl.RepositoryServiceImpl; import org.activiti.engine.impl.interceptor.CommandExecutor; import org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl; @@ -78,6 +79,9 @@ public class ProcessRuntimeImplTest { @Mock private RuntimeService runtimeService; + @Mock + private TaskService taskService; + @Mock private APIProcessInstanceConverter processInstanceConverter; @@ -105,6 +109,7 @@ public class ProcessRuntimeImplTest { processRuntime = spy(new ProcessRuntimeImpl(repositoryService, processDefinitionConverter, runtimeService, + taskService, securityPoliciesManager, processInstanceConverter, null, @@ -119,13 +124,15 @@ public class ProcessRuntimeImplTest { @Test public void updateShouldBeAbleToUpdateNameBusinessKey() { //given - ProcessInstanceImpl process = new ProcessInstanceImpl(); - process.setId("processId"); - process.setProcessDefinitionKey("processDefinitionKey"); + ExecutionEntityImpl internalProcessInstance = new ExecutionEntityImpl(); + internalProcessInstance.setId("processId"); + internalProcessInstance.setProcessDefinitionKey("processDefinitionKey"); + internalProcessInstance.setStartUserId("testuser"); - doReturn(process).when(processRuntime).processInstance("processId"); + doReturn(internalProcessInstance).when(processRuntime).internalProcessInstance("processId"); doReturn(true).when(securityPoliciesManager).canWrite("processDefinitionKey"); + doReturn("testuser").when(securityManager).getAuthenticatedUserId(); ProcessInstanceQuery processQuery = mock(ProcessInstanceQuery.class); doReturn(processQuery).when(processQuery).processInstanceId("processId"); @@ -135,6 +142,7 @@ public class ProcessRuntimeImplTest { doReturn(internalProcess).when(processQuery).singleResult(); + UpdateProcessPayload updateProcessPayload = ProcessPayloadBuilder.update() .withProcessInstanceId("processId") .withBusinessKey("businessKey") @@ -276,7 +284,8 @@ public class ProcessRuntimeImplTest { ProcessInstanceQuery processQuery = mock(ProcessInstanceQuery.class); doReturn(processQuery).when(processQuery).processInstanceId(processInstanceId); doReturn(processQuery).when(runtimeService).createProcessInstanceQuery(); - org.activiti.engine.runtime.ProcessInstance internalProcess = new ExecutionEntityImpl(); + ExecutionEntityImpl internalProcess = new ExecutionEntityImpl(); + internalProcess.setStartUserId("testuser"); internalProcess.setAppVersion(1); doReturn(internalProcess).when(processQuery).singleResult(); when(runtimeService.startCreatedProcessInstance(internalProcess, new HashMap<>())).thenReturn(internalProcess); @@ -284,7 +293,8 @@ public class ProcessRuntimeImplTest { apiProcessInstance.setBusinessKey("business-result"); apiProcessInstance.setId("999-999"); given(processInstanceConverter.from(internalProcess)).willReturn(apiProcessInstance); - given(securityPoliciesManager.canRead(any())).willReturn(true); + given(securityPoliciesManager.canWrite(any())).willReturn(true); + doReturn("testuser").when(securityManager).getAuthenticatedUserId(); //when StartProcessPayload payload = new StartProcessPayload(); diff --git a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/spring/process/ProcessVariablesInitiatorIT.java b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/spring/process/ProcessVariablesInitiatorIT.java index 8bdf167b6b7934dd09c3df2d3a509536fb8a9b5e..62e84ed16e9ed91bc7786b863471b7c4f8e0be29 100644 --- a/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/spring/process/ProcessVariablesInitiatorIT.java +++ b/activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/test/java/org/activiti/spring/process/ProcessVariablesInitiatorIT.java @@ -28,10 +28,7 @@ import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; import org.activiti.api.runtime.shared.identity.UserGroupManager; -import org.activiti.engine.ActivitiException; -import org.activiti.engine.ManagementService; -import org.activiti.engine.RepositoryService; -import org.activiti.engine.RuntimeService; +import org.activiti.engine.*; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.spring.process.model.ProcessExtensionModel; import org.junit.jupiter.api.BeforeEach; @@ -62,6 +59,9 @@ public class ProcessVariablesInitiatorIT { @MockBean private RuntimeService runtimeService; + @MockBean + private TaskService taskService; + @MockBean private ManagementService managementService; diff --git a/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/HistoryConfigurationTest.java b/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/HistoryConfigurationTest.java index 7ff5faa85e65a6a63010793ff936f46ed203463b..202fdb2963db37584d54eb02db9be3777b661535 100644 --- a/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/HistoryConfigurationTest.java +++ b/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/HistoryConfigurationTest.java @@ -27,6 +27,7 @@ import org.activiti.core.common.spring.security.policies.ProcessSecurityPolicies import org.activiti.engine.HistoryService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; import org.activiti.runtime.api.impl.ProcessAdminRuntimeImpl; import org.activiti.runtime.api.impl.ProcessRuntimeImpl; import org.activiti.runtime.api.impl.ProcessVariablesPayloadValidator; @@ -68,6 +69,9 @@ public class HistoryConfigurationTest { @Autowired private RuntimeService runtimeService; + @Autowired + private TaskService taskService; + @Autowired private ProcessSecurityPoliciesManager securityPoliciesManager; @@ -108,6 +112,7 @@ public class HistoryConfigurationTest { spy(new ProcessRuntimeImpl(repositoryService, processDefinitionConverter, runtimeService, + taskService, securityPoliciesManager, processInstanceConverter, variableInstanceConverter, diff --git a/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/process/ProcessRuntimeIT.java b/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/process/ProcessRuntimeIT.java index 698ace2c4f64e297bbc97fd1a92eb30e6522b294..f69db09f69a6a28f15bca21ef42a403fe5694ff8 100644 --- a/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/process/ProcessRuntimeIT.java +++ b/activiti-core/activiti-spring-boot-starter/src/test/java/org/activiti/spring/boot/process/ProcessRuntimeIT.java @@ -16,6 +16,7 @@ package org.activiti.spring.boot.process; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.groups.Tuple.tuple; import static org.mockito.Mockito.spy; @@ -43,10 +44,12 @@ import org.activiti.api.runtime.shared.query.Pageable; import org.activiti.api.task.model.Task; import org.activiti.api.task.model.builders.TaskPayloadBuilder; import org.activiti.api.task.runtime.TaskRuntime; +import org.activiti.core.common.spring.security.policies.ActivitiForbiddenException; import org.activiti.core.common.spring.security.policies.ProcessSecurityPoliciesManager; import org.activiti.engine.ActivitiIllegalArgumentException; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; import org.activiti.runtime.api.impl.ProcessAdminRuntimeImpl; import org.activiti.runtime.api.impl.ProcessRuntimeImpl; import org.activiti.runtime.api.impl.ProcessVariablesPayloadValidator; @@ -75,6 +78,7 @@ public class ProcessRuntimeIT { private static final String SUB_PROCESS = "subProcess"; private static final String SUPER_PROCESS = "superProcess"; + private static final String TWO_TASKS_PROCESS = "twoTaskProcess"; private static final Pageable PAGEABLE = Pageable.of(0, 50); public static final String CATEGORIZE_HUMAN_PROCESS_CATEGORY = "test-category"; @@ -97,6 +101,9 @@ public class ProcessRuntimeIT { @Autowired private RuntimeService runtimeService; + @Autowired + private TaskService taskService; + @Autowired private ProcessSecurityPoliciesManager securityPoliciesManager; @@ -146,6 +153,7 @@ public class ProcessRuntimeIT { processRuntimeMock = spy(new ProcessRuntimeImpl(repositoryService, processDefinitionConverter, runtimeService, + taskService, securityPoliciesManager, processInstanceConverter, variableInstanceConverter, @@ -877,7 +885,7 @@ public class ProcessRuntimeIT { } @Test - public void should_not_returnProcessesToNonInitiatorUser() { + public void should_not_returnProcessesToNonInitiatorAndNotTaskInvolvedUser() { //given processRuntime.start(ProcessPayloadBuilder.start() .withProcessDefinitionKey(CATEGORIZE_HUMAN_PROCESS) @@ -894,4 +902,60 @@ public class ProcessRuntimeIT { assertThat(processInstancePage).isNotNull(); assertThat(processInstancePage.getContent()).isEmpty(); } + + @Test + public void should_returnProcessToTaskAssignee() { + //given + ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start() + .withProcessDefinitionKey(SINGLE_TASK_PROCESS) + .build()); + + securityUtil.logInAs("garth"); + + //when + processInstance = processRuntime.processInstance(processInstance.getId()); + + assertThat(processInstance.getInitiator()).isEqualTo("user"); + } + + @Test + public void should_returnProcessToTaskCandidate() { + //given + ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start() + .withProcessDefinitionKey(TWO_TASKS_PROCESS) + .build()); + + securityUtil.logInAs("garth"); + + //when + processInstance = processRuntime.processInstance(processInstance.getId()); + + assertThat(processInstance.getInitiator()).isEqualTo("user"); + } + + @Test + public void should_ForbidCancelingProcessInstanceUsingTaskInvolvedUser() { + //given + ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start() + .withProcessDefinitionKey(SINGLE_TASK_PROCESS) + .build()); + + securityUtil.logInAs("garth"); + + assertThatThrownBy(() -> { processRuntime.delete(ProcessPayloadBuilder.delete(processInstance)); }) + .isInstanceOf(ActivitiForbiddenException.class); + } + + @Test + public void should_CancelProcessInstanceUsingInitiatorUser() { + //given + ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start() + .withProcessDefinitionKey(SINGLE_TASK_PROCESS) + .build()); + + ProcessInstance deletedProcessInstance = processRuntime.delete(ProcessPayloadBuilder.delete(processInstance)); + + assertThat(deletedProcessInstance).isNotNull(); + assertThat(deletedProcessInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.CANCELLED); + } }