diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml
index 5168c28c3f..b784b0d898 100644
--- a/amps/ags/pom.xml
+++ b/amps/ags/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-amps
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml
index 323b1bee17..b4a9688e68 100644
--- a/amps/ags/rm-automation/pom.xml
+++ b/amps/ags/rm-automation/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-community-parent
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml
index 4f55228fae..24b2a195a3 100644
--- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml
+++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-automation-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml
index 5ff4ae7aeb..02b483c857 100644
--- a/amps/ags/rm-community/pom.xml
+++ b/amps/ags/rm-community/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-community-parent
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml
index 184413c5d6..1de1207000 100644
--- a/amps/ags/rm-community/rm-community-repo/pom.xml
+++ b/amps/ags/rm-community/rm-community-repo/pom.xml
@@ -8,7 +8,7 @@
org.alfresco
alfresco-governance-services-community-repo-parent
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml
index a848222f51..76b0e16822 100644
--- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml
+++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-governance-services-community-repo-parent
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/pom.xml b/amps/pom.xml
index 87cc763432..d304fc383e 100644
--- a/amps/pom.xml
+++ b/amps/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml
index 6aeac13f69..12017f8b7d 100644
--- a/amps/share-services/pom.xml
+++ b/amps/share-services/pom.xml
@@ -8,7 +8,7 @@
org.alfresco
alfresco-community-repo-amps
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/core/pom.xml b/core/pom.xml
index 6b874d5d52..2c9490a4e4 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/data-model/pom.xml b/data-model/pom.xml
index 213ca9f379..87f6a7b3d9 100644
--- a/data-model/pom.xml
+++ b/data-model/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/mmt/pom.xml b/mmt/pom.xml
index 47333dbf93..a3507d15ed 100644
--- a/mmt/pom.xml
+++ b/mmt/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml
index 07d492a8aa..3e489cf39c 100644
--- a/packaging/distribution/pom.xml
+++ b/packaging/distribution/pom.xml
@@ -9,6 +9,6 @@
org.alfresco
alfresco-community-repo-packaging
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml
index 420d34f757..689803136b 100644
--- a/packaging/docker-alfresco/pom.xml
+++ b/packaging/docker-alfresco/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-packaging
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/pom.xml b/packaging/pom.xml
index 282659ec1c..1a0c640449 100644
--- a/packaging/pom.xml
+++ b/packaging/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml
index 80e229c2e6..5d618b7685 100644
--- a/packaging/tests/pom.xml
+++ b/packaging/tests/pom.xml
@@ -6,7 +6,7 @@
org.alfresco
alfresco-community-repo-packaging
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml
index 3ca199682a..a9bf9007ff 100644
--- a/packaging/tests/tas-cmis/pom.xml
+++ b/packaging/tests/tas-cmis/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml
index c7ec6b0514..2d352ffab6 100644
--- a/packaging/tests/tas-email/pom.xml
+++ b/packaging/tests/tas-email/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml
index 06776a24be..a977f5ea37 100644
--- a/packaging/tests/tas-integration/pom.xml
+++ b/packaging/tests/tas-integration/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml
index 7a176aa344..31e9ae8e1e 100644
--- a/packaging/tests/tas-restapi/pom.xml
+++ b/packaging/tests/tas-restapi/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java
index 020951f8db..4feaa7586e 100644
--- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java
+++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java
@@ -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();
diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/UpdateRulesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/UpdateRulesTests.java
index be4ea977db..c841ca0966 100644
--- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/UpdateRulesTests.java
+++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/UpdateRulesTests.java
@@ -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()));
diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml
index 7897fe32ad..c920edf41b 100644
--- a/packaging/tests/tas-webdav/pom.xml
+++ b/packaging/tests/tas-webdav/pom.xml
@@ -9,7 +9,7 @@
org.alfresco
alfresco-community-repo-tests
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml
index 15e1799a7e..48c2ed0ff2 100644
--- a/packaging/war/pom.xml
+++ b/packaging/war/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo-packaging
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/pom.xml b/pom.xml
index 298e2b8714..384ee23024 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
pom
Alfresco Community Repo Parent
diff --git a/remote-api/pom.xml b/remote-api/pom.xml
index 05647bd606..6d5bd36615 100644
--- a/remote-api/pom.xml
+++ b/remote-api/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java
index 6fd9e8f338..bda45c9c15 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java
@@ -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 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 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;
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java
index 379228ce66..4a3713936d 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java
@@ -44,6 +44,7 @@ public class RuleSet
private List inheritedBy;
private List 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 inheritedBy;
private List 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;
}
}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java
index afa3a710e1..bf4f001e99 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java
@@ -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);
+ }
}
diff --git a/repository/pom.xml b/repository/pom.xml
index 681875e1e2..d585b088ae 100644
--- a/repository/pom.xml
+++ b/repository/pom.xml
@@ -7,7 +7,7 @@
org.alfresco
alfresco-community-repo
- 17.126-SNAPSHOT
+ 17.128-SNAPSHOT
diff --git a/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java b/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java
index db591fbbf7..b833e426c8 100644
--- a/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java
+++ b/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java
@@ -689,6 +689,20 @@ public class RuleServiceImpl
return inheritors;
}
+ /** {@inheritDoc} */
+ @Override
+ @Experimental
+ public List 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
*
diff --git a/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java b/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java
index 3b03eb329b..330e731f03 100644
--- a/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java
+++ b/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java
@@ -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 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 getFoldersLinkingToRuleSet(NodeRef ruleSet);
+
/**
* Get the rule given its node reference
*
diff --git a/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java b/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java
index 8c085abaea..939743efc1 100644
--- a/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java
+++ b/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java
@@ -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 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 linkingFolders = ruleService.getFoldersLinkingToRuleSet(ruleSetNode);
+
+ assertEquals("Unexpected list of linking folders.", emptyList(), linkingFolders);
+ }
}