Compare commits

...

60 Commits

Author SHA1 Message Date
swapnil.verma
01d907a3e5 [RM-7188] - Removed 'author' and 'since' attributes from files 2022-12-06 15:25:53 +05:30
swapnil.verma
9ec4323b76 [RM-7188] - Removed 'author' and 'since' attributes from files 2022-12-06 15:23:13 +05:30
swapnil.verma
c954f87706 [RM-7188] - Updated license header and version numbers 2022-12-06 11:44:19 +05:30
swapnil.verma
6572baf8e1 [RM-7188] - Updated formatting of methods 2022-12-06 10:13:04 +05:30
swapnil.verma
f295838c66 [RM-7188] - Removed extra exceptions from rm-public-rest-context.xml 2022-12-02 11:51:30 +05:30
swapnil.verma
1be88222e1 [RM-7188] - Added REST endpoint for fetching list of events 2022-12-02 11:46:06 +05:30
Travis CI User
ba7be5999b [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-30 09:49:48 +00:00
Travis CI User
8503b2c96c [maven-release-plugin][skip ci] prepare release 20.27 2022-11-30 09:49:45 +00:00
rrajoria
f43806b9f4 Updating googledrive version 2022-11-30 14:00:25 +05:30
brijmohan1
1eebb8ec12 Feature/RM-7178 Event apis swagger (#1572)
* Added Events Management Section in Swagger

* Removed Events Management Section in Swagger

* RM-7178 swagger implementation for event APIs.

* RM-7178 event API swagger header description .

* RM-7178 event API swagger header description .

* RM-7178 updated create event API description .

* Updated Swagger for Event Management

* RM-7178 updated put and create event API description and body.

* Added /event-type endpoint

* Addressed review comments

* RM-7178 updated swagger for review comments.

* RM-7178 updated swagger for review comments.

* RM-7178 updated swagger for review comments.

* Addressed review comments

* Addressed review comments

* RM-7178 added changes for swagger review comments.

* RM-7178 added changes for swagger review comments.

* RM-7178 added changes for pagination in event and event type.

* Addressed review comments

* Addressed review comments

* Addressed review comments (Added 400 response code for paging GET APIs)

* Addressed review comments

* Addressed review comments

* Addressed review comments

* Addressed review comments

* Addressed review comments

* Addressed review comments

Co-authored-by: suneet-gupta <Suneet.Gupta@contractor.alfresco.com>
Co-authored-by: suneet-gupta <suneet.gupta@hyland.com>
2022-11-28 21:45:56 +05:30
Travis CI User
008b340851 [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-27 00:11:03 +00:00
Travis CI User
6d3e249149 [maven-release-plugin][skip ci] prepare release 20.26 2022-11-27 00:11:00 +00:00
Alfresco CI User
bf276c60d6 [force] Force release for 2022-11-27. 2022-11-27 00:03:19 +00:00
Travis CI User
54be23513a [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-25 13:54:15 +00:00
Travis CI User
fa0fdff8d4 [maven-release-plugin][skip ci] prepare release 20.25 2022-11-25 13:54:12 +00:00
kcichonczyk
c37b26e678 [ACS-4053] updated INSIGHT_ENGINE_TAG and SOLR tag to 2.0.5.1 (#1578) 2022-11-25 14:17:20 +01:00
Travis CI User
b5e13e253a [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-24 16:27:05 +00:00
Travis CI User
5b5164420f [maven-release-plugin][skip ci] prepare release 20.24 2022-11-24 16:27:02 +00:00
George Evangelopoulos
17c09efb93 ACS-4064: fix for linking from a folder with inherited rules (#1577)
* ACS-4064: fix for linking from a folder with inherited rules

* ACS-4064: fix failing tests and add E2E
2022-11-24 15:48:27 +00:00
Travis CI User
f96304bd28 [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-24 14:20:41 +00:00
Travis CI User
499f679c8c [maven-release-plugin][skip ci] prepare release 20.23 2022-11-24 14:20:38 +00:00
Piotr Żurek
80c6a0127d MNT-22686 Load template from the classpath (#1576) 2022-11-24 14:40:13 +01:00
Travis CI User
74e44acb1c [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-23 18:24:44 +00:00
Travis CI User
f4d66debea [maven-release-plugin][skip ci] prepare release 20.22 2022-11-23 18:24:41 +00:00
George Evangelopoulos
af838043c9 ACS-3964: fix for non-inheritable rules still appearing in inherited rule sets (#1565)
* ACS-3964: fix for non-inheritable rules still appearing in inherited rule sets

* ACS-3964: fix failing E2Es and add negative test
2022-11-23 16:24:15 +00:00
Travis CI User
1245647a9f [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-23 15:48:46 +00:00
Travis CI User
fe35f312bb [maven-release-plugin][skip ci] prepare release 20.21 2022-11-23 15:48:43 +00:00
Kacper Magdziarz
a5f16f1b11 Fix/mnt 22686 allow complex rest action params (#1569)
* MNT-22686 Allow more complex action params

* MNT-22686 Add email template test

Co-authored-by: pzurek <Piotr.Zurek@hyland.com>
Co-authored-by: Sara Aspery <sara.aspery@alfresco.com>
2022-11-23 15:11:48 +00:00
Sbisht19
38a9f6d3e1 Merge pull request #1531 from Alfresco/feature/APPS-1722
Feature/apps 1722
2022-11-23 14:12:02 +05:30
sbisht
dc512e5ab0 Merge remote-tracking branch 'origin/feature/APPS-1722' into feature/APPS-1722 2022-11-22 11:54:24 +05:30
sbisht
5c8db99231 updated FileVersionAsRecordRuleTest and FileAsRecordRuleTest [ags] 2022-11-22 11:53:37 +05:30
ashiva
e39a97ed8d "MoveToRuleOnFoldersTest changed names from E and NE to ELECTRONIC AND NON-ELECTRONIC RECORDS"[ags] 2022-11-22 06:07:53 +00:00
Travis CI User
ad0ad081c6 [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-20 00:10:49 +00:00
Travis CI User
8b9513ca8f [maven-release-plugin][skip ci] prepare release 20.20 2022-11-20 00:10:46 +00:00
Alfresco CI User
5b3582c051 [force] Force release for 2022-11-20. 2022-11-20 00:03:27 +00:00
Travis CI User
ccba1768bd [maven-release-plugin][skip ci] prepare for next development iteration 2022-11-18 09:49:39 +00:00
ashiva
f03790e278 "MoveToRuleOnFoldersTest Completed With Creation of updateMetaData method and declration of variables to global scope"[ags] 2022-11-17 13:00:40 +00:00
ashiva
2c979ea71e "MoveToRuleOnFoldersTest Completed Refactor of code left"[ags] 2022-11-17 11:57:09 +00:00
ashiva
227c74a8bd Merge remote-tracking branch 'origin/feature/APPS-1722' into feature/APPS-1722 2022-11-16 13:56:30 +00:00
ashiva
24aa64c165 "MoveToRuleOnFoldersTest initial changes made"[ags] 2022-11-16 13:55:47 +00:00
cchandan
183873166c Added FileAsRecordRuleTests [ags] 2022-11-16 16:57:24 +05:30
sbisht
1c9419d635 updated CopyToRuleOnFoldersTest [ags] 2022-11-16 11:47:27 +05:30
sbisht
17b04d7321 updated FileVersionAsRecordRuleTest [ags] 2022-11-15 16:38:12 +05:30
sbisht
fe5faa3263 updated CopyToRuleOnFoldersTest [ags] 2022-11-15 12:16:44 +05:30
sbisht
63b0ff8cf4 Added FileVersionAsRecordRuleTest [ags] 2022-11-09 10:34:29 +05:30
sbisht
15c99b0c10 Merge remote-tracking branch 'origin/feature/APPS-1722' into feature/APPS-1722 2022-11-09 10:33:47 +05:30
sbisht
0f24f453c8 Added FileVersionAsRecordRuleTest [ags] 2022-11-09 10:33:14 +05:30
ashiva
03ce7e37d4 "MoveToRuleOnFoldersTest added metadata update and and copy of records"[ags] 2022-11-04 15:39:08 +00:00
ashiva
1a5740eec1 Merge remote-tracking branch 'origin/feature/APPS-1722' into feature/APPS-1722 2022-11-04 15:33:19 +00:00
ashiva
f55602842d "MoveToRuleOnFoldersTest added metadata update and and copy of records"[ags] 2022-11-04 15:32:37 +00:00
sbisht
7819e29bcc Added FileVersionAsRecordRuleTest [ags] 2022-11-04 16:37:18 +05:30
sbisht
91031ca72a Added FileAsRecordRuleTests [ags] 2022-11-04 15:48:03 +05:30
cchandan
32314480a1 Added FileAsRecordRuleTests [ags] 2022-11-04 15:10:49 +05:30
ashiva
f49b7a393f "MoveToRuleOnFoldersTest added rule and folder creation" 2022-11-04 08:20:04 +00:00
cchandan
d32ba12405 Merge remote-tracking branch 'origin/feature/APPS-1722' into feature/APPS-1722 2022-11-04 13:39:44 +05:30
cchandan
7430c80a41 Added FileAsRecordRuleTests [ags] 2022-11-04 13:39:11 +05:30
ashiva
af2c11063b [ags]"MoveToRuleOnFoldersTest converted" 2022-11-02 07:26:06 +00:00
ashiva
0d74540b2b Merge branch 'feature/APPS-1722' of github.com:Alfresco/alfresco-community-repo into feature/APPS-1722 2022-11-02 07:18:54 +00:00
ashiva
d68ceb1a4b [ags]"MoveToRuleOnFoldersTest converted" 2022-11-02 07:06:46 +00:00
shishuraj.bisht
379f65db0d Added copyToRuleOnFoldersTest [ags] 2022-11-01 17:40:07 +05:30
50 changed files with 1656 additions and 50 deletions

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,118 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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.rm.community.rules;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.rest.rm.community.smoke.CreateCategoriesTests;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.test.AlfrescoTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.Collections;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.*;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.*;
public class CopyToRuleOnFoldersTest extends BaseRMRestTest {
private RecordCategory category;
private RecordCategoryChild folder1,folder2;
private final static String title = "Run in background";
private final String TEST_PREFIX = generateTestPrefix(CopyToRuleOnFoldersTest.class);
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
private final String electronicRecord = TEST_PREFIX + "record_electronic_for_copyTo";
private final String nonElectronicRecord = TEST_PREFIX + "record_non_electronic_for_copyTo";
@Autowired
private RulesAPI rulesAPI;
@Test
@AlfrescoTest(jira = "RM-2994")
public void copyToRuleOnFoldersTest()
{
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description1")
.runInBackground(true).title(title)
.actions(Collections.singletonList(ActionsOnRule.COPY_TO.getActionValue()));
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create record categories and record folders");
category= createRootCategory(getRandomName("recordCategory"));
String folder1 = createCategoryFolderInFilePlan().getId();
String folder2 = createCategoryFolderInFilePlan().getId();
// create a rule on folder
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folder1, ruleDefinition);
// create electronic record in record folder
String electronicRecordId = createElectronicRecord(folder1, ELECTRONIC_RECORD_NAME).getId();
assertStatusCode(CREATED);
// create non-electronic record in record folder
String nonElectronicRecord = createElectronicRecord(folder1, NONELECTRONIC_RECORD_NAME).getId();
assertStatusCode(CREATED);
// Move the electronic and non-electronic records from "Category with records"> "Folder with rule"
// to "Copy Category with records" > "Folder with rule"
getRestAPIFactory().getNodeAPI(toContentModel(folder1)).copy(createBodyForMoveCopy(category.getId()));
getRestAPIFactory().getNodeAPI(toContentModel( electronicRecord)).move(createBodyForMoveCopy(folder2));
getRestAPIFactory().getNodeAPI(toContentModel( nonElectronicRecord)).move(createBodyForMoveCopy(folder2));
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// Delete the record category
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
String recordCategoryId = category.getId();
recordCategoryAPI.deleteRecordCategory(recordCategoryId);
recordsAPI.deleteRecord(electronicRecord);
recordsAPI.deleteRecord(nonElectronicRecord);
assertStatusCode(NO_CONTENT);
}
}

View File

@@ -0,0 +1,229 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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.rm.community.rules;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.smoke.FileAsRecordTests;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.CREATED;
@AlfrescoTest (jira = "APPS-36")
public class FileAsRecordRuleTests extends BaseRMRestTest
{
private UserModel nonRMUser, rmManager;
private RecordCategory category_manager, category_admin;
private RecordCategoryChild folder_admin, folder_manager ;
private static final String CATEGORY_MANAGER = "catManager" + generateTestPrefix(FileAsRecordTests.class);
private static final String CATEGORY_ADMIN = "catAdmin" + generateTestPrefix(FileAsRecordTests.class);
private static final String FOLDER_MANAGER = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
private static final String FOLDER_ADMIN = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
private FolderModel testFolder;
private FileModel document,inPlaceRecord;
@Autowired
private RoleService roleService;
@Autowired
private RulesAPI rulesAPI;
/**
* Create preconditions:
* 1. RM site is created
* 2. Two users: user without RM role and a user with RM manager role
* 3. Two Record categories with one folder each
* 4. User with RM MANAGER role has Filling permission over one category
* 5. A collaboration folder with rule set to declare and file as record to a record folder
**/
@BeforeClass(alwaysRun = true)
public void preconditionForDeclareFileAsRecordRuleTests()
{
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create a user");
nonRMUser = dataUser.createRandomTestUser("testUser");
STEP("Create a collaboration site");
testSite = dataSite.usingUser(nonRMUser).createPublicRandomSite();
STEP("Create two categories with two folders");
category_manager = createRootCategory(CATEGORY_MANAGER);
category_admin = createRootCategory(CATEGORY_ADMIN);
folder_admin = createFolder(category_admin.getId(),FOLDER_ADMIN);
folder_manager = createFolder(category_manager.getId(),FOLDER_MANAGER);
STEP("Create an rm user and give filling permission over CATEGORY_MANAGER record category");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
rmManager = roleService.createCollaboratorWithRMRoleAndPermission(testSite, recordCategory,
UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
STEP("Create a collaboration folder with a rule set to declare and file as record to a record folder");
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
assertStatusCode(CREATED);
}
/**
* Given I am a user that can create a rule on a folder in a collaboration site
* When I am creating the rule
* Then I have the option of adding a "Declare and File as Record" action to the rule
* <p>
* Given I am creating a rule
* When I add the "Declare and File as Record" action to the rule
* Then I am able to select the record folder I want the declared record to be filed to
* <p>
* Given I am configuring a "Declare and File as Record" action within a rule
* And I have at least one records management role (eg RM User)
* When I am selecting the record folder location to file the declared record to
* Then I see the record folders in the file plan that I have file access to as the creator of the record
**/
@Test
public void declareAsRecordRuleAsRMUserWithFilingPermissions() {
STEP("Create a collaboration folder");
testFolder = dataContent.usingSite(testSite)
.usingUser(rmManager)
.createFolder();
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
assertStatusCode(CREATED);
}
/**
* Given I am configuring a "Declare and File as Record" action within a rule
* And I don't have a records management role
* When I am selecting the record folder location to file the declared record to
* Then I can see only the file plan
*/
@Test
public void declareAsRecordRuleAsNonRMUser()
{
STEP("Create a collaboration folder");
testFolder = dataContent.usingSite(testSite)
.usingUser(nonRMUser)
.createFolder();
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(nonRMUser.getUsername(), nonRMUser.getPassword(), NODE_PREFIX + testFolder.getNodeRef(), ruleDefinition);
assertStatusCode(CREATED);
}
/**
* Given I have not selected a record folder location
* When the rule is triggered
* Then the file is declared as record to the UnFiled Records folder
*/
@Test
public void triggerDeclareToUnfiledRuleAsNonRMUser()
{
STEP("Create a collaboration folder with a rule set to declare and file as record without a record folder location");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
assertStatusCode(CREATED);
STEP("Create as nonRMUser a new file into the previous folder in order to trigger the rule");
inPlaceRecord = dataContent.usingUser(nonRMUser).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
// Verify that declared record is in Unfilled Records Folder
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
List<UnfiledContainerChildEntry> matchingRecords = unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.filter(e -> e.getEntry().getId().equals(inPlaceRecord.getNodeRefWithoutVersion()))
.collect(Collectors.toList());
}
@AfterClass(alwaysRun = true)
public void cleanupDeclareAsRecordRuleTests()
{
STEP("Delete the collaboration site");
dataSite.usingUser(nonRMUser).deleteSite(testSite);
STEP("Delete Users");
dataUser.deleteUser(nonRMUser);
dataUser.deleteUser(rmManager);
STEP("Delete categories");
getRestAPIFactory().getFilePlansAPI().getRootRecordCategories(FILE_PLAN_ALIAS).getEntries().forEach(recordCategoryEntry ->
deleteRecordCategory(recordCategoryEntry.getEntry().getId()));
}
}

View File

@@ -0,0 +1,221 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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.rm.community.rules;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.smoke.FileAsRecordTests;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.CREATED;
public class FileVersionAsRecordRuleTest extends BaseRMRestTest {
private UserModel nonRMuser, rmManager;
private RecordCategory category_manager, category_admin;
private RecordCategoryChild folder_admin, folder_manager ;
private static final String CATEGORY_MANAGER = "catManager" + generateTestPrefix(FileAsRecordTests.class);
private static final String CATEGORY_ADMIN = "catAdmin" + generateTestPrefix(FileAsRecordTests.class);
private static final String FOLDER_MANAGER = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
private static final String FOLDER_ADMIN = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
private FolderModel testFolder;
private FileModel document,inPlaceRecord;
@Autowired
private RoleService roleService;
@Autowired
private RulesAPI rulesAPI;
@BeforeClass(alwaysRun = true)
public void createTestPrecondition()
{
STEP("Create the RM site if doesn't exist");
createRMSiteIfNotExists();
STEP("Create a user");
nonRMuser = dataUser.createRandomTestUser("testUser");
STEP("Create a collaboration site");
testSite = dataSite.usingUser(nonRMuser).createPublicRandomSite();
STEP("Create a document with the user without RM role");
document = dataContent.usingSite(testSite)
.usingUser(nonRMuser)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
STEP("Create two categories with two folders");
category_manager = createRootCategory(CATEGORY_MANAGER);
category_admin = createRootCategory(CATEGORY_ADMIN);
folder_admin = createFolder(category_admin.getId(),FOLDER_ADMIN);
folder_manager = createFolder(category_manager.getId(),FOLDER_MANAGER);
STEP("Create an rm user and give filling permission over CATEGORY_MANAGER record category");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId())
.build();
rmManager = roleService.createCollaboratorWithRMRoleAndPermission(testSite, recordCategory,
UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
STEP("Create a collaboration folder with a rule set to declare and file version as record to a record folder");
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
assertStatusCode(CREATED);
}
@Test
public void declareVersionAsRecordRuleAsRMUserWithFilingPermissions()
{
STEP("Create a collaboration folder");
testFolder = dataContent.usingSite(testSite)
.usingUser(rmManager)
.createFolder();
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(rmManager.getUsername(), rmManager.getPassword(), NODE_PREFIX + testFolder.getNodeRef(), ruleDefinition);
assertStatusCode(CREATED);
}
@Test
public void declareVersionAsRecordRuleAsNonRMUser()
{
STEP("Create a collaboration folder");
testFolder = dataContent.usingSite(testSite)
.usingUser(nonRMuser)
.createFolder();
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(nonRMuser.getUsername(), nonRMuser.getPassword(), NODE_PREFIX + testFolder.getNodeRef(), ruleDefinition);
assertStatusCode(CREATED);
}
@Test
public void triggerDeclareToUnfiledRuleAsNonRMUser() throws Exception {
STEP("Create a collaboration folder with a rule set to declare and file as record without a record folder location");
FileModel inplaceRecord = dataContent.usingSite(testSite).usingUser(nonRMuser)
.createContent(new FileModel("declareAndFileToIntoUnfiledRecordFolder",
FileType.TEXT_PLAIN));
RecordCategory recordCategory = new RecordCategory().builder()
.id(category_manager.getId()).build();
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
.applyToChildren(true)
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
rulesAPI.createRule(nonRMuser.getUsername(), nonRMuser.getPassword(), NODE_PREFIX + inplaceRecord.getNodeRef(), ruleDefinition);
assertStatusCode(CREATED);
STEP("Create as nonRMuser a new file into the previous folder in order to trigger the rule");
inPlaceRecord = dataContent.usingUser(nonRMuser).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
// verify the declared record is in Unfilled Records folder
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
List<UnfiledContainerChildEntry> matchingRecords = unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.filter(e -> e.getEntry().getId().equals(inplaceRecord.getNodeRefWithoutVersion()))
.collect(Collectors.toList());
}
@AfterClass(alwaysRun = true)
public void cleanupDeclareVersionAsRecordRuleTests()
{
STEP("Delete the collaboration site");
dataSite.usingUser(nonRMuser).deleteSite(testSite);
STEP("Delete Users");
dataUser.deleteUser(nonRMuser);
dataUser.deleteUser(rmManager);
STEP("Delete categories");
getRestAPIFactory().getFilePlansAPI().getRootRecordCategories(FILE_PLAN_ALIAS).getEntries().forEach(recordCategoryEntry ->
deleteRecordCategory(recordCategoryEntry.getEntry().getId()));
}
}

View File

@@ -0,0 +1,237 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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.rm.community.rules;
import org.alfresco.rest.model.RestNodeModel;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
import org.alfresco.rest.rm.community.model.rules.ConditionsOnRule;
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.search.RestRequestQueryModel;
import org.alfresco.rest.v0.HoldsAPI;
import org.alfresco.rest.v0.RecordsAPI;
import org.alfresco.rest.v0.RulesAPI;
import org.alfresco.rest.v0.service.RoleService;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import static java.lang.Integer.MAX_VALUE;
import static java.util.Arrays.asList;
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.*;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.*;
import static org.testng.Assert.assertNotNull;
public class MoveToRuleOnFoldersTest extends BaseRMRestTest{
private RecordCategoryChild recordFolder2;
private RecordCategoryChild recordFolder1;
private String nonElectronicId;
public Record electronicRecord;
private String ruleType = ConditionsOnRule.UPDATE.getWhenConditionValue();
private UserModel rmAdmin;
public RecordCategory RecordCategoryOne;
private RecordCategoryChild recordFolder;
public static final String RECORD_FOLDER_ONE = "record-folder-one";
private final String TEST_PREFIX = generateTestPrefix(MoveToRuleOnFoldersTest.class);
private final String RECORD_CATEGORY_ONE = TEST_PREFIX + "category";
private final String recordName = "Test record";
private final String recordTitle = recordName + " title";
private final String recordDescription = recordName + " description";
private Record nonElectrinicRecordModel;
private RecordFolderAPI recordFolderAPI;
public String title,description,box,file,shelf,storageLocation,name;
@Autowired
private RulesAPI rulesAPI;
@Autowired
private HoldsAPI holdsAPI;
@Autowired
private RoleService roleService;
@Autowired
public RecordsAPI recordsAPI;
@BeforeClass(alwaysRun = true)
public void precondition()
{
//create RM site
createRMSiteIfNotExists();
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
//create root category, create folders , add electronic and non electronic records
RecordCategoryOne = createRootCategory(RECORD_CATEGORY_ONE);
recordFolder1=createRecordFolder(RecordCategoryOne.getId(), getRandomName("recFolder"));
// recordFolder1_id = createRecordFolder(RecordCategoryOne.getId(), getRandomName("recFolder")).getId();
recordFolder2 = createFolder(getAdminUser(),RecordCategoryOne.getId(),getRandomName("recFolder"));
STEP("CREATE ELECTRONIC RECORD");
recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder1.getId(), getFile(IMAGE_FILE));
STEP("Check the electronic record has been created");
assertStatusCode(CREATED);
STEP("Create a non-electronic record by completing some of the fields");
// Use these properties for non-electronic record to be created
title = "Title " + getRandomAlphanumeric();
description = "Description " + getRandomAlphanumeric();
box = "Box "+ getRandomAlphanumeric();
file = "File " + getRandomAlphanumeric();
shelf = "Shelf " + getRandomAlphanumeric();
storageLocation = "Storage Location " + getRandomAlphanumeric();
name = "Record " + getRandomAlphanumeric();
Random random = new Random();
Integer numberOfCopies = random.nextInt(MAX_VALUE);
Integer physicalSize = random.nextInt(MAX_VALUE);
// Set values of all available properties for the non electronic records
nonElectrinicRecordModel = createFullNonElectronicRecordModel(name, title, description, box, file, shelf, storageLocation, numberOfCopies, physicalSize);
// Create non-electronic record
nonElectronicId = recordFolderAPI.createRecord(nonElectrinicRecordModel, recordFolder1.getId()).getId();
STEP("Check the non-electronic record has been created");
assertStatusCode(CREATED);
}
@Test
public void MoveToRuleFoldersTest()
{
String CatName=RecordCategoryOne.getName();
String folder2name=recordFolder2.getName();
String recfolder2_path="/"+CatName+"/"+folder2name;
STEP("create a rule MOVE_TO for folder 1");
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description1")
.runInBackground(true).title(title)
.actions(Collections.singletonList(ActionsOnRule.MOVE_TO.getActionValue())).ruleType(ruleType).path(recfolder2_path);
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX +recordFolder1.getId() , ruleDefinition);
STEP("Update metadata for Non-Electronic Record");
updateRecordMetadata();
STEP("Delete ELECTRONIC AND NON-ELECTRONIC RECORDS IN FOLDER 2");
org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
recordsAPI.deleteRecord(electronicRecord.getId());
assertStatusCode(NO_CONTENT);
recordsAPI.deleteRecord(nonElectronicId);
assertStatusCode(NO_CONTENT);
STEP("RULE CREATION FOR FOLDER 1 WITHOUT RUNNING IN BACKGROUND");
RuleDefinition ruleDefinition_notinbackground = RuleDefinition.createNewRule().title("name").description("description1")
.runInBackground(false).title(title)
.actions(Collections.singletonList(ActionsOnRule.MOVE_TO.getActionValue())).ruleType(ruleType).path(recfolder2_path);
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX +recordFolder1.getId() , ruleDefinition);
STEP("CREATE ELECTRONIC AND NON-ELECTRONIC RECORDS");
electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder1.getId(), getFile(IMAGE_FILE));
STEP("Check the electronic record has been created");
assertStatusCode(CREATED);
nonElectronicId = recordFolderAPI.createRecord(nonElectrinicRecordModel, recordFolder1.getId()).getId();
STEP("Check the non-electronic record has been created");
assertStatusCode(CREATED);
STEP("UPDATE METADATA");
updateRecordMetadata();
STEP("CHECK IF ELECTRONIC AND NON-ELECTRONIC RECORDS MOVED TO FOLDER2");
updateRecordMetadata();
}
@AfterClass(alwaysRun = true)
public void cleanMoveToRuleOnFoldersTest()
{
deleteRecordCategory(RecordCategoryOne.getId());
getDataUser().deleteUser(rmAdmin);
}
private String getModifiedPropertyValue(String originalValue) {
/* to be used to append to modifications */
String MODIFIED_PREFIX = "modified_";
return MODIFIED_PREFIX + originalValue;
}
private void updateRecordMetadata(){
STEP("Update metadata for Non-Electronic Record");
org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
Record nonelecrecord = recordsAPI.getRecord(nonElectronicId);
String nonelecnewName = getModifiedPropertyValue(nonElectrinicRecordModel.getName());
String nonelecnewTitle = getModifiedPropertyValue(nonElectrinicRecordModel.getProperties().getTitle());
String nonelecnewDescription = getModifiedPropertyValue(nonElectrinicRecordModel.getProperties().getDescription());
recordsAPI.updateRecord(createRecordModel(nonelecnewName, nonelecnewDescription, nonelecnewTitle),nonelecrecord.getId());
assertStatusCode(OK);
STEP("Update metadata for Electronic Record");
Record elecrecord = recordsAPI.getRecord(electronicRecord.getId());
String elecnewName = getModifiedPropertyValue(electronicRecord.getName());
String elecnewTitle = getModifiedPropertyValue(electronicRecord.getProperties().getTitle());
String elecnewDescription = getModifiedPropertyValue(electronicRecord.getProperties().getDescription());
recordsAPI.updateRecord(createRecordModel(elecnewName, elecnewDescription, elecnewTitle),elecrecord.getId());
assertStatusCode(OK);
}
}

View File

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

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.5
SOLR6_TAG=2.0.5.1
POSTGRES_TAG=14.4
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8

View File

@@ -175,6 +175,10 @@
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.events.EventEntityResource">
<property name="recordsManagementEventService" ref="RecordsManagementEventService" />
</bean>
<!-- extended sites bean definition -->
<bean id="rm.sites" class="org.alfresco.rm.rest.api.impl.RMSitesImpl" parent="sites">
<property name="siteSurfConfig" ref="rm.siteSurfConfig" />

View File

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

View File

@@ -0,0 +1,76 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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.rm.rest.api.events;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.EventInfo;
import java.util.List;
import java.util.stream.Collectors;
/**
* Event entity resource
*/
@EntityResource(name = "events", title = "Events")
public class EventEntityResource implements EntityResourceAction.Read<EventInfo> {
private RecordsManagementEventService recordsManagementEventService;
/**
* Set the records management event service
*
* @param rmEventService Records management event service
*/
public void setRecordsManagementEventService(RecordsManagementEventService rmEventService)
{
this.recordsManagementEventService = rmEventService;
}
@Override
@WebApiDescription(title = "Return a list of events")
public CollectionWithPagingInfo<EventInfo> readAll(Parameters params)
{
Paging paging = params.getPaging();
List<EventInfo> eventInfoList = recordsManagementEventService.getEvents().stream()
.map(EventInfo::fromRecordsManagementEvent)
.collect(Collectors.toList());
int totalCount = eventInfoList.size();
boolean hasMoreItems = paging.getSkipCount() + paging.getMaxItems() < totalCount;
return CollectionWithPagingInfo.asPaged(paging, eventInfoList.stream()
.skip(paging.getSkipCount())
.limit(paging.getMaxItems())
.collect(Collectors.toList()), hasMoreItems, totalCount);
}
}

View File

@@ -0,0 +1,34 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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 info that defines the Information Governance Events REST API
*/
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
package org.alfresco.rm.rest.api.events;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.WebApi;

View File

@@ -0,0 +1,82 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* 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.rm.rest.api.model;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
/**
* The EventInfo model to be exposed through REST API.
*/
public class EventInfo {
private String id;
private String name;
private String type;
public static EventInfo fromRecordsManagementEvent(RecordsManagementEvent event)
{
EventInfo eventInfo = new EventInfo();
if (event != null) {
eventInfo.setName(event.getDisplayLabel());
eventInfo.setId(event.getName());
eventInfo.setType(event.getType());
}
return eventInfo;
}
public EventInfo() {}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
}

View File

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

View File

@@ -38,6 +38,9 @@ tags:
description: Retrieve and manage unfiled records containers
- name: unfiled-record-folders
description: Retrieve and manage unfiled record folders
- name: events
description: Retrieve and manage retention events
paths:
## GS sites
'/gs-sites':
@@ -2091,7 +2094,172 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/events':
get:
tags:
- events
summary: List all available retention events
description: |
Gets the list of events that can be used by retention steps
operationId: getAllEvents
produces:
- application/json
parameters:
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/EventPaging'
'400':
description: |
Invalid parameter: value of **maxItems** or **skipCount** is invalid
'401':
description: Authentication failed
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
post:
tags:
- events
summary: Create a new retention event
description: |
Creates a new event that can be used by retention schedules.
operationId: createEvent
parameters:
- in: body
name: eventBodyCreate
description: The new event.
required: true
schema:
$ref: '#/definitions/EventBody'
consumes:
- application/json
produces:
- application/json
responses:
'201':
description: Successful response
schema:
$ref: '#/definitions/EventEntry'
'400':
description: |
Invalid parameter: **name** or **type** is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to create event
'409':
description: Cannot create event. An event with the name **name** already exists
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/events/{eventId}':
get:
tags:
- events
summary: Return event for given eventId
description: |
Gets information about the retention event with id **eventId**.
operationId: getEvent
produces:
- application/json
parameters:
- $ref: '#/parameters/eventIdParam'
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/EventEntry'
'400':
description: |
Invalid parameter: **eventId** is invalid
'401':
description: Authentication failed
'404':
description: "**eventId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
put:
tags:
- events
summary: Update event for given eventId
operationId: updateEvent
description: |
Updates retention event with id **eventId**.
produces:
- application/json
parameters:
- $ref: '#/parameters/eventIdParam'
- in: body
name: eventBodyUpdate
description: The event information to update.
required: true
schema:
$ref: '#/definitions/EventBody'
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/EventEntry'
'400':
description: |
Invalid parameter: The update request is invalid or **eventId** is not a valid format or **eventBodyUpdate** is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to update events
'404':
description: "**eventId** does not exist"
'409':
description: Cannot update event. An event with the name **name** already exists
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/event-types':
get:
tags:
- events
summary: List all the retention event types
description: |
Gets a list of all the retention event types.
operationId: getAllEventTypes
produces:
- application/json
parameters:
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/EventTypePaging'
'400':
description: |
Invalid parameter: value of **maxItems** or **skipCount** is invalid
'401':
description: Authentication failed
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
parameters:
## event
eventIdParam:
name: eventId
in: path
description: The identifier of an event.
required: true
type: string
## File plans
filePlanEntryIncludeParam:
name: include
@@ -3760,3 +3928,91 @@ definitions:
- SiteCollaborator
- SiteContributor
- SiteManager
EventPaging:
type: object
properties:
list:
type: object
properties:
pagination:
$ref: '#/definitions/Pagination'
entries:
type: array
items:
$ref: '#/definitions/EventEntry'
EventEntry:
type: object
required:
- entry
properties:
entry:
$ref: '#/definitions/Event'
Event:
type: object
required:
- id
- name
- type
properties:
id:
type: string
description: this is the id of the event
name:
type: string
description: This is the unique display label of the event
type:
type: string
description: this is event type
EventBody:
type: object
required:
- name
properties:
name:
type: string
description: This is the unique display label of the event
type:
type: string
description: this is event type
default: Simple
EventTypePaging:
type: object
properties:
list:
type: object
properties:
pagination:
$ref: '#/definitions/Pagination'
entries:
type: array
items:
$ref: '#/definitions/EventTypeEntry'
EventTypeEntry:
type: object
required:
- entry
properties:
entry:
$ref: '#/definitions/EventType'
EventType:
type: object
required:
- id
- name
properties:
id:
type: string
description: this is the event type id
name:
type: string
description: this is event type name
isAutomatic:
type: boolean
description: Whether events of this type need completing manually or can be completed automatically
default: true
associationName:
type: string
description: The association used to determine whether automatic events of this type are complete
actionOnAssociatedNode:
type: string
description: If an association name is set for this event type then it is possible to require an action to be completed on the associated node

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.5
SOLR6_TAG=2.0.5.1
POSTGRES_TAG=14.4
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>20.19</version>
<version>20.28-SNAPSHOT</version>
</parent>
<organization>

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,103 @@
package org.alfresco.rest.actions.email;
import static java.util.Objects.requireNonNull;
import static org.hamcrest.Matchers.notNullValue;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.json.JsonObject;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.core.JsonBodyGenerator;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class EmailTemplateTest extends RestTest {
public static final String MAIL_ACTION = "mail";
private UserModel adminUser;
private UserModel testUser;
private FolderModel testFolder;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception {
adminUser = dataUser.getAdminUser();
testUser = dataUser.createRandomTestUser();
testSite = dataSite.usingUser(testUser)
.createPublicRandomSite();
testFolder = dataContent.usingUser(testUser)
.usingSite(testSite)
.createFolder();
}
@Test
public void adminCanSendEmailUsingTemplateWithModelAsString() throws Exception
{
String templateId = uploadEmailTemplate("simpleEmailTemplate.ftl");
// Create the model for use with email template
JsonObject args = JsonBodyGenerator.defineJSON()
.add("args", JsonBodyGenerator.defineJSON()
.add("name", "testname")
.build())
.build();
String emailModel = args.toString();
// Send an email using the template
restClient.authenticateUser(adminUser)
.withCoreAPI()
.usingActions()
.executeAction(MAIL_ACTION, testFolder, createMailWithTemplateParameters(adminUser, testUser, templateId, emailModel));
restClient.onResponse()
.assertThat().statusCode(HttpStatus.ACCEPTED.value())
.assertThat().body("entry.id", notNullValue());
}
private String uploadEmailTemplate(String templateName) throws IOException
{
final String templateContent = getTemplateContent(templateName);
final FileModel templateToCreate = new FileModel(templateName, FileType.TEXT_PLAIN, templateContent);
final FileModel createdTemplate = dataContent.usingAdmin()
.usingResource(testFolder)
.createContent(templateToCreate);
return createdTemplate.getNodeRef();
}
private String getTemplateContent(String templateName) throws IOException
{
final String templateClasspathLocation = "/shared-resources/testdata/" + templateName;
try (InputStream templateStream = getClass().getResourceAsStream(templateClasspathLocation))
{
requireNonNull(templateStream, "Couldn't locate `" + templateClasspathLocation + "`");
return new String(templateStream.readAllBytes());
}
}
private static Map<String, Serializable> createMailWithTemplateParameters(UserModel sender, UserModel recipient, String templateId, Serializable model)
{
Map<String, Serializable> parameterValues = new HashMap<>();
parameterValues.put("from", sender.getEmailAddress());
parameterValues.put("to", recipient.getEmailAddress());
parameterValues.put("subject", "Test");
parameterValues.put("template", "workspace://SpacesStore/" + templateId);
parameterValues.put("template_model", model);
return parameterValues;
}
}

View File

@@ -25,6 +25,7 @@
*/
package org.alfresco.rest.rules;
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.testng.Assert.assertEquals;
@@ -38,10 +39,12 @@ import org.alfresco.rest.model.RestRuleModelsCollection;
import org.alfresco.rest.model.RestRuleSetLinkModel;
import org.alfresco.rest.model.RestRuleSetModel;
import org.alfresco.rest.model.RestRuleSetModelsCollection;
import org.alfresco.rest.model.RestRuleSettingsModel;
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.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -71,26 +74,96 @@ public class GetInheritedRulesTests extends RestTest
STEP("Create a parent and child folder, each with inheriting rules");
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
RestRuleModel parentRule = rulesUtils.createRuleModelWithDefaultValues();
RestRuleModel parentRule = rulesUtils.createInheritableRuleModel();
parentRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(parentRule);
restClient.assertStatusCodeIs(HttpStatus.CREATED);
RestRuleSettingsModel enabled = new RestRuleSettingsModel();
enabled.setValue(true);
restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabled);
restClient.assertStatusCodeIs(HttpStatus.OK);
RestRuleModel childRule = rulesUtils.createRuleModelWithDefaultValues();
childRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingDefaultRuleSet().createSingleRule(childRule);
restClient.assertStatusCodeIs(HttpStatus.CREATED);
STEP("Get the rules in the default rule set for the child folder");
RestRuleModelsCollection rules = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingDefaultRuleSet().getListOfRules();
restClient.assertStatusCodeIs(HttpStatus.OK);
rules.assertThat().entriesListContains("id", childRule.getId())
.and().entriesListCountIs(1);
STEP("Get the rules in the inherited rule set for the child folder");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).include("inclusionType").getListOfRuleSets();
restClient.assertStatusCodeIs(HttpStatus.OK);
String inheritedRuleSetId = ruleSets.getEntries().stream()
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
.findFirst().get().onModel().getId();
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSet(inheritedRuleSetId).getListOfRules();
restClient.assertStatusCodeIs(HttpStatus.OK);
inheritedRules.assertThat().entriesListContains("id", parentRule.getId())
.and().entriesListCountIs(1);
}
/**
* Check we get no (inherited) rules when inheritance is disabled in the child folder.
*/
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getInheritedRules_childFolderInheritanceDisabled()
{
STEP("Create a parent and child folder, with inheritable parent rule");
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
RestRuleModel parentRule = rulesUtils.createInheritableRuleModel();
restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(parentRule);
restClient.assertStatusCodeIs(HttpStatus.CREATED);
STEP("Disable inheritance in the child folder");
RestRuleSettingsModel enabledInheritance = new RestRuleSettingsModel();
enabledInheritance.setValue(false);
restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabledInheritance);
restClient.assertStatusCodeIs(HttpStatus.OK);
STEP("The child folder should have no rule sets");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).getListOfRuleSets();
restClient.assertStatusCodeIs(HttpStatus.OK);
ruleSets.assertThat().entriesListIsEmpty();
}
/**
* Check that non-inheritable rules owned by the parent folder are not found inside the child folder.
*/
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void inheritance_test()
{
STEP("Create a parent and child folder, with an inheritable and a non-inheritable parent rule");
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
RestRuleModel inheritableRule = rulesUtils.createInheritableRuleModel();
inheritableRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(inheritableRule);
restClient.assertStatusCodeIs(HttpStatus.CREATED);
RestRuleModel nonInheritableRule = rulesUtils.createRuleModelWithDefaultValues();
nonInheritableRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(nonInheritableRule);
restClient.assertStatusCodeIs(HttpStatus.CREATED);
STEP("The inherited rule set for the child folder should only return the inheritable rule");
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).include("inclusionType").getListOfRuleSets();
restClient.assertStatusCodeIs(HttpStatus.OK);
String inheritedRuleSetId = ruleSets.getEntries().stream()
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
.findFirst().get().onModel().getId();
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSet(inheritedRuleSetId).getListOfRules();
restClient.assertStatusCodeIs(HttpStatus.OK);
inheritedRules.assertThat().entriesListContains("id", inheritableRule.getId())
.and().entriesListDoesNotContain("id",nonInheritableRule.getId())
.and().entriesListCountIs(1);
}
/**
* Check that we only get each rule once with linking and inheritance, and the order is correct.
* <p>
@@ -110,9 +183,14 @@ public class GetInheritedRulesTests extends RestTest
FolderModel folderB = dataContent.usingUser(user).usingResource(folderA).createFolder();
FolderModel folderC = dataContent.usingUser(user).usingResource(folderB).createFolder();
FolderModel folderD = dataContent.usingUser(user).usingResource(folderC).createFolder();
RestRuleModel ruleB = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderB).usingDefaultRuleSet().createSingleRule(rulesUtils.createRuleModelWithDefaultValues());
RestRuleModel ruleC = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderC).usingDefaultRuleSet().createSingleRule(rulesUtils.createRuleModelWithDefaultValues());
RestRuleModel ruleB = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderB).usingDefaultRuleSet().createSingleRule(rulesUtils.createInheritableRuleModel());
RestRuleModel ruleC = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderC).usingDefaultRuleSet().createSingleRule(rulesUtils.createInheritableRuleModel());
RestRuleModel ruleD = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderD).usingDefaultRuleSet().createSingleRule(rulesUtils.createRuleModelWithDefaultValues());
RestRuleSettingsModel enabled = new RestRuleSettingsModel();
enabled.setValue(true);
restClient.authenticateUser(user).withPrivateAPI().usingNode(folderC).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabled);
restClient.authenticateUser(user).withPrivateAPI().usingNode(folderD).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabled);
STEP("Link folderA to ruleSetD");
RestRuleSetLinkModel linkModel = new RestRuleSetLinkModel();
linkModel.setId(folderD.getNodeRef());

View File

@@ -46,6 +46,7 @@ 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.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -172,6 +173,56 @@ public class RuleSetLinksTests extends RestTest
.get(0).onModel().assertThat().isEqualTo(expectedRuleSet);
}
/**
* Check we can link to a rule set when linking from a folder which has inherited rules.
*/
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
public void linkFromFolderWithInheritedRules()
{
STEP("Create folders");
final FolderModel parentFolder = dataContent.usingUser(user).usingSite(site).createFolder();
final FolderModel childFolder = dataContent.usingUser(user).usingResource(parentFolder).createFolder();
final FolderModel linkedToFolder = dataContent.usingUser(user).usingSite(site).createFolder();
STEP("Create rules in the parent folder and the linking folder");
RestRuleModel parentRule = rulesUtils.createInheritableRuleModel();
parentRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parentFolder).usingDefaultRuleSet().createSingleRule(parentRule);
restClient.assertStatusCodeIs(CREATED);
RestRuleModel linkingFolderRule = rulesUtils.createRuleModelWithDefaultValues();
restClient.authenticateUser(user).withPrivateAPI().usingNode(linkedToFolder).usingDefaultRuleSet().createSingleRule(linkingFolderRule);
restClient.assertStatusCodeIs(CREATED);
STEP("Get the rule sets for the linking folder and find the rule set id");
final RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(linkedToFolder).getListOfRuleSets();
restClient.assertStatusCodeIs(OK);
ruleSets.assertThat().entriesListCountIs(1);
final String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
STEP("Link the child folder to the target folder");
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
request.setId(linkedToFolder.getNodeRef());
final RestRuleSetLinkModel ruleLink = restClient.authenticateUser(user).withPrivateAPI().usingNode(childFolder).createRuleLink(request);
restClient.assertStatusCodeIs(CREATED);
STEP("Assert link result");
final RestRuleSetLinkModel expectedLink = new RestRuleSetLinkModel();
expectedLink.setId(ruleSetId);
ruleLink.assertThat().isEqualTo(expectedLink);
STEP("Assert that the child folder has also inherited the parent rule");
RestRuleSetModelsCollection ruleSetsInh = restClient.authenticateUser(user).withPrivateAPI().usingNode(childFolder).include("inclusionType").getListOfRuleSets();
restClient.assertStatusCodeIs(OK);
String inheritedRuleSetId = ruleSetsInh.getEntries().stream()
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
.findFirst().get().onModel().getId();
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withPrivateAPI().usingNode(childFolder).usingRuleSet(inheritedRuleSetId).getListOfRules();
restClient.assertStatusCodeIs(OK);
inheritedRules.assertThat().entriesListContains("id", parentRule.getId())
.and().entriesListCountIs(1);
}
/**
* Check we get 404 when linking to a non-existing rule set/folder.
*/

View File

@@ -213,6 +213,13 @@ public class RulesTestsUtils
return createRuleModel(RULE_NAME_DEFAULT);
}
public RestRuleModel createInheritableRuleModel()
{
RestRuleModel ruleModel = createRuleModel(RULE_NAME_DEFAULT);
ruleModel.setIsInheritable(true);
return ruleModel;
}
public RestRuleModel createRuleModel(String name)
{
return createRuleModel(name, List.of(createAddAudioAspectAction()));

View File

@@ -0,0 +1,6 @@
<html>
<head></head>
<body>
Hello ${args.name}!
</body>
</html>

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>20.19</version>
<version>20.28-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>20.19</version>
<version>20.28-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -109,7 +109,7 @@
<dependency.jakarta-json-path.version>2.7.0</dependency.jakarta-json-path.version>
<dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
<alfresco.googledrive.version>3.3.1-A2</alfresco.googledrive.version>
<alfresco.googledrive.version>3.3.1-A3</alfresco.googledrive.version>
<alfresco.aos-module.version>1.5.0</alfresco.aos-module.version>
<alfresco.api-explorer.version>7.3.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
@@ -149,7 +149,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>20.19</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>

View File

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

View File

@@ -363,13 +363,13 @@ public class ActionsImpl implements Actions
Map.Entry::getValue));
}
private Map<String, Serializable> extractActionParams(org.alfresco.service.cmr.action.ActionDefinition actionDefinition, Map<String, String> params)
private Map<String, Serializable> extractActionParams(org.alfresco.service.cmr.action.ActionDefinition actionDefinition, Map<String, ?> params)
{
Map<String, Serializable> parameterValues = new HashMap<>();
try
{
for (Map.Entry<String, String> entry : params.entrySet())
for (Map.Entry<String, ?> entry : params.entrySet())
{
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();

View File

@@ -170,7 +170,7 @@ public class RuleSetsImpl implements RuleSets
}
//The folder shouldn't have any pre-existing rules
if (ruleService.hasRules(folderNodeRef)) {
if (ruleService.hasNonInheritedRules(folderNodeRef)) {
throw new InvalidArgumentException("Unable to link to a rule set because the folder has pre-existing rules or is already linked to a rule set.");
}

View File

@@ -26,17 +26,12 @@
package org.alfresco.rest.api.impl.rules;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.access.ActionAccessRestriction;
import org.alfresco.repo.action.executer.ExecuteAllRulesActionExecuter;
import org.alfresco.rest.api.Rules;
import org.alfresco.rest.api.model.mapper.RestModelMapper;
import org.alfresco.rest.api.model.rules.InclusionType;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.api.model.rules.RuleExecution;
import org.alfresco.rest.api.model.rules.RuleSet;
@@ -53,6 +48,14 @@ import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
@Experimental
public class RulesImpl implements Rules
{
@@ -63,6 +66,7 @@ public class RulesImpl implements Rules
private RuleService ruleService;
private NodeValidator validator;
private RuleLoader ruleLoader;
private RuleSetLoader ruleSetLoader;
private ActionPermissionValidator actionPermissionValidator;
private RestModelMapper<Rule, org.alfresco.service.cmr.rule.Rule> ruleMapper;
@@ -75,8 +79,10 @@ public class RulesImpl implements Rules
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
NodeRef ruleSetNode = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
NodeRef owningFolder = ruleService.getOwningNodeRef(ruleSetNode);
RuleSet ruleSet = ruleSetLoader.loadRuleSet(ruleSetNode, folderNodeRef, List.of(INCLUSION_TYPE));
final List<Rule> rules = ruleService.getRules(owningFolder, false).stream()
.filter(ruleModel -> ruleSet.getInclusionType() != InclusionType.INHERITED || ruleModel.isAppliedToChildren())
.map(ruleModel -> ruleLoader.loadRule(ruleModel, includes))
.collect(Collectors.toList());
@@ -182,6 +188,11 @@ public class RulesImpl implements Rules
this.ruleLoader = ruleLoader;
}
public void setRuleSetLoader(RuleSetLoader ruleSetLoader)
{
this.ruleSetLoader = ruleSetLoader;
}
public void setActionPermissionValidator(ActionPermissionValidator actionPermissionValidator)
{
this.actionPermissionValidator = actionPermissionValidator;

View File

@@ -32,7 +32,7 @@ public class Action
private String id;
private String actionDefinitionId;
private String targetId;
Map<String, String> params;
private Map<String, ?> params;
public String getId()
{
@@ -64,12 +64,12 @@ public class Action
this.targetId = targetId;
}
public Map<String, String> getParams()
public Map<String, ?> getParams()
{
return params;
}
public void setParams(Map<String, String> params)
public void setParams(Map<String, ? extends Object> params)
{
this.params = params;
}

View File

@@ -929,6 +929,7 @@
<property name="validator" ref="nodeValidator"/>
<property name="ruleService" ref="RuleService" />
<property name="ruleLoader" ref="ruleLoader"/>
<property name="ruleSetLoader" ref="ruleSetLoader"/>
<property name="actionPermissionValidator" ref="actionPermissionValidator"/>
<property name="ruleMapper" ref="ruleMapper"/>
</bean>

View File

@@ -257,7 +257,7 @@ public class RuleSetsImplTest extends TestCase
String actual = ruleSets.linkToRuleSet(FOLDER_ID,LINK_TO_NODE_ID).getId();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
then(ruleServiceMock).should().hasNonInheritedRules(FOLDER_NODE);
then(runtimeRuleServiceMock).should().getSavedRuleFolderAssoc(LINK_TO_NODE);
then(runtimeRuleServiceMock).shouldHaveNoMoreInteractions();
then(nodeServiceMock).should().addChild(FOLDER_NODE, childNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
@@ -284,7 +284,7 @@ public class RuleSetsImplTest extends TestCase
then(nodeValidatorMock).should().validateRuleSetNode(LINK_TO_NODE_ID,false);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
then(ruleServiceMock).should().hasNonInheritedRules(FOLDER_NODE);
then(runtimeRuleServiceMock).should().getSavedRuleFolderAssoc(LINK_TO_NODE);
then(runtimeRuleServiceMock).shouldHaveNoMoreInteractions();
then(nodeServiceMock).should().addChild(FOLDER_NODE, childNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
@@ -312,7 +312,8 @@ public class RuleSetsImplTest extends TestCase
@Test
public void testLinkToRuleSet_folderShouldntHavePreExistingRules()
{
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true, true);
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true);
given(ruleServiceMock.hasNonInheritedRules(any(NodeRef.class))).willReturn(true);
//when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
@@ -320,7 +321,7 @@ public class RuleSetsImplTest extends TestCase
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
then(ruleServiceMock).should().hasNonInheritedRules(FOLDER_NODE);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(runtimeRuleServiceMock).shouldHaveNoInteractions();
}

View File

@@ -28,6 +28,7 @@ package org.alfresco.rest.api.impl.rules;
import static java.util.Collections.emptyList;
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
import static org.alfresco.rest.api.model.rules.RuleSet.DEFAULT_ID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -51,8 +52,10 @@ import org.alfresco.repo.action.executer.ExecuteAllRulesActionExecuter;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.mapper.RestModelMapper;
import org.alfresco.rest.api.model.rules.Action;
import org.alfresco.rest.api.model.rules.InclusionType;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.api.model.rules.RuleExecution;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
@@ -80,6 +83,7 @@ public class RulesImplTest extends TestCase
private static final String FOLDER_NODE_ID = "dummy-folder-node-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
private static final String RULE_ID = "dummy-rule-id";
private static final String RULE_ID_INHERITED = "dummy-rule-id-inherited";
private static final NodeRef FOLDER_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_NODE_ID);
private static final NodeRef RULE_SET_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final NodeRef RULE_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
@@ -101,15 +105,20 @@ public class RulesImplTest extends TestCase
@Mock
private RuleLoader ruleLoaderMock;
@Mock
private RuleSetLoader ruleSetLoaderMock;
@Mock
private ActionPermissionValidator actionPermissionValidatorMock;
@Mock
private org.alfresco.service.cmr.rule.Rule serviceRuleMock;
@Mock
private Rule ruleMock;
@Mock
private RuleSet ruleSetMock;
@Mock
private Action actionMock;
private org.alfresco.service.cmr.rule.Rule ruleModel = createRule(RULE_ID);
private org.alfresco.service.cmr.rule.Rule ruleModelInherited = createRule(RULE_ID_INHERITED);
@InjectMocks
private RulesImpl rules;
@@ -118,6 +127,9 @@ public class RulesImplTest extends TestCase
@Override
public void setUp() throws Exception
{
ruleModel.applyToChildren(true);
ruleModelInherited.applyToChildren(true);
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(FOLDER_NODE_REF);
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(RULE_SET_NODE_REF);
given(nodeValidatorMock.validateRuleNode(any(), any())).willReturn(RULE_NODE_REF);
@@ -126,13 +138,15 @@ public class RulesImplTest extends TestCase
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel));
given(ruleServiceMock.getOwningNodeRef(RULE_SET_NODE_REF)).willReturn(FOLDER_NODE_REF);
given(ruleSetMock.getInclusionType()).willReturn(InclusionType.INHERITED);
given(ruleLoaderMock.loadRule(ruleModel, INCLUDE)).willReturn(ruleMock);
given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE))).willReturn(ruleSetMock);
}
@Test
public void testGetRules()
{
given(ruleLoaderMock.loadRule(ruleModel, emptyList())).willReturn(ruleMock);
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
@@ -141,6 +155,66 @@ public class RulesImplTest extends TestCase
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
then(ruleLoaderMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull()
.extracting(Collection::size)
.isEqualTo(1);
assertThat(rulesPage.getCollection().stream().findFirst().get()).isEqualTo(ruleMock);
}
@Test
public void testGetRules_ruleNotAppliedToChildren()
{
given(ruleSetMock.getInclusionType()).willReturn(InclusionType.INHERITED);
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel, ruleModelInherited));
ruleModelInherited.applyToChildren(false);
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
then(ruleLoaderMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
.isNotNull()
.extracting(CollectionWithPagingInfo::getCollection)
.isNotNull()
.extracting(Collection::size)
.isEqualTo(1);
assertThat(rulesPage.getCollection().stream().findFirst().get()).isEqualTo(ruleMock);
}
@Test
public void testGetRules_inheritedRuleSet()
{
given(ruleSetMock.getInclusionType()).willReturn(InclusionType.INHERITED);
ruleModelInherited.applyToChildren(false);
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel, ruleModelInherited));
// when
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
@@ -163,6 +237,8 @@ public class RulesImplTest extends TestCase
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)

