Merge branch 'master' into feature/ACS-3555_Add_CustomEmbeddedWorkflow_license_code

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -354,7 +354,7 @@ public class GetRuleSetsTests extends RestTest
RestRuleSetLinkModel ruleSetLink = new RestRuleSetLinkModel(); RestRuleSetLinkModel ruleSetLink = new RestRuleSetLinkModel();
ruleSetLink.setId(ruleFolder.getNodeRef()); ruleSetLink.setId(ruleFolder.getNodeRef());
coreAPIForUser().usingNode(publicFolder).createRuleLink(ruleSetLink); coreAPIForUser().usingNode(publicFolder).createRuleLink(ruleSetLink);
coreAPIForUser().usingNode(privateFolder).createRuleLink(ruleSetLink); coreAPIForAdmin().usingNode(privateFolder).createRuleLink(ruleSetLink);
STEP("Get the rule set and linkedToBy field"); STEP("Get the rule set and linkedToBy field");
RestRuleSetModel ruleSet = coreAPIForUser().usingNode(ruleFolder) RestRuleSetModel ruleSet = coreAPIForUser().usingNode(ruleFolder)
@@ -447,6 +447,62 @@ public class GetRuleSetsTests extends RestTest
ruleSet.assertThat().field("isInherited").is(false); 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() private RestCoreAPI coreAPIForUser()
{ {
return restClient.authenticateUser(user).withCoreAPI(); 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.ID;
import static org.alfresco.rest.rules.RulesTestsUtils.INBOUND; 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.IS_SHARED;
import static org.alfresco.rest.rules.RulesTestsUtils.RULE_ASYNC_DEFAULT; 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_CASCADE_DEFAULT;
import static org.alfresco.rest.rules.RulesTestsUtils.RULE_ENABLED_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.createDefaultActionModel;
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.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.constants.UserRole.SiteCollaborator;
import static org.alfresco.utility.report.log.Step.STEP; import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN; 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.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.OK;
@@ -47,6 +52,7 @@ import java.util.Map;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.alfresco.rest.RestTest; import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestActionBodyExecTemplateModel; import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
import org.alfresco.rest.model.RestCompositeConditionDefinitionModel;
import org.alfresco.rest.model.RestRuleModel; import org.alfresco.rest.model.RestRuleModel;
import org.alfresco.utility.model.FolderModel; import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel; import org.alfresco.utility.model.SiteModel;
@@ -287,14 +293,173 @@ public class UpdateRulesTests extends RestTest
final String updatedErrorScript = "updated-error-script"; final String updatedErrorScript = "updated-error-script";
rule.setErrorScript(updatedErrorScript); rule.setErrorScript(updatedErrorScript);
final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet() final RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
.include(IS_SHARED)
.updateRule(rule.getId(), rule); .updateRule(rule.getId(), rule);
restClient.assertStatusCodeIs(OK); restClient.assertStatusCodeIs(OK);
updatedRule.assertThat().isEqualTo(rule, ID, IS_SHARED) updatedRule.assertThat().isEqualTo(rule, ID)
.assertThat().field(ID).isNotNull(); .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) private RestRuleModel createAndSaveRule(String name)
{ {
return createAndSaveRule(name, List.of(createDefaultActionModel())); return createAndSaveRule(name, List.of(createDefaultActionModel()));

View File

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

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>17.126-SNAPSHOT</version> <version>17.128-SNAPSHOT</version>
</parent> </parent>
<properties> <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"> <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> <modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version> <version>17.128-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name> <name>Alfresco Community Repo Parent</name>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version> <version>17.128-SNAPSHOT</version>
</parent> </parent>
<dependencies> <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 static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.rest.api.model.rules.RuleSet; 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 INHERITED_BY = "inheritedBy";
protected static final String LINKED_TO_BY = "linkedToBy"; protected static final String LINKED_TO_BY = "linkedToBy";
protected static final String IS_INHERITED = "isInherited"; 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 static final int MAX_INHERITED_BY_SIZE = 100;
private NodeService nodeService; private NodeService nodeService;
private RuleService ruleService; private RuleService ruleService;
@@ -93,17 +93,16 @@ public class RuleSetLoader
} }
if (includes.contains(LINKED_TO_BY)) if (includes.contains(LINKED_TO_BY))
{ {
List<NodeRef> linkedToBy = nodeService.getParentAssocs(ruleSetNodeRef) ruleSet.setLinkedToBy(loadLinkedToBy(ruleSetNodeRef));
.stream()
.map(ChildAssociationRef::getParentRef)
.filter(folder -> !folder.equals(parentRef))
.collect(Collectors.toList());
ruleSet.setLinkedToBy(linkedToBy);
} }
if (includes.contains(IS_INHERITED)) if (includes.contains(IS_INHERITED))
{ {
ruleSet.setIsInherited(loadIsInherited(ruleSetNodeRef)); ruleSet.setIsInherited(loadIsInherited(ruleSetNodeRef));
} }
if (includes.contains(IS_LINKED_TO))
{
ruleSet.setIsLinkedTo(loadIsLinkedTo(ruleSetNodeRef, parentRef));
}
} }
return ruleSet; return ruleSet;
} }
@@ -113,11 +112,33 @@ public class RuleSetLoader
return ruleService.getFoldersInheritingRuleSet(ruleSetNodeRef, MAX_INHERITED_BY_SIZE); return ruleService.getFoldersInheritingRuleSet(ruleSetNodeRef, MAX_INHERITED_BY_SIZE);
} }
private List<NodeRef> loadLinkedToBy(NodeRef ruleSetNodeRef)
{
return ruleService.getFoldersLinkingToRuleSet(ruleSetNodeRef);
}
private boolean loadIsInherited(NodeRef ruleSetNodeRef) private boolean loadIsInherited(NodeRef ruleSetNodeRef)
{ {
return AuthenticationUtil.runAsSystem(() -> !ruleService.getFoldersInheritingRuleSet(ruleSetNodeRef, 1).isEmpty()); 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) public void setNodeService(NodeService nodeService)
{ {
this.nodeService = nodeService; this.nodeService = nodeService;

View File

@@ -44,6 +44,7 @@ public class RuleSet
private List<NodeRef> inheritedBy; private List<NodeRef> inheritedBy;
private List<NodeRef> linkedToBy; private List<NodeRef> linkedToBy;
private Boolean isInherited; private Boolean isInherited;
private Boolean isLinkedTo;
public static RuleSet of(String id) public static RuleSet of(String id)
{ {
@@ -130,6 +131,26 @@ public class RuleSet
return isInherited; 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 @Override
public String toString() public String toString()
{ {
@@ -141,6 +162,7 @@ public class RuleSet
.add("inheritedBy='" + inheritedBy + "'") .add("inheritedBy='" + inheritedBy + "'")
.add("linkedToBy='" + linkedToBy + "'") .add("linkedToBy='" + linkedToBy + "'")
.add("isInherited='" + isInherited + "'") .add("isInherited='" + isInherited + "'")
.add("isLinkedTo='" + isLinkedTo + "'")
.toString() .toString()
+ '}'; + '}';
} }
@@ -158,13 +180,14 @@ public class RuleSet
&& inclusionType == ruleSet.inclusionType && inclusionType == ruleSet.inclusionType
&& Objects.equals(inheritedBy, ruleSet.inheritedBy) && Objects.equals(inheritedBy, ruleSet.inheritedBy)
&& Objects.equals(linkedToBy, ruleSet.linkedToBy) && Objects.equals(linkedToBy, ruleSet.linkedToBy)
&& Objects.equals(isInherited, ruleSet.isInherited); && Objects.equals(isInherited, ruleSet.isInherited)
&& Objects.equals(isLinkedTo, ruleSet.isLinkedTo);
} }
@Override @Override
public int hashCode() 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() public static Builder builder()
@@ -180,6 +203,7 @@ public class RuleSet
private List<NodeRef> inheritedBy; private List<NodeRef> inheritedBy;
private List<NodeRef> linkedToBy; private List<NodeRef> linkedToBy;
private Boolean isInherited; private Boolean isInherited;
private Boolean isLinkedTo;
public Builder id(String id) public Builder id(String id)
{ {
@@ -217,6 +241,12 @@ public class RuleSet
return this; return this;
} }
public Builder isLinkedTo(Boolean isLinkedTo)
{
this.isLinkedTo = isLinkedTo;
return this;
}
public RuleSet create() public RuleSet create()
{ {
final RuleSet ruleSet = new RuleSet(); final RuleSet ruleSet = new RuleSet();
@@ -226,6 +256,7 @@ public class RuleSet
ruleSet.setInheritedBy(inheritedBy); ruleSet.setInheritedBy(inheritedBy);
ruleSet.setLinkedToBy(linkedToBy); ruleSet.setLinkedToBy(linkedToBy);
ruleSet.setIsInherited(isInherited); ruleSet.setIsInherited(isInherited);
ruleSet.setIsLinkedTo(isLinkedTo);
return ruleSet; 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.INCLUSION_TYPE;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INHERITED_BY; 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_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.LINKED_TO_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;
@@ -170,4 +171,14 @@ public class RuleSetLoaderTest extends TestCase
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).isInherited(true).create(); RuleSet expected = RuleSet.builder().id(RULE_SET_ID).isInherited(true).create();
assertEquals(expected, actual); 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> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>17.126-SNAPSHOT</version> <version>17.128-SNAPSHOT</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -689,6 +689,20 @@ public class RuleServiceImpl
return inheritors; 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 * 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 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 * @param maxFoldersToReturn A limit on the number of folders to return (since otherwise this could traverse a very large proportion of
* the repository. * the repository).
* @return The list of the specified * @return The list of the inheriting folders.
*/ */
@Auditable (parameters = { "ruleSet", "maxFoldersToReturn" }) @Auditable (parameters = { "ruleSet", "maxFoldersToReturn" })
@Experimental @Experimental
List<NodeRef> getFoldersInheritingRuleSet(NodeRef ruleSet, int maxFoldersToReturn); 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 * 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); 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);
}
} }