Merge branch 'feature/ACS-3555_Add_CustomEmbeddedWorkflow_license_code' into feature/ACS-3560_Discovery_API_for_customEmbeddedWorkflow_License

This commit is contained in:
Sara Aspery
2022-09-21 22:07:06 +01:00
32 changed files with 388 additions and 38 deletions

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
</project>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -354,7 +354,7 @@ public class GetRuleSetsTests extends RestTest
RestRuleSetLinkModel ruleSetLink = new RestRuleSetLinkModel();
ruleSetLink.setId(ruleFolder.getNodeRef());
coreAPIForUser().usingNode(publicFolder).createRuleLink(ruleSetLink);
coreAPIForUser().usingNode(privateFolder).createRuleLink(ruleSetLink);
coreAPIForAdmin().usingNode(privateFolder).createRuleLink(ruleSetLink);
STEP("Get the rule set and linkedToBy field");
RestRuleSetModel ruleSet = coreAPIForUser().usingNode(ruleFolder)
@@ -447,6 +447,62 @@ public class GetRuleSetsTests extends RestTest
ruleSet.assertThat().field("isInherited").is(false);
}
/** Check that a user can see that a rule set is linked to even if they don't have permission to view the linking folder. */
@Test
public void getRuleSetAndIsLinkedToWithoutPermission()
{
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 a folder with a rule set");
FolderModel ruleFolder = dataContent.usingUser(user).usingSite(siteModel).createFolder();
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
coreAPIForUser().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
STEP("Create a private folder linking to the rule set");
FolderModel linkingFolder = dataContent.usingAdmin().usingSite(siteModel).createFolder();
RestRuleSetLinkModel linkModel = new RestRuleSetLinkModel();
linkModel.setId(ruleFolder.getNodeRef());
coreAPIForAdmin().usingNode(linkingFolder).createRuleLink(linkModel);
STEP("Remove the user from the site");
dataUser.removeUserFromSite(user, siteModel);
STEP("Get the rule set and isLinkedTo field");
RestRuleSetModel ruleSet = coreAPIForUser().usingNode(ruleFolder)
.include("isLinkedTo", "linkedToBy", "owningFolder")
.getDefaultRuleSet();
restClient.assertStatusCodeIs(OK);
ruleSet.assertThat().field("isLinkedTo").is(true)
.assertThat().field("linkedToBy").isEmpty();
}
/**
* Check that if a rule set is owned and inherited but not linked to then isLinkedTo returns false.
*/
@Test
public void getRuleSetAndIsLinkedToCanBeFalse()
{
STEP("Create a site, a folder with a rule and a child folder that inherits it");
SiteModel siteModel = dataSite.usingUser(user).createPublicRandomSite();
FolderModel ruleFolder = dataContent.usingUser(user).usingSite(siteModel).createFolder();
RestRuleModel ruleModel = createRuleModelWithDefaultValues();
coreAPIForUser().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
dataContent.usingUser(user).usingResource(ruleFolder).createFolder();
STEP("Get the rule set and isLinkedTo field");
RestRuleSetModel ruleSet = coreAPIForUser().usingNode(ruleFolder)
.include("isLinkedTo")
.getDefaultRuleSet();
restClient.assertStatusCodeIs(OK);
ruleSet.assertThat().field("isLinkedTo").is(false);
}
private RestCoreAPI coreAPIForUser()
{
return restClient.authenticateUser(user).withCoreAPI();

View File

@@ -27,17 +27,22 @@ package org.alfresco.rest.rules;
import static org.alfresco.rest.rules.RulesTestsUtils.ID;
import static org.alfresco.rest.rules.RulesTestsUtils.INBOUND;
import static org.alfresco.rest.rules.RulesTestsUtils.INVERTED;
import static org.alfresco.rest.rules.RulesTestsUtils.IS_SHARED;
import static org.alfresco.rest.rules.RulesTestsUtils.RULE_ASYNC_DEFAULT;
import static org.alfresco.rest.rules.RulesTestsUtils.RULE_CASCADE_DEFAULT;
import static org.alfresco.rest.rules.RulesTestsUtils.RULE_ENABLED_DEFAULT;
import static org.alfresco.rest.rules.RulesTestsUtils.createCompositeCondition;
import static org.alfresco.rest.rules.RulesTestsUtils.createDefaultActionModel;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModel;
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModelWithModifiedValues;
import static org.alfresco.rest.rules.RulesTestsUtils.createSimpleCondition;
import static org.alfresco.rest.rules.RulesTestsUtils.createVariousConditions;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
@@ -47,6 +52,7 @@ import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
import org.alfresco.rest.model.RestCompositeConditionDefinitionModel;
import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
@@ -287,14 +293,173 @@ public class UpdateRulesTests extends RestTest
final String updatedErrorScript = "updated-error-script";
rule.setErrorScript(updatedErrorScript);
final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include(IS_SHARED)
.updateRule(rule.getId(), rule);
restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().isEqualTo(rule, ID, IS_SHARED)
updatedRule.assertThat().isEqualTo(rule, ID)
.assertThat().field(ID).isNotNull();
}
/** Check we can use the POST response and update rule by adding conditions. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleAddConditions()
{
final RestRuleModel rule = createAndSaveRule(createRuleModelWithModifiedValues());
STEP("Try to update the rule and add conditions.");
rule.setConditions(createVariousConditions());
final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), rule);
restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().isEqualTo(rule, ID)
.assertThat().field(ID).isNotNull();
}
/** Check we can use the POST response and update a rule rule without any conditions by adding null conditions. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleAddNullConditions()
{
final RestRuleModel rule = createAndSaveRule(createRuleModelWithModifiedValues());
STEP("Try to update the rule and add null conditions.");
rule.setConditions(createCompositeCondition(null));
final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), rule);
restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().isEqualTo(rule, ID)
.assertThat().field(ID).isNotNull();
}
/** Check we can use the POST response and update rule by modifying conditions. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleModifyConditions()
{
final RestRuleModel ruleModelWithInitialValues = createRuleModelWithModifiedValues();
ruleModelWithInitialValues.setConditions(createVariousConditions());
final RestRuleModel rule = createAndSaveRule(ruleModelWithInitialValues);
STEP("Try to update the rule and modify conditions.");
final RestCompositeConditionDefinitionModel compositeCondition = createCompositeCondition(
List.of(createCompositeCondition(false, List.of(createSimpleCondition("tag", "equals", "sample_tag")))));
rule.setConditions(compositeCondition);
final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), rule);
restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().isEqualTo(rule, ID)
.assertThat().field(ID).isNotNull();
}
/** Check we can use the POST response and update rule by removing all conditions. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleRemoveAllConditions()
{
final RestRuleModel ruleModelWithInitialValues = createRuleModelWithModifiedValues();
ruleModelWithInitialValues.setConditions(createVariousConditions());
final RestRuleModel rule = createAndSaveRule(ruleModelWithInitialValues);
STEP("Try to update the rule and remove all conditions.");
rule.setConditions(null);
final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.updateRule(rule.getId(), rule);
//set expected object
rule.setConditions(createCompositeCondition(null));
restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().isEqualTo(rule, ID)
.assertThat().field(ID).isNotNull();
}
/** Check we get a 400 error when using the POST response and update rule by adding condition with invalid category. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleWithInvalidCategoryInConditionAndFail()
{
final RestRuleModel ruleModelWithInitialValues = createRuleModelWithModifiedValues();
ruleModelWithInitialValues.setConditions(createVariousConditions());
final RestRuleModel rule = createAndSaveRule(ruleModelWithInitialValues);
STEP("Try to update the rule with invalid condition.");
final RestCompositeConditionDefinitionModel conditions = createCompositeCondition(
List.of(createCompositeCondition(!INVERTED, List.of(createSimpleCondition("category", "equals", "fake-category-id")))));
rule.setConditions(conditions);
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include(IS_SHARED)
.updateRule(rule.getId(), rule);
restClient.assertStatusCodeIs(BAD_REQUEST);
restClient.assertLastError().containsSummary("Category in condition is invalid");
}
/** Check we get a 500 error when using the POST response and update rule by adding condition without comparator. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleWithConditionWithoutComparatorAndFail()
{
final RestRuleModel ruleModelWithInitialValues = createRuleModelWithModifiedValues();
ruleModelWithInitialValues.setConditions(createVariousConditions());
final RestRuleModel rule = createAndSaveRule(ruleModelWithInitialValues);
STEP("Try to update the rule with invalid condition.");
final RestCompositeConditionDefinitionModel conditions = createCompositeCondition(
List.of(createCompositeCondition(!INVERTED, List.of(createSimpleCondition("size", null, "65500")))));
rule.setConditions(conditions);
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include(IS_SHARED)
.updateRule(rule.getId(), rule);
//TODO: in next iteration of mapper refactoring this error code will change to 400
restClient.assertStatusCodeIs(INTERNAL_SERVER_ERROR);
}
/** Check we get a 500 error when using the POST response and update rule by adding condition without field. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleWithConditionWithoutFieldAndFail()
{
final RestRuleModel ruleModelWithInitialValues = createRuleModelWithModifiedValues();
ruleModelWithInitialValues.setConditions(createVariousConditions());
final RestRuleModel rule = createAndSaveRule(ruleModelWithInitialValues);
STEP("Try to update the rule with invalid condition.");
final RestCompositeConditionDefinitionModel conditions = createCompositeCondition(
List.of(createCompositeCondition(!INVERTED, List.of(createSimpleCondition(null, "greater_than", "65500")))));
rule.setConditions(conditions);
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include(IS_SHARED)
.updateRule(rule.getId(), rule);
//TODO: in next iteration of mapper refactoring this error code will change to 400
restClient.assertStatusCodeIs(INTERNAL_SERVER_ERROR);
}
/** Check we get a 500 error when using the POST response and update rule by adding condition without parameter value. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void updateRuleWithConditionWithoutParamValueAndFail()
{
final RestRuleModel ruleModelWithInitialValues = createRuleModelWithModifiedValues();
ruleModelWithInitialValues.setConditions(createVariousConditions());
final RestRuleModel rule = createAndSaveRule(ruleModelWithInitialValues);
STEP("Try to update the rule with invalid condition.");
final RestCompositeConditionDefinitionModel conditions = createCompositeCondition(
List.of(createCompositeCondition(!INVERTED, List.of(createSimpleCondition("size", "greater_than", null)))));
rule.setConditions(conditions);
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include(IS_SHARED)
.updateRule(rule.getId(), rule);
//TODO: in next iteration of mapper refactoring this error code will change to 400
restClient.assertStatusCodeIs(INTERNAL_SERVER_ERROR);
}
private RestRuleModel createAndSaveRule(String name)
{
return createAndSaveRule(name, List.of(createDefaultActionModel()));

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -30,7 +30,6 @@ import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.rest.api.model.rules.RuleSet;
@@ -49,6 +48,7 @@ public class RuleSetLoader
protected static final String INHERITED_BY = "inheritedBy";
protected static final String LINKED_TO_BY = "linkedToBy";
protected static final String IS_INHERITED = "isInherited";
protected static final String IS_LINKED_TO = "isLinkedTo";
private static final int MAX_INHERITED_BY_SIZE = 100;
private NodeService nodeService;
private RuleService ruleService;
@@ -93,17 +93,16 @@ public class RuleSetLoader
}
if (includes.contains(LINKED_TO_BY))
{
List<NodeRef> linkedToBy = nodeService.getParentAssocs(ruleSetNodeRef)
.stream()
.map(ChildAssociationRef::getParentRef)
.filter(folder -> !folder.equals(parentRef))
.collect(Collectors.toList());
ruleSet.setLinkedToBy(linkedToBy);
ruleSet.setLinkedToBy(loadLinkedToBy(ruleSetNodeRef));
}
if (includes.contains(IS_INHERITED))
{
ruleSet.setIsInherited(loadIsInherited(ruleSetNodeRef));
}
if (includes.contains(IS_LINKED_TO))
{
ruleSet.setIsLinkedTo(loadIsLinkedTo(ruleSetNodeRef, parentRef));
}
}
return ruleSet;
}
@@ -113,11 +112,33 @@ public class RuleSetLoader
return ruleService.getFoldersInheritingRuleSet(ruleSetNodeRef, MAX_INHERITED_BY_SIZE);
}
private List<NodeRef> loadLinkedToBy(NodeRef ruleSetNodeRef)
{
return ruleService.getFoldersLinkingToRuleSet(ruleSetNodeRef);
}
private boolean loadIsInherited(NodeRef ruleSetNodeRef)
{
return AuthenticationUtil.runAsSystem(() -> !ruleService.getFoldersInheritingRuleSet(ruleSetNodeRef, 1).isEmpty());
}
/**
* Check if any parents of the rule set node are not the owning folder.
*
* @param ruleSetNodeRef The rule set node.
* @param parentRef The owning folder.
* @return True if another folder links to the rule set.
*/
private Boolean loadIsLinkedTo(NodeRef ruleSetNodeRef, NodeRef parentRef)
{
return AuthenticationUtil.runAsSystem(() ->
nodeService.getParentAssocs(ruleSetNodeRef)
.stream()
.map(ChildAssociationRef::getParentRef)
.anyMatch(folder -> !folder.equals(parentRef))
);
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;

View File

@@ -44,6 +44,7 @@ public class RuleSet
private List<NodeRef> inheritedBy;
private List<NodeRef> linkedToBy;
private Boolean isInherited;
private Boolean isLinkedTo;
public static RuleSet of(String id)
{
@@ -130,6 +131,26 @@ public class RuleSet
return isInherited;
}
/**
* Set a flag indicating that the rule set is linked to by a folder.
*
* @param isLinkedTo The flag.
*/
public void setIsLinkedTo(Boolean isLinkedTo)
{
this.isLinkedTo = isLinkedTo;
}
/**
* Find if the rule set is linked to by a folder.
*
* @return The value of the flag.
*/
public Boolean getIsLinkedTo()
{
return isLinkedTo;
}
@Override
public String toString()
{
@@ -141,6 +162,7 @@ public class RuleSet
.add("inheritedBy='" + inheritedBy + "'")
.add("linkedToBy='" + linkedToBy + "'")
.add("isInherited='" + isInherited + "'")
.add("isLinkedTo='" + isLinkedTo + "'")
.toString()
+ '}';
}
@@ -158,13 +180,14 @@ public class RuleSet
&& inclusionType == ruleSet.inclusionType
&& Objects.equals(inheritedBy, ruleSet.inheritedBy)
&& Objects.equals(linkedToBy, ruleSet.linkedToBy)
&& Objects.equals(isInherited, ruleSet.isInherited);
&& Objects.equals(isInherited, ruleSet.isInherited)
&& Objects.equals(isLinkedTo, ruleSet.isLinkedTo);
}
@Override
public int hashCode()
{
return Objects.hash(id, owningFolder, inclusionType, inheritedBy, linkedToBy, isInherited);
return Objects.hash(id, owningFolder, inclusionType, inheritedBy, linkedToBy, isInherited, isLinkedTo);
}
public static Builder builder()
@@ -180,6 +203,7 @@ public class RuleSet
private List<NodeRef> inheritedBy;
private List<NodeRef> linkedToBy;
private Boolean isInherited;
private Boolean isLinkedTo;
public Builder id(String id)
{
@@ -217,6 +241,12 @@ public class RuleSet
return this;
}
public Builder isLinkedTo(Boolean isLinkedTo)
{
this.isLinkedTo = isLinkedTo;
return this;
}
public RuleSet create()
{
final RuleSet ruleSet = new RuleSet();
@@ -226,6 +256,7 @@ public class RuleSet
ruleSet.setInheritedBy(inheritedBy);
ruleSet.setLinkedToBy(linkedToBy);
ruleSet.setIsInherited(isInherited);
ruleSet.setIsLinkedTo(isLinkedTo);
return ruleSet;
}
}

