mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-3214 Update rules. (#1254)
This commit is contained in:
@@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.rest.rules;
|
||||||
|
|
||||||
|
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
|
||||||
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
import static org.springframework.http.HttpStatus.CREATED;
|
||||||
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
import static org.springframework.http.HttpStatus.OK;
|
||||||
|
|
||||||
|
import org.alfresco.rest.RestTest;
|
||||||
|
import org.alfresco.rest.model.RestRuleModel;
|
||||||
|
import org.alfresco.rest.model.RestRuleSetModel;
|
||||||
|
import org.alfresco.utility.constants.UserRole;
|
||||||
|
import org.alfresco.utility.model.FolderModel;
|
||||||
|
import org.alfresco.utility.model.SiteModel;
|
||||||
|
import org.alfresco.utility.model.TestGroup;
|
||||||
|
import org.alfresco.utility.model.UserModel;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for PUT /nodes/{nodeId}/rule-sets/{ruleSetId}/rules.
|
||||||
|
*/
|
||||||
|
@Test (groups = { TestGroup.RULES })
|
||||||
|
public class UpdateRulesTests extends RestTest
|
||||||
|
{
|
||||||
|
private UserModel user;
|
||||||
|
private SiteModel site;
|
||||||
|
private FolderModel ruleFolder;
|
||||||
|
|
||||||
|
@BeforeClass (alwaysRun = true)
|
||||||
|
public void dataPreparation()
|
||||||
|
{
|
||||||
|
user = dataUser.createRandomTestUser();
|
||||||
|
site = dataSite.usingUser(user).createPublicRandomSite();
|
||||||
|
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can update a rule. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||||
|
public void updateRule()
|
||||||
|
{
|
||||||
|
RestRuleModel rule = createRule("Rule name");
|
||||||
|
|
||||||
|
STEP("Try to update the rule.");
|
||||||
|
RestRuleModel updatedRuleModel = new RestRuleModel();
|
||||||
|
updatedRuleModel.setName("Updated rule name");
|
||||||
|
RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
|
||||||
|
.updateRule(rule.getId(), updatedRuleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(OK);
|
||||||
|
updatedRule.assertThat().field("id").is(rule.getId())
|
||||||
|
.assertThat().field("name").is("Updated rule name");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to update a rule in a folder that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void updateRuleForNonExistentFolder()
|
||||||
|
{
|
||||||
|
RestRuleModel rule = createRule("Rule name");
|
||||||
|
|
||||||
|
STEP("Try to update a rule in a non-existent folder.");
|
||||||
|
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
|
||||||
|
nonExistentFolder.setNodeRef("fake-id");
|
||||||
|
|
||||||
|
RestRuleModel updatedRuleModel = new RestRuleModel();
|
||||||
|
updatedRuleModel.setName("Updated rule name");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet()
|
||||||
|
.updateRule(rule.getId(), updatedRuleModel);
|
||||||
|
|
||||||
|
restClient.assertLastError().statusCodeIs(NOT_FOUND)
|
||||||
|
.containsSummary("fake-id was not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to update a rule in a rule set that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void updateRuleForNonExistentRuleSet()
|
||||||
|
{
|
||||||
|
RestRuleModel rule = createRule("Rule name");
|
||||||
|
|
||||||
|
STEP("Try to update a rule in a non-existent rule set.");
|
||||||
|
RestRuleModel updatedRuleModel = new RestRuleModel();
|
||||||
|
updatedRuleModel.setName("Updated rule name");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingRuleSet("fake-id")
|
||||||
|
.updateRule(rule.getId(), updatedRuleModel);
|
||||||
|
|
||||||
|
restClient.assertLastError().statusCodeIs(NOT_FOUND)
|
||||||
|
.containsSummary("fake-id was not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to update a rule that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void updateRuleForNonExistentRuleId()
|
||||||
|
{
|
||||||
|
STEP("Try to update a rule that doesn't exist.");
|
||||||
|
RestRuleModel updatedRuleModel = new RestRuleModel();
|
||||||
|
updatedRuleModel.setName("Updated rule name");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
|
||||||
|
.updateRule("fake-id", updatedRuleModel);
|
||||||
|
|
||||||
|
restClient.assertLastError().statusCodeIs(NOT_FOUND)
|
||||||
|
.containsSummary("fake-id was not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that a user without permission cannot update a rule. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void requirePermissionToUpdateRule()
|
||||||
|
{
|
||||||
|
STEP("Create a user and use them to create a private site containing a folder");
|
||||||
|
UserModel privateUser = dataUser.createRandomTestUser();
|
||||||
|
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
|
||||||
|
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
|
||||||
|
|
||||||
|
STEP("Create a collaborator and check they don't have permission to create a rule");
|
||||||
|
UserModel collaborator = dataUser.createRandomTestUser();
|
||||||
|
dataUser.addUserToSite(collaborator, privateSite, SiteCollaborator);
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("ruleName");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(FORBIDDEN);
|
||||||
|
restClient.assertLastError().containsSummary("Insufficient permissions to manage rules");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get an error trying to update a rule to have no name. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void updateRuleToHaveEmptyName()
|
||||||
|
{
|
||||||
|
RestRuleModel rule = createRule("Rule name");
|
||||||
|
|
||||||
|
STEP("Try to update the rule to have no name.");
|
||||||
|
RestRuleModel updatedRuleModel = new RestRuleModel();
|
||||||
|
updatedRuleModel.setName("");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().updateRule(rule.getId(), updatedRuleModel);
|
||||||
|
|
||||||
|
restClient.assertLastError().statusCodeIs(BAD_REQUEST)
|
||||||
|
.containsSummary("Rule name is a mandatory parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that updates to the rule's id are ignored. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void tryToUpdateRuleId()
|
||||||
|
{
|
||||||
|
RestRuleModel rule = createRule("Rule name");
|
||||||
|
|
||||||
|
STEP("Try to update the rule id and check it isn't changed.");
|
||||||
|
RestRuleModel updatedRuleModel = new RestRuleModel();
|
||||||
|
updatedRuleModel.setId("new-rule-id");
|
||||||
|
updatedRuleModel.setName("Rule name");
|
||||||
|
RestRuleModel updatedRule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
|
||||||
|
.updateRule(rule.getId(), updatedRuleModel);
|
||||||
|
|
||||||
|
updatedRule.assertThat().field("id").is(rule.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a rule.
|
||||||
|
*
|
||||||
|
* @param name The name for the rule.
|
||||||
|
* @return The created rule.
|
||||||
|
*/
|
||||||
|
private RestRuleModel createRule(String name)
|
||||||
|
{
|
||||||
|
STEP("Create a rule called " + name);
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName(name);
|
||||||
|
return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
|
||||||
|
.createSingleRule(ruleModel);
|
||||||
|
}
|
||||||
|
}
|
@@ -74,6 +74,17 @@ public interface Rules
|
|||||||
*/
|
*/
|
||||||
List<Rule> createRules(String folderNodeId, String ruleSetId, List<Rule> rule);
|
List<Rule> createRules(String folderNodeId, String ruleSetId, List<Rule> rule);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a rule.
|
||||||
|
*
|
||||||
|
* @param folderNodeId The id of a folder.
|
||||||
|
* @param ruleSetId The id of a rule set within the folder (or "_default_" to use the default rule set for the folder).
|
||||||
|
* @param ruleId The rule id.
|
||||||
|
* @param rule The new version of the rule.
|
||||||
|
* @return The newly updated rule.
|
||||||
|
*/
|
||||||
|
Rule updateRuleById(String folderNodeId, String ruleSetId, String ruleId, Rule rule);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete rule for rule's ID and check associations with folder node and rule set node
|
* Delete rule for rule's ID and check associations with folder node and rule set node
|
||||||
*
|
*
|
||||||
|
@@ -30,6 +30,7 @@ import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
|
|||||||
import static org.alfresco.service.cmr.security.PermissionService.CHANGE_PERMISSIONS;
|
import static org.alfresco.service.cmr.security.PermissionService.CHANGE_PERMISSIONS;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -49,10 +50,13 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.rule.RuleService;
|
import org.alfresco.service.cmr.rule.RuleService;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Experimental
|
@Experimental
|
||||||
public class RulesImpl implements Rules
|
public class RulesImpl implements Rules
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RulesImpl.class);
|
||||||
private static final String RULE_SET_EXPECTED_TYPE_NAME = "rule set";
|
private static final String RULE_SET_EXPECTED_TYPE_NAME = "rule set";
|
||||||
|
|
||||||
private Nodes nodes;
|
private Nodes nodes;
|
||||||
@@ -99,6 +103,18 @@ public class RulesImpl implements Rules
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rule updateRuleById(String folderNodeId, String ruleSetId, String ruleId, Rule rule)
|
||||||
|
{
|
||||||
|
LOGGER.debug("Updating rule in folder {}, rule set {}, rule {} to {}", folderNodeId, ruleSetId, ruleId, rule);
|
||||||
|
|
||||||
|
NodeRef folderNodeRef = validateFolderNode(folderNodeId, true);
|
||||||
|
NodeRef ruleSetNodeRef = validateRuleSetNode(ruleSetId, folderNodeRef);
|
||||||
|
validateRuleNode(ruleId, ruleSetNodeRef);
|
||||||
|
|
||||||
|
return Rule.from(ruleService.saveRule(folderNodeRef, rule.toServiceModel(nodes)));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteRuleById(String folderNodeId, String ruleSetId, String ruleId)
|
public void deleteRuleById(String folderNodeId, String ruleSetId, String ruleId)
|
||||||
{
|
{
|
||||||
|
@@ -47,8 +47,12 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Experimental
|
@Experimental
|
||||||
@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules")
|
@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules")
|
||||||
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>, RelationshipResourceAction.ReadById<Rule>,
|
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
|
||||||
RelationshipResourceAction.Create<Rule>, RelationshipResourceAction.Delete, InitializingBean
|
RelationshipResourceAction.ReadById<Rule>,
|
||||||
|
RelationshipResourceAction.Create<Rule>,
|
||||||
|
RelationshipResourceAction.Update<Rule>,
|
||||||
|
RelationshipResourceAction.Delete,
|
||||||
|
InitializingBean
|
||||||
{
|
{
|
||||||
|
|
||||||
private Rules rules;
|
private Rules rules;
|
||||||
@@ -107,6 +111,8 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create one or more rules inside a given folder and rule set.
|
* Create one or more rules inside a given folder and rule set.
|
||||||
|
* <p>
|
||||||
|
* POST /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules
|
||||||
*
|
*
|
||||||
* @param folderNodeId The folder in which to create the rule.
|
* @param folderNodeId The folder in which to create the rule.
|
||||||
* @param ruleList The list of rules to create.
|
* @param ruleList The list of rules to create.
|
||||||
@@ -126,9 +132,28 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
|
|||||||
return rules.createRules(folderNodeId, ruleSetId, ruleList);
|
return rules.createRules(folderNodeId, ruleSetId, ruleList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRules(Rules rules)
|
/**
|
||||||
|
* Update the specified folder rule.
|
||||||
|
* <p>
|
||||||
|
* PUT /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules/{ruleId}
|
||||||
|
*
|
||||||
|
* @param folderNodeId The id of the folder containing the rule.
|
||||||
|
* @param rule The updated rule.
|
||||||
|
* @param parameters List of parameters including the rule set id and rule id.
|
||||||
|
* @return The updated rule.
|
||||||
|
* @throws RelationshipResourceNotFoundException in case resource was not found
|
||||||
|
*/
|
||||||
|
@WebApiDescription (
|
||||||
|
title = "Update folder node rule",
|
||||||
|
description = "Update a single rule definition for given node's, rule set's and rule's IDs",
|
||||||
|
successStatus = HttpServletResponse.SC_OK
|
||||||
|
)
|
||||||
|
@Override
|
||||||
|
public Rule update(String folderNodeId, Rule rule, Parameters parameters)
|
||||||
{
|
{
|
||||||
this.rules = rules;
|
String ruleSetId = parameters.getRelationshipId();
|
||||||
|
String ruleId = parameters.getRelationship2Id();
|
||||||
|
return rules.updateRuleById(folderNodeId, ruleSetId, ruleId, rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,4 +177,9 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
|
|||||||
final String ruleId = parameters.getRelationship2Id();
|
final String ruleId = parameters.getRelationship2Id();
|
||||||
rules.deleteRuleById(folderNodeId, ruleSetId, ruleId);
|
rules.deleteRuleById(folderNodeId, ruleSetId, ruleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRules(Rules rules)
|
||||||
|
{
|
||||||
|
this.rules = rules;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -79,6 +79,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
|||||||
final Map<String, String> resourceVars = locator.parseTemplateVars(req.getServiceMatch().getTemplateVars());
|
final Map<String, String> resourceVars = locator.parseTemplateVars(req.getServiceMatch().getTemplateVars());
|
||||||
final String entityId = resourceVars.get(ResourceLocator.ENTITY_ID);
|
final String entityId = resourceVars.get(ResourceLocator.ENTITY_ID);
|
||||||
final String relationshipId = resourceVars.get(ResourceLocator.RELATIONSHIP_ID);
|
final String relationshipId = resourceVars.get(ResourceLocator.RELATIONSHIP_ID);
|
||||||
|
final String relationship2Id = resourceVars.get(ResourceLocator.RELATIONSHIP2_ID);
|
||||||
|
|
||||||
final RecognizedParams params = getRecognizedParams(req);
|
final RecognizedParams params = getRecognizedParams(req);
|
||||||
final ResourceOperation operation = resourceMeta.getOperation(HttpMethod.PUT);
|
final ResourceOperation operation = resourceMeta.getOperation(HttpMethod.PUT);
|
||||||
@@ -99,9 +100,16 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
|||||||
if (StringUtils.isBlank(relationshipId))
|
if (StringUtils.isBlank(relationshipId))
|
||||||
{
|
{
|
||||||
throw new UnsupportedResourceOperationException("PUT is executed against the instance URL");
|
throw new UnsupportedResourceOperationException("PUT is executed against the instance URL");
|
||||||
} else
|
}
|
||||||
{
|
|
||||||
Object putRel = extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
Object putRel = extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||||
|
if (StringUtils.isNotBlank(relationship2Id))
|
||||||
|
{
|
||||||
|
ResourceWebScriptHelper.setUniqueId(putRel, relationship2Id);
|
||||||
|
return Params.valueOf(false, entityId, relationshipId, relationship2Id,
|
||||||
|
putRel, null, null, params, null, req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ResourceWebScriptHelper.setUniqueId(putRel,relationshipId);
|
ResourceWebScriptHelper.setUniqueId(putRel,relationshipId);
|
||||||
return Params.valueOf(entityId, params, putRel, req);
|
return Params.valueOf(entityId, params, putRel, req);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user