mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged HEAD-BUG-FIX (5.1/Cloud) to HEAD (5.0/Cloud)
85943: Merged V4.2-BUG-FIX (4.2.4) to HEAD-BUG-FIX (5.0/Cloud) 85883: Merged DEV to V4.2-BUG-FIX (4.2.4) 85645 : MNT-12382 : No access to process items of (unclaimed) pooled group task via Activiti REST API if user being member of assigned candidate group is not in administrators group - Add unit test 85718 : MNT-12382 : No access to process items of (unclaimed) pooled group task via Activiti REST API if user being member of assigned candidate group is not in administrators group - Add check for unclaimed process - Add unit test 85771 : MNT-12382 : No access to process items of (unclaimed) pooled group task via Activiti REST API if user being member of assigned candidate group is not in administrators group - Added check for membership in the assigned group for unclaimed pooled workflow git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@94521 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -17,6 +17,7 @@ import org.activiti.engine.ProcessEngine;
|
||||
import org.activiti.engine.history.HistoricTaskInstance;
|
||||
import org.activiti.engine.history.HistoricTaskInstanceQuery;
|
||||
import org.activiti.engine.history.HistoricVariableInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
@@ -50,6 +51,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.beanutils.ConversionException;
|
||||
@@ -493,13 +495,26 @@ public class WorkflowRestImpl
|
||||
return variableInstances;
|
||||
}
|
||||
|
||||
if (authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser()))
|
||||
String username = AuthenticationUtil.getRunAsUser();
|
||||
if (authorityService.isAdminAuthority(username))
|
||||
{
|
||||
// Admin is allowed to read all processes in the current tenant
|
||||
return variableInstances;
|
||||
}
|
||||
else
|
||||
{
|
||||
// MNT-12382 check for membership in the assigned group
|
||||
ActivitiScriptNode group = (ActivitiScriptNode) variableMap.get("bpm_groupAssignee");
|
||||
if (group != null)
|
||||
{
|
||||
// check that the process is unclaimed
|
||||
Task task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processId).singleResult();
|
||||
if ((task != null) && (task.getAssignee() == null) && isUserInGroup(username, group.getNodeRef()))
|
||||
{
|
||||
return variableInstances;
|
||||
}
|
||||
}
|
||||
|
||||
// If non-admin user, involvement in the task is required (either owner, assignee or externally involved).
|
||||
HistoricTaskInstanceQuery query = activitiProcessEngine.getHistoryService()
|
||||
.createHistoricTaskInstanceQuery()
|
||||
@@ -550,4 +565,16 @@ public class WorkflowRestImpl
|
||||
{
|
||||
this.activitiWorkflowEngine = activitiWorkflowEngine;
|
||||
}
|
||||
|
||||
private boolean isUserInGroup(String username, NodeRef group)
|
||||
{
|
||||
// Get the group name
|
||||
String groupName = (String) nodeService.getProperty(group, ContentModel.PROP_AUTHORITY_NAME);
|
||||
|
||||
// Get all group members
|
||||
Set<String> groupMembers = authorityService.getContainedAuthorities(AuthorityType.USER, groupName, false);
|
||||
|
||||
// Check if the user is a group member.
|
||||
return (groupMembers != null) && groupMembers.contains(username);
|
||||
}
|
||||
}
|
||||
|
@@ -24,24 +24,33 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.activiti.engine.TaskService;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.tenant.TenantUtil;
|
||||
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
|
||||
import org.alfresco.rest.api.tests.PersonInfo;
|
||||
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
|
||||
import org.alfresco.rest.api.tests.RepoService.TestPerson;
|
||||
import org.alfresco.rest.api.tests.RepoService.TestSite;
|
||||
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiException;
|
||||
import org.alfresco.rest.api.tests.client.RequestContext;
|
||||
import org.alfresco.rest.api.tests.client.data.Document;
|
||||
import org.alfresco.rest.api.tests.client.data.MemberOfSite;
|
||||
import org.alfresco.rest.api.tests.client.data.SiteRole;
|
||||
import org.alfresco.rest.workflow.api.model.ProcessInfo;
|
||||
import org.alfresco.rest.workflow.api.model.Variable;
|
||||
import org.alfresco.rest.workflow.api.tests.WorkflowApiClient.ProcessesClient;
|
||||
@@ -49,6 +58,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||
import org.alfresco.util.ISO8601DateFormat;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.junit.experimental.categories.Category;
|
||||
@@ -1285,6 +1295,110 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMNT12382() throws Exception
|
||||
{
|
||||
currentNetwork = getTestFixture().getRandomNetwork();
|
||||
TestPerson initiator = currentNetwork.getPeople().get(0);
|
||||
RequestContext requestContext = new RequestContext(currentNetwork.getId(), initiator.getId());
|
||||
publicApiClient.setRequestContext(requestContext);
|
||||
ProcessInfo processInfo = startReviewPooledProcess(requestContext);
|
||||
|
||||
final List<TestPerson> persons = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<List<TestPerson>>()
|
||||
{
|
||||
@SuppressWarnings("synthetic-access")
|
||||
public List<TestPerson> execute() throws Throwable
|
||||
{
|
||||
ArrayList<TestPerson> persons = new ArrayList<TestPerson>();
|
||||
persons.add(currentNetwork.createUser(new PersonInfo("Maxim0", "Bobyleu0", "maxim0.bobyleu0", "password", null, "skype", "location", "telephone", "mob", "instant", "google")));
|
||||
persons.add(currentNetwork.createUser(new PersonInfo("Maxim1", "Bobyleu1", "maxim1.bobyleu1", "password", null, "skype", "location", "telephone", "mob", "instant", "google")));
|
||||
persons.add(currentNetwork.createUser(new PersonInfo("Maxim2", "Bobyleu2", "maxim2.bobyleu2", "password", null, "skype", "location", "telephone", "mob", "instant", "google")));
|
||||
return persons;
|
||||
}
|
||||
}, false, true);
|
||||
|
||||
final MemberOfSite memberOfSite = currentNetwork.getSiteMemberships(initiator.getId()).get(0);
|
||||
|
||||
// startReviewPooledProcess() uses initiator's site id and role name for construct bpm_groupAssignee, thus we need appropriate things for created users
|
||||
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
TestSite initiatorSite = (TestSite) memberOfSite.getSite();
|
||||
initiatorSite.inviteToSite(persons.get(0).getId(), memberOfSite.getRole());
|
||||
initiatorSite.inviteToSite(persons.get(1).getId(), memberOfSite.getRole());
|
||||
// this user wouldn't be in group
|
||||
initiatorSite.inviteToSite(persons.get(2).getId(), SiteRole.SiteConsumer == memberOfSite.getRole() ? SiteRole.SiteCollaborator : SiteRole.SiteConsumer);
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getAdminUserName(), currentNetwork.getId());
|
||||
|
||||
return null;
|
||||
}
|
||||
}, false, true);
|
||||
|
||||
String processId = processInfo.getId();
|
||||
|
||||
// getting process items by workflow initiator
|
||||
ProcessesClient processesClient = publicApiClient.processesClient();
|
||||
JSONObject initiatorItems = processesClient.findProcessItems(processId);
|
||||
|
||||
// getting unclaimed process items by user in group
|
||||
requestContext = new RequestContext(currentNetwork.getId(), persons.get(0).getId());
|
||||
publicApiClient.setRequestContext(requestContext);
|
||||
JSONObject items1 = processesClient.findProcessItems(processId);
|
||||
assertEquals(initiatorItems.toJSONString(), items1.toJSONString());
|
||||
|
||||
// getting unclaimed process items by user not in group
|
||||
requestContext = new RequestContext(currentNetwork.getId(), persons.get(2).getId());
|
||||
publicApiClient.setRequestContext(requestContext);
|
||||
try
|
||||
{
|
||||
JSONObject items2 = processesClient.findProcessItems(processId);
|
||||
fail("User not from group should not see items.");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
// expected
|
||||
assertEquals(403, e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
|
||||
// claim task
|
||||
TaskService taskService = activitiProcessEngine.getTaskService();
|
||||
Task task = taskService.createTaskQuery().processInstanceId(processId).singleResult();
|
||||
TestPerson assignee = persons.get(1);
|
||||
taskService.setAssignee(task.getId(), assignee.getId());
|
||||
|
||||
// getting claimed process items by assignee
|
||||
requestContext = new RequestContext(currentNetwork.getId(), assignee.getId());
|
||||
publicApiClient.setRequestContext(requestContext);
|
||||
JSONObject items3 = processesClient.findProcessItems(processId);
|
||||
assertEquals(initiatorItems.toJSONString(), items3.toJSONString());
|
||||
|
||||
// getting claimed process items by user in group
|
||||
requestContext = new RequestContext(currentNetwork.getId(), persons.get(0).getId());
|
||||
publicApiClient.setRequestContext(requestContext);
|
||||
try
|
||||
{
|
||||
JSONObject items4 = processesClient.findProcessItems(processId);
|
||||
fail("User from group should not see items for claimed task by another user.");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
// expected
|
||||
assertEquals(403, e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
finally
|
||||
{
|
||||
cleanupProcessInstance(processId);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProcessItems() throws Exception
|
||||
{
|
||||
|
Reference in New Issue
Block a user