mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-3363 Support inheritedBy in GET rule sets. (#1387)
* ACS-3363 E2E test for inheritedBy. * ACS-3363 Support optional inheritedBy field in GET rule sets. * ACS-3363 Update to new version of TAS REST API. * ACS-3363 Remove user from private site before calling method under test.
This commit is contained in:
@@ -25,17 +25,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.rules;
|
package org.alfresco.rest.rules;
|
||||||
|
|
||||||
|
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
|
||||||
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
|
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
|
||||||
|
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModelWithModifiedValues;
|
||||||
import static org.alfresco.utility.report.log.Step.STEP;
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
import static org.springframework.http.HttpStatus.OK;
|
import static org.springframework.http.HttpStatus.OK;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import org.alfresco.rest.RestTest;
|
import org.alfresco.rest.RestTest;
|
||||||
import org.alfresco.rest.model.RestRuleModel;
|
import org.alfresco.rest.model.RestRuleModel;
|
||||||
|
import org.alfresco.rest.model.RestRuleSetLinkModel;
|
||||||
import org.alfresco.rest.model.RestRuleSetModel;
|
import org.alfresco.rest.model.RestRuleSetModel;
|
||||||
import org.alfresco.rest.model.RestRuleSetModelsCollection;
|
import org.alfresco.rest.model.RestRuleSetModelsCollection;
|
||||||
import org.alfresco.rest.model.RestRuleSettingsModel;
|
import org.alfresco.rest.model.RestRuleSettingsModel;
|
||||||
|
import org.alfresco.rest.requests.coreAPI.RestCoreAPI;
|
||||||
|
import org.alfresco.utility.constants.UserRole;
|
||||||
import org.alfresco.utility.model.FolderModel;
|
import org.alfresco.utility.model.FolderModel;
|
||||||
import org.alfresco.utility.model.SiteModel;
|
import org.alfresco.utility.model.SiteModel;
|
||||||
import org.alfresco.utility.model.TestGroup;
|
import org.alfresco.utility.model.TestGroup;
|
||||||
@@ -248,4 +257,78 @@ public class GetRuleSetsTests extends RestTest
|
|||||||
ruleSet.assertThat().field("owningFolder").is(ruleFolder.getNodeRef())
|
ruleSet.assertThat().field("owningFolder").is(ruleFolder.getNodeRef())
|
||||||
.assertThat().field("id").is(ruleSetId);
|
.assertThat().field("id").is(ruleSetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we can find out the id of any folders that inherit a rule set.
|
||||||
|
* <p>
|
||||||
|
* The test checks several different situations:
|
||||||
|
* <pre>
|
||||||
|
* folder --[owns]-> rule set
|
||||||
|
* +- publicFolder --[inherits]-> rule set (user has access)
|
||||||
|
* +- privateFolder --[inherits]-> rule set (user does not have access)
|
||||||
|
* +- publicGrandchild --[inherits]-> rule set (user has access again)
|
||||||
|
* +- nonInheritingFolder (inheritance should be prevented)
|
||||||
|
* +- linkingFolder --[links]-> rule set (not inherited)
|
||||||
|
* +- descendantFolder --[inherits]-> rule set (inherited via link)
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void getRuleSetAndInheritedBy()
|
||||||
|
{
|
||||||
|
STEP("Create a site owned by admin and add user as a contributor");
|
||||||
|
SiteModel siteModel = dataSite.usingAdmin().createPrivateRandomSite();
|
||||||
|
dataUser.addUserToSite(user, siteModel, UserRole.SiteContributor);
|
||||||
|
|
||||||
|
STEP("Create the folder structure");
|
||||||
|
FolderModel folder = dataContent.usingUser(user).usingSite(siteModel).createFolder();
|
||||||
|
FolderModel publicFolder = dataContent.usingUser(user).usingResource(folder).createFolder();
|
||||||
|
FolderModel privateFolder = dataContent.usingAdmin().usingResource(folder).createFolder();
|
||||||
|
dataContent.usingAdmin().usingResource(privateFolder).setInheritPermissions(false);
|
||||||
|
// Create the grandchild with user and use admin to move it under the private folder.
|
||||||
|
FolderModel publicGrandchild = dataContent.usingUser(user).usingSite(siteModel).createFolder();
|
||||||
|
coreAPIForAdmin().usingActions().executeAction("move", publicGrandchild, ImmutableMap.of("destination-folder", "workspace://SpacesStore/" + privateFolder.getNodeRef()));
|
||||||
|
// Create the non-inheriting folder.
|
||||||
|
FolderModel nonInheritingFolder = dataContent.usingUser(user).usingResource(folder).createFolder();
|
||||||
|
RestRuleSettingsModel nonInheriting = new RestRuleSettingsModel();
|
||||||
|
nonInheriting.setKey(IS_INHERITANCE_ENABLED);
|
||||||
|
nonInheriting.setValue(false);
|
||||||
|
coreAPIForUser().usingNode(nonInheritingFolder).usingIsInheritanceEnabledRuleSetting().updateSetting(nonInheriting);
|
||||||
|
// Create a child that will link to the rule and a child of that to inherit via the link.
|
||||||
|
FolderModel linkingFolder = dataContent.usingUser(user).usingResource(nonInheritingFolder).createFolder();
|
||||||
|
FolderModel descendantFolder = dataContent.usingUser(user).usingResource(linkingFolder).createFolder();
|
||||||
|
|
||||||
|
STEP("Create an inheritable rule in the folder and get the rule set id.");
|
||||||
|
RestRuleModel ruleModel = createRuleModelWithModifiedValues();
|
||||||
|
coreAPIForUser().usingNode(folder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
RestRuleSetModelsCollection ruleSets = coreAPIForUser().usingNode(folder).getListOfRuleSets();
|
||||||
|
String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
|
||||||
|
|
||||||
|
STEP("Create the link to the rule from the linking folder");
|
||||||
|
RestRuleSetLinkModel ruleSetLink = new RestRuleSetLinkModel();
|
||||||
|
ruleSetLink.setId(folder.getNodeRef());
|
||||||
|
coreAPIForUser().usingNode(linkingFolder).createRuleLink(ruleSetLink);
|
||||||
|
|
||||||
|
STEP("Remove the user from the site");
|
||||||
|
dataUser.removeUserFromSite(user, siteModel);
|
||||||
|
|
||||||
|
STEP("Get the rule set and inheriting folders");
|
||||||
|
RestRuleSetModel ruleSet = coreAPIForUser().usingNode(folder)
|
||||||
|
.include("inheritedBy")
|
||||||
|
.getRuleSet(ruleSetId);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(OK);
|
||||||
|
List<String> expectedInheritors = List.of(publicFolder.getNodeRef(), descendantFolder.getNodeRef(), publicGrandchild.getNodeRef());
|
||||||
|
ruleSet.assertThat().field("inheritedBy").is(expectedInheritors)
|
||||||
|
.assertThat().field("id").is(ruleSetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RestCoreAPI coreAPIForUser()
|
||||||
|
{
|
||||||
|
return restClient.authenticateUser(user).withCoreAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RestCoreAPI coreAPIForAdmin()
|
||||||
|
{
|
||||||
|
return restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
pom.xml
2
pom.xml
@@ -123,7 +123,7 @@
|
|||||||
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
|
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
|
||||||
<dependency.tas-utility.version>3.0.49</dependency.tas-utility.version>
|
<dependency.tas-utility.version>3.0.49</dependency.tas-utility.version>
|
||||||
<dependency.rest-assured.version>5.1.1</dependency.rest-assured.version>
|
<dependency.rest-assured.version>5.1.1</dependency.rest-assured.version>
|
||||||
<dependency.tas-restapi.version>1.115</dependency.tas-restapi.version>
|
<dependency.tas-restapi.version>1.117</dependency.tas-restapi.version>
|
||||||
<dependency.tas-cmis.version>1.32</dependency.tas-cmis.version>
|
<dependency.tas-cmis.version>1.32</dependency.tas-cmis.version>
|
||||||
<dependency.tas-email.version>1.9</dependency.tas-email.version>
|
<dependency.tas-email.version>1.9</dependency.tas-email.version>
|
||||||
<dependency.tas-webdav.version>1.7</dependency.tas-webdav.version>
|
<dependency.tas-webdav.version>1.7</dependency.tas-webdav.version>
|
||||||
|
@@ -36,6 +36,7 @@ import org.alfresco.service.Experimental;
|
|||||||
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.rule.RuleService;
|
||||||
|
|
||||||
/** Responsible for converting a NodeRef into a {@link RuleSet} object. */
|
/** Responsible for converting a NodeRef into a {@link RuleSet} object. */
|
||||||
@Experimental
|
@Experimental
|
||||||
@@ -43,7 +44,10 @@ public class RuleSetLoader
|
|||||||
{
|
{
|
||||||
protected static final String OWNING_FOLDER = "owningFolder";
|
protected static final String OWNING_FOLDER = "owningFolder";
|
||||||
protected static final String INCLUSION_TYPE = "inclusionType";
|
protected static final String INCLUSION_TYPE = "inclusionType";
|
||||||
|
protected static final String INHERITED_BY = "inheritedBy";
|
||||||
|
public static final int MAX_INHERITED_BY_SIZE = 100;
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
private RuleService ruleService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a rule set for the given node ref.
|
* Load a rule set for the given node ref.
|
||||||
@@ -79,12 +83,26 @@ public class RuleSetLoader
|
|||||||
ruleSet.setInclusionType(linked ? LINKED : INHERITED);
|
ruleSet.setInclusionType(linked ? LINKED : INHERITED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (includes.contains(INHERITED_BY))
|
||||||
|
{
|
||||||
|
ruleSet.setInheritedBy(loadInheritedBy(ruleSetNodeRef));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ruleSet;
|
return ruleSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<NodeRef> loadInheritedBy(NodeRef ruleSetNodeRef)
|
||||||
|
{
|
||||||
|
return ruleService.getFoldersInheritingRuleSet(ruleSetNodeRef, MAX_INHERITED_BY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
public void setNodeService(NodeService nodeService)
|
public void setNodeService(NodeService nodeService)
|
||||||
{
|
{
|
||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRuleService(RuleService ruleService)
|
||||||
|
{
|
||||||
|
this.ruleService = ruleService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.model.rules;
|
package org.alfresco.rest.api.model.rules;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ public class RuleSet
|
|||||||
private String id;
|
private String id;
|
||||||
private NodeRef owningFolder;
|
private NodeRef owningFolder;
|
||||||
private InclusionType inclusionType;
|
private InclusionType inclusionType;
|
||||||
|
private List<NodeRef> inheritedBy;
|
||||||
|
|
||||||
public static RuleSet of(String id)
|
public static RuleSet of(String id)
|
||||||
{
|
{
|
||||||
@@ -86,6 +88,16 @@ public class RuleSet
|
|||||||
this.inclusionType = inclusionType;
|
this.inclusionType = inclusionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<NodeRef> getInheritedBy()
|
||||||
|
{
|
||||||
|
return inheritedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInheritedBy(List<NodeRef> inheritedBy)
|
||||||
|
{
|
||||||
|
this.inheritedBy = inheritedBy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
@@ -94,6 +106,7 @@ public class RuleSet
|
|||||||
.add("id='" + id + "'")
|
.add("id='" + id + "'")
|
||||||
.add("owningFolder='" + owningFolder + "'")
|
.add("owningFolder='" + owningFolder + "'")
|
||||||
.add("inclusionType='" + inclusionType + "'")
|
.add("inclusionType='" + inclusionType + "'")
|
||||||
|
.add("inheritedBy='" + inheritedBy + "'")
|
||||||
.toString()
|
.toString()
|
||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
@@ -108,13 +121,14 @@ public class RuleSet
|
|||||||
RuleSet ruleSet = (RuleSet) o;
|
RuleSet ruleSet = (RuleSet) o;
|
||||||
return Objects.equals(id, ruleSet.id)
|
return Objects.equals(id, ruleSet.id)
|
||||||
&& Objects.equals(owningFolder, ruleSet.owningFolder)
|
&& Objects.equals(owningFolder, ruleSet.owningFolder)
|
||||||
&& inclusionType == ruleSet.inclusionType;
|
&& inclusionType == ruleSet.inclusionType
|
||||||
|
&& Objects.equals(inheritedBy, ruleSet.inheritedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
return Objects.hash(id, owningFolder, inclusionType);
|
return Objects.hash(id, owningFolder, inclusionType, inheritedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder()
|
public static Builder builder()
|
||||||
@@ -127,6 +141,7 @@ public class RuleSet
|
|||||||
private String id;
|
private String id;
|
||||||
private NodeRef owningFolder;
|
private NodeRef owningFolder;
|
||||||
private InclusionType inclusionType;
|
private InclusionType inclusionType;
|
||||||
|
private List<NodeRef> inheritedBy;
|
||||||
|
|
||||||
public Builder id(String id)
|
public Builder id(String id)
|
||||||
{
|
{
|
||||||
@@ -146,12 +161,19 @@ public class RuleSet
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder inheritedBy(List<NodeRef> inheritedBy)
|
||||||
|
{
|
||||||
|
this.inheritedBy = inheritedBy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public RuleSet create()
|
public RuleSet create()
|
||||||
{
|
{
|
||||||
final RuleSet ruleSet = new RuleSet();
|
final RuleSet ruleSet = new RuleSet();
|
||||||
ruleSet.setId(id);
|
ruleSet.setId(id);
|
||||||
ruleSet.setOwningFolder(owningFolder);
|
ruleSet.setOwningFolder(owningFolder);
|
||||||
ruleSet.setInclusionType(inclusionType);
|
ruleSet.setInclusionType(inclusionType);
|
||||||
|
ruleSet.setInheritedBy(inheritedBy);
|
||||||
return ruleSet;
|
return ruleSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -863,6 +863,7 @@
|
|||||||
|
|
||||||
<bean id="ruleSetLoader" class="org.alfresco.rest.api.impl.rules.RuleSetLoader">
|
<bean id="ruleSetLoader" class="org.alfresco.rest.api.impl.rules.RuleSetLoader">
|
||||||
<property name="nodeService" ref="NodeService" />
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
<property name="ruleService" ref="RuleService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="ruleSets" class="org.alfresco.rest.api.impl.rules.RuleSetsImpl">
|
<bean id="ruleSets" class="org.alfresco.rest.api.impl.rules.RuleSetsImpl">
|
||||||
|
@@ -26,11 +26,14 @@
|
|||||||
package org.alfresco.rest.api.impl.rules;
|
package org.alfresco.rest.api.impl.rules;
|
||||||
|
|
||||||
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
|
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
|
||||||
|
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INHERITED_BY;
|
||||||
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.OWNING_FOLDER;
|
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.OWNING_FOLDER;
|
||||||
import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
|
import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
|
||||||
import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
|
import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
|
||||||
import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
|
import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
|
||||||
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -41,6 +44,7 @@ import org.alfresco.service.Experimental;
|
|||||||
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.rule.RuleService;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -66,6 +70,8 @@ public class RuleSetLoaderTest extends TestCase
|
|||||||
@Mock
|
@Mock
|
||||||
private NodeService nodeServiceMock;
|
private NodeService nodeServiceMock;
|
||||||
@Mock
|
@Mock
|
||||||
|
private RuleService ruleServiceMock;
|
||||||
|
@Mock
|
||||||
private ChildAssociationRef ruleSetAssociationMock;
|
private ChildAssociationRef ruleSetAssociationMock;
|
||||||
@Mock
|
@Mock
|
||||||
private ChildAssociationRef linkAssociationMock;
|
private ChildAssociationRef linkAssociationMock;
|
||||||
@@ -79,6 +85,8 @@ public class RuleSetLoaderTest extends TestCase
|
|||||||
|
|
||||||
given(linkAssociationMock.getParentRef()).willReturn(LINKING_FOLDER);
|
given(linkAssociationMock.getParentRef()).willReturn(LINKING_FOLDER);
|
||||||
given(nodeServiceMock.getParentAssocs(RULE_SET_NODE)).willReturn(List.of(ruleSetAssociationMock, linkAssociationMock));
|
given(nodeServiceMock.getParentAssocs(RULE_SET_NODE)).willReturn(List.of(ruleSetAssociationMock, linkAssociationMock));
|
||||||
|
|
||||||
|
given(ruleServiceMock.getFoldersInheritingRuleSet(eq(RULE_SET_NODE), anyInt())).willReturn(List.of(INHERITING_FOLDER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -130,4 +138,14 @@ public class RuleSetLoaderTest extends TestCase
|
|||||||
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(INHERITED).create();
|
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(INHERITED).create();
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadRuleSet_inheritedBy()
|
||||||
|
{
|
||||||
|
// Call the method under test.
|
||||||
|
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, INHERITING_FOLDER, List.of(INHERITED_BY));
|
||||||
|
|
||||||
|
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inheritedBy(List.of(INHERITING_FOLDER)).create();
|
||||||
|
assertEquals(expected, actual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,14 +25,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rule;
|
package org.alfresco.repo.rule;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
|
||||||
import static org.alfresco.repo.rule.RuleModel.ASPECT_IGNORE_INHERITED_RULES;
|
import static org.alfresco.repo.rule.RuleModel.ASPECT_IGNORE_INHERITED_RULES;
|
||||||
import static org.alfresco.repo.rule.RuleModel.ASSOC_RULE_FOLDER;
|
import static org.alfresco.repo.rule.RuleModel.ASSOC_RULE_FOLDER;
|
||||||
|
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
|
||||||
|
import static org.alfresco.service.namespace.RegexQNamePattern.MATCH_ALL;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -70,7 +75,6 @@ import org.alfresco.service.cmr.rule.Rule;
|
|||||||
import org.alfresco.service.cmr.rule.RuleService;
|
import org.alfresco.service.cmr.rule.RuleService;
|
||||||
import org.alfresco.service.cmr.rule.RuleServiceException;
|
import org.alfresco.service.cmr.rule.RuleServiceException;
|
||||||
import org.alfresco.service.cmr.rule.RuleType;
|
import org.alfresco.service.cmr.rule.RuleType;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.QNamePattern;
|
import org.alfresco.service.namespace.QNamePattern;
|
||||||
@@ -520,7 +524,7 @@ public class RuleServiceImpl
|
|||||||
// https://issues.alfresco.com/browse/ETWOTWO-438
|
// https://issues.alfresco.com/browse/ETWOTWO-438
|
||||||
|
|
||||||
if (!runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) ||
|
if (!runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) ||
|
||||||
permissionService.hasPermission(nodeRef, PermissionService.READ) != AccessStatus.ALLOWED)
|
permissionService.hasPermission(nodeRef, PermissionService.READ) != ALLOWED)
|
||||||
{
|
{
|
||||||
// Doesn't have the aspect or the user doesn't have access
|
// Doesn't have the aspect or the user doesn't have access
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@@ -538,7 +542,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
// Get the rules for this node
|
// Get the rules for this node
|
||||||
List<ChildAssociationRef> ruleChildAssocRefs =
|
List<ChildAssociationRef> ruleChildAssocRefs =
|
||||||
this.runtimeNodeService.getChildAssocs(ruleFolder, RegexQNamePattern.MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
this.runtimeNodeService.getChildAssocs(ruleFolder, MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
||||||
for (ChildAssociationRef ruleChildAssocRef : ruleChildAssocRefs)
|
for (ChildAssociationRef ruleChildAssocRef : ruleChildAssocRefs)
|
||||||
{
|
{
|
||||||
// Create the rule and add to the list
|
// Create the rule and add to the list
|
||||||
@@ -567,7 +571,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
// Get the rules for this node
|
// Get the rules for this node
|
||||||
List<ChildAssociationRef> ruleChildAssocRefs =
|
List<ChildAssociationRef> ruleChildAssocRefs =
|
||||||
this.runtimeNodeService.getChildAssocs(ruleFolder, RegexQNamePattern.MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
this.runtimeNodeService.getChildAssocs(ruleFolder, MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
||||||
|
|
||||||
ruleCount = ruleChildAssocRefs.size();
|
ruleCount = ruleChildAssocRefs.size();
|
||||||
}
|
}
|
||||||
@@ -647,6 +651,44 @@ public class RuleServiceImpl
|
|||||||
return returnList;
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
@Experimental
|
||||||
|
public List<NodeRef> getFoldersInheritingRuleSet(NodeRef ruleSet, int maxFoldersToReturn)
|
||||||
|
{
|
||||||
|
// Seed stack with all folders owning or linking to the rule set.
|
||||||
|
Deque<NodeRef> stack = new LinkedList<>();
|
||||||
|
for (ChildAssociationRef parentAssociation : runtimeNodeService.getParentAssocs(ruleSet))
|
||||||
|
{
|
||||||
|
stack.add(parentAssociation.getParentRef());
|
||||||
|
}
|
||||||
|
// Process child folders to find all that inherit the rules.
|
||||||
|
List<NodeRef> inheritors = new ArrayList<>();
|
||||||
|
while (!stack.isEmpty() && inheritors.size() < maxFoldersToReturn)
|
||||||
|
{
|
||||||
|
NodeRef folder = stack.pop();
|
||||||
|
runtimeNodeService.getChildAssocs(folder, ASSOC_CONTAINS, MATCH_ALL).stream().map(ChildAssociationRef::getChildRef).forEach(childNode -> {
|
||||||
|
QName childType = runtimeNodeService.getType(childNode);
|
||||||
|
if (dictionaryService.isSubClass(childType, ContentModel.TYPE_FOLDER)
|
||||||
|
&& !runtimeNodeService.hasAspect(childNode, ASPECT_IGNORE_INHERITED_RULES))
|
||||||
|
{
|
||||||
|
stack.add(childNode);
|
||||||
|
// Only return nodes that the user has permission to view.
|
||||||
|
if (permissionService.hasReadPermission(childNode) == ALLOWED)
|
||||||
|
{
|
||||||
|
inheritors.add(childNode);
|
||||||
|
if (inheritors.size() == maxFoldersToReturn)
|
||||||
|
{
|
||||||
|
// Return once we've hit the limit.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return inheritors;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the inherited rules for a given node reference
|
* Gets the inherited rules for a given node reference
|
||||||
*
|
*
|
||||||
@@ -798,7 +840,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
checkForLinkedRules(nodeRef);
|
checkForLinkedRules(nodeRef);
|
||||||
|
|
||||||
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) != AccessStatus.ALLOWED)
|
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) != ALLOWED)
|
||||||
{
|
{
|
||||||
throw new RuleServiceException("Insufficient permissions to save a rule.");
|
throw new RuleServiceException("Insufficient permissions to save a rule.");
|
||||||
}
|
}
|
||||||
@@ -823,7 +865,7 @@ public class RuleServiceImpl
|
|||||||
// Create the action node
|
// Create the action node
|
||||||
ruleNodeRef = this.nodeService.createNode(
|
ruleNodeRef = this.nodeService.createNode(
|
||||||
getSavedRuleFolderRef(nodeRef),
|
getSavedRuleFolderRef(nodeRef),
|
||||||
ContentModel.ASSOC_CONTAINS,
|
ASSOC_CONTAINS,
|
||||||
QName.createQName(RuleModel.RULE_MODEL_URI, ASSOC_NAME_RULES_PREFIX + GUID.generate()),
|
QName.createQName(RuleModel.RULE_MODEL_URI, ASSOC_NAME_RULES_PREFIX + GUID.generate()),
|
||||||
RuleModel.TYPE_RULE).getChildRef();
|
RuleModel.TYPE_RULE).getChildRef();
|
||||||
|
|
||||||
@@ -866,7 +908,7 @@ public class RuleServiceImpl
|
|||||||
NodeRef ruleFolder = getSavedRuleFolderRef(nodeRef);
|
NodeRef ruleFolder = getSavedRuleFolderRef(nodeRef);
|
||||||
if (ruleFolder != null)
|
if (ruleFolder != null)
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> assocs = this.runtimeNodeService.getChildAssocs(ruleFolder, RegexQNamePattern.MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
List<ChildAssociationRef> assocs = this.runtimeNodeService.getChildAssocs(ruleFolder, MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
||||||
List<ChildAssociationRef> orderedAssocs = new ArrayList<ChildAssociationRef>(assocs.size());
|
List<ChildAssociationRef> orderedAssocs = new ArrayList<ChildAssociationRef>(assocs.size());
|
||||||
ChildAssociationRef movedAssoc = null;
|
ChildAssociationRef movedAssoc = null;
|
||||||
for (ChildAssociationRef assoc : assocs)
|
for (ChildAssociationRef assoc : assocs)
|
||||||
@@ -948,7 +990,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
checkForLinkedRules(nodeRef);
|
checkForLinkedRules(nodeRef);
|
||||||
|
|
||||||
if (permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
|
if (permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == ALLOWED)
|
||||||
{
|
{
|
||||||
if (nodeService.exists(nodeRef) && nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES))
|
if (nodeService.exists(nodeRef) && nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES))
|
||||||
{
|
{
|
||||||
@@ -1011,7 +1053,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
checkForLinkedRules(nodeRef);
|
checkForLinkedRules(nodeRef);
|
||||||
|
|
||||||
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
|
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == ALLOWED)
|
||||||
{
|
{
|
||||||
if (this.nodeService.exists(nodeRef) == true &&
|
if (this.nodeService.exists(nodeRef) == true &&
|
||||||
this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true)
|
this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true)
|
||||||
@@ -1021,7 +1063,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
List<ChildAssociationRef> ruleChildAssocs = this.nodeService.getChildAssocs(
|
List<ChildAssociationRef> ruleChildAssocs = this.nodeService.getChildAssocs(
|
||||||
folder,
|
folder,
|
||||||
RegexQNamePattern.MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
||||||
for (ChildAssociationRef ruleChildAssoc : ruleChildAssocs)
|
for (ChildAssociationRef ruleChildAssoc : ruleChildAssocs)
|
||||||
{
|
{
|
||||||
this.nodeService.removeChild(folder, ruleChildAssoc.getChildRef());
|
this.nodeService.removeChild(folder, ruleChildAssoc.getChildRef());
|
||||||
@@ -1371,7 +1413,7 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
if (this.nodeService.exists(actionedUponNodeRef)
|
if (this.nodeService.exists(actionedUponNodeRef)
|
||||||
&& this.permissionService.hasPermission(actionedUponNodeRef, PermissionService.READ).equals(AccessStatus.ALLOWED))
|
&& this.permissionService.hasPermission(actionedUponNodeRef, PermissionService.READ).equals(ALLOWED))
|
||||||
{
|
{
|
||||||
NodeRef copiedFrom = copyService.getOriginal(actionedUponNodeRef);
|
NodeRef copiedFrom = copyService.getOriginal(actionedUponNodeRef);
|
||||||
if (logger.isDebugEnabled() == true)
|
if (logger.isDebugEnabled() == true)
|
||||||
|
@@ -227,6 +227,18 @@ public interface RuleService
|
|||||||
@Experimental
|
@Experimental
|
||||||
List<NodeRef> getNodesSupplyingRuleSets(NodeRef nodeRef);
|
List<NodeRef> getNodesSupplyingRuleSets(NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of folders inheriting the specified rule set.
|
||||||
|
*
|
||||||
|
* @param ruleSet The rule set node.
|
||||||
|
* @param maxFoldersToReturn A limit on the number of folders to return (since otherwise this could traverse a very large proportion of
|
||||||
|
* the repository.
|
||||||
|
* @return The list of the specified
|
||||||
|
*/
|
||||||
|
@Auditable (parameters = { "ruleSet", "maxFoldersToReturn" })
|
||||||
|
@Experimental
|
||||||
|
List<NodeRef> getFoldersInheritingRuleSet(NodeRef ruleSet, int maxFoldersToReturn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the rule given its node reference
|
* Get the rule given its node reference
|
||||||
*
|
*
|
||||||
|
@@ -25,17 +25,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rule;
|
package org.alfresco.repo.rule;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
|
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
|
||||||
import static org.alfresco.model.ContentModel.ASSOC_MEMBER;
|
import static org.alfresco.model.ContentModel.ASSOC_MEMBER;
|
||||||
|
import static org.alfresco.model.ContentModel.TYPE_CONTENT;
|
||||||
|
import static org.alfresco.model.ContentModel.TYPE_FOLDER;
|
||||||
import static org.alfresco.repo.rule.RuleModel.ASPECT_IGNORE_INHERITED_RULES;
|
import static org.alfresco.repo.rule.RuleModel.ASPECT_IGNORE_INHERITED_RULES;
|
||||||
import static org.alfresco.repo.rule.RuleModel.ASSOC_ACTION;
|
import static org.alfresco.repo.rule.RuleModel.ASSOC_ACTION;
|
||||||
import static org.alfresco.repo.rule.RuleModel.ASSOC_RULE_FOLDER;
|
import static org.alfresco.repo.rule.RuleModel.ASSOC_RULE_FOLDER;
|
||||||
import static org.alfresco.repo.rule.RuleModel.TYPE_RULE;
|
import static org.alfresco.repo.rule.RuleModel.TYPE_RULE;
|
||||||
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
|
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
|
||||||
import static org.alfresco.service.cmr.security.AccessStatus.DENIED;
|
import static org.alfresco.service.cmr.security.AccessStatus.DENIED;
|
||||||
|
import static org.alfresco.service.namespace.RegexQNamePattern.MATCH_ALL;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -52,18 +56,19 @@ import static org.mockito.Mockito.when;
|
|||||||
import static org.mockito.MockitoAnnotations.openMocks;
|
import static org.mockito.MockitoAnnotations.openMocks;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
import org.alfresco.repo.action.RuntimeActionService;
|
import org.alfresco.repo.action.RuntimeActionService;
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
import org.alfresco.service.cmr.action.ActionServiceException;
|
import org.alfresco.service.cmr.action.ActionServiceException;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
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;
|
||||||
@@ -98,6 +103,8 @@ public class RuleServiceImplUnitTest
|
|||||||
@Mock
|
@Mock
|
||||||
private RuntimeActionService runtimeActionService;
|
private RuntimeActionService runtimeActionService;
|
||||||
@Mock
|
@Mock
|
||||||
|
private DictionaryService dictionaryService;
|
||||||
|
@Mock
|
||||||
private Rule mockRule;
|
private Rule mockRule;
|
||||||
@Mock
|
@Mock
|
||||||
private Action mockAction;
|
private Action mockAction;
|
||||||
@@ -106,6 +113,10 @@ public class RuleServiceImplUnitTest
|
|||||||
public void setUp()
|
public void setUp()
|
||||||
{
|
{
|
||||||
openMocks(this);
|
openMocks(this);
|
||||||
|
|
||||||
|
when(dictionaryService.isSubClass(TYPE_FOLDER, TYPE_FOLDER)).thenReturn(true);
|
||||||
|
when(dictionaryService.isSubClass(TYPE_CONTENT, TYPE_FOLDER)).thenReturn(false);
|
||||||
|
when(permissionService.hasReadPermission(any())).thenReturn(ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -220,7 +231,7 @@ public class RuleServiceImplUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRuleSetNode_emptyAssociation()
|
public void testGetRuleSetNode_emptyAssociation()
|
||||||
{
|
{
|
||||||
given(runtimeNodeService.getChildAssocs(any(), any(), any())).willReturn(Collections.emptyList());
|
given(runtimeNodeService.getChildAssocs(any(), any(), any())).willReturn(emptyList());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final NodeRef actualNode = ruleService.getRuleSetNode(FOLDER_NODE);
|
final NodeRef actualNode = ruleService.getRuleSetNode(FOLDER_NODE);
|
||||||
@@ -264,7 +275,7 @@ public class RuleServiceImplUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testIsRuleSetAssociatedWithFolder_emptyAssociation()
|
public void testIsRuleSetAssociatedWithFolder_emptyAssociation()
|
||||||
{
|
{
|
||||||
given(runtimeNodeService.getParentAssocs(any(), any(), any())).willReturn(Collections.emptyList());
|
given(runtimeNodeService.getParentAssocs(any(), any(), any())).willReturn(emptyList());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
|
boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
|
||||||
@@ -343,7 +354,7 @@ public class RuleServiceImplUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testIsRuleAssociatedWithRuleSet_emptyAssociation()
|
public void testIsRuleAssociatedWithRuleSet_emptyAssociation()
|
||||||
{
|
{
|
||||||
given(runtimeNodeService.getParentAssocs(any())).willReturn(Collections.emptyList());
|
given(runtimeNodeService.getParentAssocs(any())).willReturn(emptyList());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean associated = ruleService.isRuleAssociatedWithRuleSet(RULE_NODE, RULE_SET_NODE);
|
boolean associated = ruleService.isRuleAssociatedWithRuleSet(RULE_NODE, RULE_SET_NODE);
|
||||||
@@ -456,7 +467,7 @@ public class RuleServiceImplUnitTest
|
|||||||
{
|
{
|
||||||
Map<String, NodeRef> nodes = createParentChildHierarchy("A,B", "B,C", "C,D", "D,E");
|
Map<String, NodeRef> nodes = createParentChildHierarchy("A,B", "B,C", "C,D", "D,E");
|
||||||
// Replace the B,C association with a user group membership association.
|
// Replace the B,C association with a user group membership association.
|
||||||
ChildAssociationRef memberAssoc = new ChildAssociationRef(ASSOC_MEMBER, nodes.get("B"), ContentModel.TYPE_FOLDER, nodes.get("C"));
|
ChildAssociationRef memberAssoc = new ChildAssociationRef(ASSOC_MEMBER, nodes.get("B"), TYPE_FOLDER, nodes.get("C"));
|
||||||
given(runtimeNodeService.getParentAssocs(nodes.get("C"))).willReturn(List.of(memberAssoc));
|
given(runtimeNodeService.getParentAssocs(nodes.get("C"))).willReturn(List.of(memberAssoc));
|
||||||
|
|
||||||
List<NodeRef> actual = ruleService.getNodesSupplyingRuleSets(nodes.get("E"));
|
List<NodeRef> actual = ruleService.getNodesSupplyingRuleSets(nodes.get("E"));
|
||||||
@@ -570,10 +581,137 @@ public class RuleServiceImplUnitTest
|
|||||||
.filter(assoc -> assoc.endsWith(nodeName))
|
.filter(assoc -> assoc.endsWith(nodeName))
|
||||||
.map(assoc -> assoc.split(",")[0])
|
.map(assoc -> assoc.split(",")[0])
|
||||||
.map(nodeRefMap::get)
|
.map(nodeRefMap::get)
|
||||||
.map(parentRef -> new ChildAssociationRef(ASSOC_CONTAINS, parentRef, ContentModel.TYPE_FOLDER, nodeRef))
|
.map(parentRef -> new ChildAssociationRef(ASSOC_CONTAINS, parentRef, TYPE_FOLDER, nodeRef))
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
given(runtimeNodeService.getParentAssocs(nodeRef)).willReturn(parentAssocs);
|
given(runtimeNodeService.getParentAssocs(nodeRef)).willReturn(parentAssocs);
|
||||||
});
|
});
|
||||||
return nodeRefMap;
|
return nodeRefMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check that getFoldersInheritingRuleSet returns a child folder. */
|
||||||
|
@Test
|
||||||
|
public void testGetFoldersInheritingRuleSet()
|
||||||
|
{
|
||||||
|
NodeRef parent = new NodeRef("parent://node/");
|
||||||
|
NodeRef ruleSetNode = new NodeRef("rule://set/");
|
||||||
|
ChildAssociationRef ruleSetAssociation = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(ruleSetAssociation));
|
||||||
|
given(ruleSetAssociation.getParentRef()).willReturn(parent);
|
||||||
|
NodeRef child = new NodeRef("child://node/");
|
||||||
|
ChildAssociationRef childAssocMock = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getChildAssocs(parent, ASSOC_CONTAINS, MATCH_ALL)).willReturn(List.of(childAssocMock));
|
||||||
|
given(childAssocMock.getChildRef()).willReturn(child);
|
||||||
|
given(runtimeNodeService.getType(child)).willReturn(TYPE_FOLDER);
|
||||||
|
|
||||||
|
List<NodeRef> actual = ruleService.getFoldersInheritingRuleSet(ruleSetNode, 100);
|
||||||
|
|
||||||
|
assertEquals("Unexpected list of inheriting folders.", List.of(child), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that getFoldersInheritingRuleSet omits a child folder if IGNORE_INHERITED_RULES is applied. */
|
||||||
|
@Test
|
||||||
|
public void testGetFoldersInheritingRuleSet_ignoreInheritedRules()
|
||||||
|
{
|
||||||
|
NodeRef parent = new NodeRef("parent://node/");
|
||||||
|
NodeRef ruleSetNode = new NodeRef("rule://set/");
|
||||||
|
ChildAssociationRef ruleSetAssociation = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(ruleSetAssociation));
|
||||||
|
given(ruleSetAssociation.getParentRef()).willReturn(parent);
|
||||||
|
NodeRef child = new NodeRef("child://node/");
|
||||||
|
ChildAssociationRef childAssocMock = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getChildAssocs(parent, ASSOC_CONTAINS, MATCH_ALL)).willReturn(List.of(childAssocMock));
|
||||||
|
given(childAssocMock.getChildRef()).willReturn(child);
|
||||||
|
given(runtimeNodeService.getType(child)).willReturn(TYPE_FOLDER);
|
||||||
|
given(runtimeNodeService.hasAspect(child, ASPECT_IGNORE_INHERITED_RULES)).willReturn(true);
|
||||||
|
|
||||||
|
List<NodeRef> actual = ruleService.getFoldersInheritingRuleSet(ruleSetNode, 100);
|
||||||
|
|
||||||
|
assertEquals("Unexpected list of inheriting folders.", emptyList(), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that getFoldersInheritingRuleSet only returns at most the requested number of folders. */
|
||||||
|
@Test
|
||||||
|
public void testGetFoldersExceedsLimit()
|
||||||
|
{
|
||||||
|
NodeRef root = new NodeRef("root://node/");
|
||||||
|
NodeRef ruleSetNode = new NodeRef("rule://set/");
|
||||||
|
ChildAssociationRef ruleSetAssociation = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(ruleSetAssociation));
|
||||||
|
given(ruleSetAssociation.getParentRef()).willReturn(root);
|
||||||
|
// Create a chain of ancestors starting from the root that is 10 folders deep.
|
||||||
|
List<NodeRef> nodeChain = new ArrayList<>();
|
||||||
|
nodeChain.add(root);
|
||||||
|
IntStream.range(0, 10).forEach(index -> {
|
||||||
|
NodeRef parent = nodeChain.get(nodeChain.size() - 1);
|
||||||
|
NodeRef child = new NodeRef("chain://node/" + index);
|
||||||
|
nodeChain.add(child);
|
||||||
|
ChildAssociationRef childAssocMock = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getChildAssocs(parent, ASSOC_CONTAINS, MATCH_ALL)).willReturn(List.of(childAssocMock));
|
||||||
|
given(childAssocMock.getChildRef()).willReturn(child);
|
||||||
|
given(runtimeNodeService.getType(child)).willReturn(TYPE_FOLDER);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Request at most 9 folders inheriting the rule.
|
||||||
|
List<NodeRef> actual = ruleService.getFoldersInheritingRuleSet(ruleSetNode, 9);
|
||||||
|
|
||||||
|
// Check we don't get the root node or the final descendant folder.
|
||||||
|
assertEquals("Unexpected list of inheriting folders.", nodeChain.subList(1, 10), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that getFoldersInheritingRuleSet doesn't include documents. */
|
||||||
|
@Test
|
||||||
|
public void testGetFoldersInheritingRuleSet_ignoreFiles()
|
||||||
|
{
|
||||||
|
NodeRef parent = new NodeRef("parent://node/");
|
||||||
|
NodeRef ruleSetNode = new NodeRef("rule://set/");
|
||||||
|
ChildAssociationRef ruleSetAssociation = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(ruleSetAssociation));
|
||||||
|
given(ruleSetAssociation.getParentRef()).willReturn(parent);
|
||||||
|
NodeRef childDocument = new NodeRef("child://document/");
|
||||||
|
ChildAssociationRef childAssocMock = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getChildAssocs(parent, ASSOC_CONTAINS, MATCH_ALL)).willReturn(List.of(childAssocMock));
|
||||||
|
given(childAssocMock.getChildRef()).willReturn(childDocument);
|
||||||
|
given(runtimeNodeService.getType(childDocument)).willReturn(TYPE_CONTENT);
|
||||||
|
|
||||||
|
List<NodeRef> actual = ruleService.getFoldersInheritingRuleSet(ruleSetNode, 100);
|
||||||
|
|
||||||
|
assertEquals("Unexpected list of inheriting folders.", emptyList(), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that getFoldersInheritingRuleSet does not include folders that the user doesn't have access to.
|
||||||
|
* <p>
|
||||||
|
* This test uses a chain of three folders:
|
||||||
|
* <pre>
|
||||||
|
* grandparent - owns the rule set
|
||||||
|
* parent - user does not have read access
|
||||||
|
* child - user _does_ have read access
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetFoldersInheritingRuleSet_omitFoldersWithoutReadPermission()
|
||||||
|
{
|
||||||
|
NodeRef grandparent = new NodeRef("grandparent://node/");
|
||||||
|
NodeRef ruleSetNode = new NodeRef("rule://set/");
|
||||||
|
ChildAssociationRef ruleSetAssociation = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(ruleSetAssociation));
|
||||||
|
given(ruleSetAssociation.getParentRef()).willReturn(grandparent);
|
||||||
|
NodeRef parent = new NodeRef("parent://node/");
|
||||||
|
ChildAssociationRef parentAssocMock = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getChildAssocs(grandparent, ASSOC_CONTAINS, MATCH_ALL)).willReturn(List.of(parentAssocMock));
|
||||||
|
given(parentAssocMock.getChildRef()).willReturn(parent);
|
||||||
|
given(runtimeNodeService.getType(parent)).willReturn(TYPE_FOLDER);
|
||||||
|
NodeRef child = new NodeRef("child://node/");
|
||||||
|
ChildAssociationRef childAssocMock = mock(ChildAssociationRef.class);
|
||||||
|
given(runtimeNodeService.getChildAssocs(grandparent, ASSOC_CONTAINS, MATCH_ALL)).willReturn(List.of(childAssocMock));
|
||||||
|
given(childAssocMock.getChildRef()).willReturn(child);
|
||||||
|
given(runtimeNodeService.getType(child)).willReturn(TYPE_FOLDER);
|
||||||
|
|
||||||
|
// The current user doesn't have permission to view the parent node.
|
||||||
|
given(permissionService.hasReadPermission(parent)).willReturn(DENIED);
|
||||||
|
|
||||||
|
List<NodeRef> actual = ruleService.getFoldersInheritingRuleSet(ruleSetNode, 100);
|
||||||
|
|
||||||
|
assertEquals("Unexpected list of inheriting folders.", List.of(child), actual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user