View File

@@ -28,6 +28,7 @@ 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.INHERITED_BY;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.IS_INHERITED;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.IS_LINKED_TO;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.LINKED_TO_BY;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.OWNING_FOLDER;
import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
@@ -170,4 +171,14 @@ public class RuleSetLoaderTest extends TestCase
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).isInherited(true).create();
assertEquals(expected, actual);
}
@Test
public void testLoadRuleSet_isLinkedTo()
{
// Call the method under test.
RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(IS_LINKED_TO));
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).isLinkedTo(true).create();
assertEquals(expected, actual);
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version>
<version>17.128-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -689,6 +689,20 @@ public class RuleServiceImpl
return inheritors;
}
/** {@inheritDoc} */
@Override
@Experimental
public List<NodeRef> getFoldersLinkingToRuleSet(NodeRef ruleSet)
{
NodeRef parentRef = nodeService.getPrimaryParent(ruleSet).getParentRef();
return nodeService.getParentAssocs(ruleSet)
.stream()
.map(ChildAssociationRef::getParentRef)
.filter(folder -> !folder.equals(parentRef))
.filter(folder -> permissionService.hasReadPermission(folder) == ALLOWED)
.collect(Collectors.toList());
}
/**
* Gets the inherited rules for a given node reference
*

View File

@@ -232,13 +232,23 @@ public interface RuleService
*
* @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
* the repository).
* @return The list of the inheriting folders.
*/
@Auditable (parameters = { "ruleSet", "maxFoldersToReturn" })
@Experimental
List<NodeRef> getFoldersInheritingRuleSet(NodeRef ruleSet, int maxFoldersToReturn);
/**
* Get a list of folders linking to the specified rule set.
*
* @param ruleSet The rule set node.
* @return The list linking folders.
*/
@Auditable (parameters = { "ruleSet" })
@Experimental
List<NodeRef> getFoldersLinkingToRuleSet(NodeRef ruleSet);
/**
* Get the rule given its node reference
*

View File

@@ -714,4 +714,46 @@ public class RuleServiceImplUnitTest
assertEquals("Unexpected list of inheriting folders.", List.of(child), actual);
}
/** Check that a linked folder can be retrieved from a rule set node. */
@Test
public void testGetFoldersLinkingToRuleSet()
{
NodeRef ruleSetNode = new NodeRef("rule://set/");
NodeRef owningFolder = new NodeRef("owning://folder/");
ChildAssociationRef owningAssocMock = mock(ChildAssociationRef.class);
given(owningAssocMock.getParentRef()).willReturn(owningFolder);
given(nodeService.getPrimaryParent(ruleSetNode)).willReturn(owningAssocMock);
// Simulate a folder linking to the rule set.
NodeRef linkingFolder = new NodeRef("linking://folder/");
ChildAssociationRef linkingAssocMock = mock(ChildAssociationRef.class);
given(linkingAssocMock.getParentRef()).willReturn(linkingFolder);
given(nodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(owningAssocMock, linkingAssocMock));
List<NodeRef> linkingFolders = ruleService.getFoldersLinkingToRuleSet(ruleSetNode);
assertEquals("Unexpected list of linking folders.", List.of(linkingFolder), linkingFolders);
}
/** Check that permissions affect which linked folders are returned to the user. */
@Test
public void testGetFoldersLinkingToRuleSet_respectsPermissions()
{
NodeRef ruleSetNode = new NodeRef("rule://set/");
NodeRef owningFolder = new NodeRef("owning://folder/");
ChildAssociationRef owningAssocMock = mock(ChildAssociationRef.class);
given(owningAssocMock.getParentRef()).willReturn(owningFolder);
given(nodeService.getPrimaryParent(ruleSetNode)).willReturn(owningAssocMock);
// Simulate a folder linking to the rule set.
NodeRef linkingFolder = new NodeRef("linking://folder/");
ChildAssociationRef linkingAssocMock = mock(ChildAssociationRef.class);
given(linkingAssocMock.getParentRef()).willReturn(linkingFolder);
given(nodeService.getParentAssocs(ruleSetNode)).willReturn(List.of(owningAssocMock, linkingAssocMock));
// The currect user does not have permission to view the folder.
given(permissionService.hasReadPermission(linkingFolder)).willReturn(DENIED);
List<NodeRef> linkingFolders = ruleService.getFoldersLinkingToRuleSet(ruleSetNode);
assertEquals("Unexpected list of linking folders.", emptyList(), linkingFolders);
}
}