View File

@@ -78,7 +78,7 @@ public class Action extends org.alfresco.rest.api.model.Action implements Serial
String id = (String) jsonObject.get("id");
String actionDefinitionId = (String) jsonObject.get("actionDefinitionId");
String targetId = (String) jsonObject.get("targetId");
Map<String, String> params = (Map<String, String>) jsonObject.get("params");
Map<String, Object> params = (Map<String, Object>) jsonObject.get("params");
Action action = new Action();
action.setId(id);

View File

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

View File

@@ -459,7 +459,13 @@ public class RuleServiceImpl
public boolean hasRules(NodeRef nodeRef)
{
return getRules(nodeRef).size() != 0;
}
}
@Override
public boolean hasNonInheritedRules(NodeRef nodeRef)
{
return getRules(nodeRef, false).size() != 0;
}
@Override
public List<Rule> getRules(NodeRef nodeRef)

View File

@@ -165,6 +165,15 @@ public interface RuleService
@Auditable(parameters = {"nodeRef"})
public boolean hasRules(NodeRef nodeRef);
/**
* Indicates whether the node in question has any non-inherited rules associated with it.
*
* @param nodeRef the node reference
* @return true if the node has rules associated, false otherwise
*/
@Auditable(parameters = {"nodeRef"})
public boolean hasNonInheritedRules(NodeRef nodeRef);
/**
* Get all the rules associated with an actionable node, including those
* inherited from parents.