From 5dd1f48af67a40ee7ade21fe1fed973c31b9aaa8 Mon Sep 17 00:00:00 2001 From: cagache Date: Tue, 6 Apr 2021 11:32:01 +0300 Subject: [PATCH] Revert "Move Audit Hold events from community to enterprise" This reverts commit 9ee262f1 --- .../community/audit/AuditAddToHoldTests.java | 313 +++++++++++++++++ .../community/audit/AuditCreateHoldTests.java | 189 ++++++++++ .../community/audit/AuditDeleteHoldTests.java | 139 ++++++++ .../audit/AuditRemoveFromHoldTests.java | 329 ++++++++++++++++++ .../rm-audit-context.xml | 25 ++ .../audit/event/AddToHoldAuditEvent.java | 85 +++++ .../audit/event/CreateHoldAuditEvent.java | 88 +++++ .../audit/event/DeleteHoldAuditEvent.java | 82 +++++ .../audit/event/HoldUtils.java | 69 ++++ .../audit/event/RemoveFromHoldAuditEvent.java | 84 +++++ .../event/AddToHoldAuditEventUnitTest.java | 92 +++++ .../event/CreateHoldAuditEventUnitTest.java | 93 +++++ .../event/DeleteHoldAuditEventUnitTest.java | 89 +++++ .../RemoveFromHoldAuditEventUnitTest.java | 95 +++++ 14 files changed, 1772 insertions(+) create mode 100644 rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditAddToHoldTests.java create mode 100644 rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditCreateHoldTests.java create mode 100644 rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditDeleteHoldTests.java create mode 100644 rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditRemoveFromHoldTests.java create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEvent.java create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEvent.java create mode 100644 rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java create mode 100644 rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java create mode 100644 rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEventUnitTest.java create mode 100644 rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEventUnitTest.java diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditAddToHoldTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditAddToHoldTests.java new file mode 100644 index 0000000000..954c074064 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditAddToHoldTests.java @@ -0,0 +1,313 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ +package org.alfresco.rest.rm.community.audit; + +import static java.util.Arrays.asList; + +import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION; +import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON; +import static org.alfresco.rest.rm.community.model.audit.AuditEvents.ADD_TO_HOLD; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH; +import static org.alfresco.utility.Utility.buildPath; +import static org.alfresco.utility.Utility.removeLastSlash; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.google.common.collect.ImmutableMap; + +import org.alfresco.dataprep.CMISUtil; +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.audit.AuditEntry; +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.user.UserPermissions; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.v0.HoldsAPI; +import org.alfresco.rest.v0.service.RMAuditService; +import org.alfresco.rest.v0.service.RoleService; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.constants.UserRole; +import org.alfresco.utility.model.FileModel; +import org.alfresco.utility.model.SiteModel; +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.DataProvider; +import org.testng.annotations.Test; + +/** + * This class contains the tests that check the add to hold event is audited + * + * @author Claudia Agache + * @since 3.3 + */ +@AlfrescoTest (jira = "RM-6859") +public class AuditAddToHoldTests extends BaseRMRestTest +{ + private final String PREFIX = generateTestPrefix(AuditAddToHoldTests.class); + private final String HOLD1 = PREFIX + "hold1"; + private final String HOLD2 = PREFIX + "hold2"; + + @Autowired + private RMAuditService rmAuditService; + @Autowired + private HoldsAPI holdsAPI; + @Autowired + private RoleService roleService; + + private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode; + private SiteModel privateSite; + private RecordCategory recordCategory; + private RecordCategoryChild recordFolder; + private List auditEntries; + private List holdsList = asList(HOLD1, HOLD2); + private List holdsListRef = new ArrayList<>(); + private String hold1NodeRef; + + @BeforeClass (alwaysRun = true) + public void preconditionForAuditAddToHoldTests() throws Exception + { + STEP("Create 2 holds."); + hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), + getAdminUser().getPassword(), HOLD1, HOLD_REASON, HOLD_DESCRIPTION); + String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION); + holdsListRef = asList(hold1NodeRef, hold2NodeRef); + + STEP("Create a new record category with a record folder."); + recordCategory = createRootCategory(getRandomName("recordCategory")); + recordFolder = createRecordFolder(recordCategory.getId(), PREFIX + "recFolder"); + + STEP("Create an user with full rights to add content to a hold."); + rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId); + + STEP("Create a collaboration site."); + privateSite = dataSite.usingUser(rmAdmin).createPrivateRandomSite(); + + STEP("Create users without rights to add content to a hold."); + rmManagerNoReadOnHold = roleService.createUserWithSiteRoleRMRoleAndPermission(privateSite, + UserRole.SiteManager, recordCategory.getId(), UserRoles.ROLE_RM_MANAGER, UserPermissions.PERMISSION_FILING); + rmManagerNoReadOnNode = roleService.createUserWithRMRoleAndRMNodePermission(UserRoles.ROLE_RM_MANAGER.roleId, + hold1NodeRef, UserPermissions.PERMISSION_FILING); + } + + /** + * Data provider with valid nodes that can be added to a hold + * + * @return the node id, the node name and the node path + * @throws Exception + */ + @DataProvider (name = "validNodesForAddToHold") + public Object[][] getValidNodesForAddToHold() throws Exception + { + FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + RecordCategoryChild recordFolderToBeAdded = createRecordFolder(recordCategory.getId(), PREFIX + "recFolderToBeAdded"); + Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record"); + String recordFolderPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(), + recordFolderToBeAdded.getName())); + String recordPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(), + recordFolder.getName(), recordToBeAdded.getName())); + String contentPath = "/Company Home" + contentToBeAdded.getCmisLocation(); + + return new String[][] + { + // a record folder + { recordFolderToBeAdded.getId(), recordFolderToBeAdded.getName(), recordFolderPath }, + // a record + { recordToBeAdded.getId(), recordToBeAdded.getName(), recordPath }, + //an active content, + { contentToBeAdded.getNodeRefWithoutVersion(), contentToBeAdded.getName(), contentPath } + }; + } + + /** + * Given a document/record/record folder is added to a hold + * When I view the audit log + * Then an entry has been created in the audit log that contains the following: + * name of the hold + * name of the document/record/record folder added + * user who added the content + * date the content was added + * path of the node + */ + @Test (dataProvider = "validNodesForAddToHold") + public void addToHoldEventIsAudited(String nodeId, String nodeName, String nodePath) + { + rmAuditService.clearAuditLog(); + + STEP("Add node to hold."); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD1); + + STEP("Check the audit log contains the entry for the add to hold event."); + rmAuditService.checkAuditLogForEvent(getAdminUser(), ADD_TO_HOLD, rmAdmin, nodeName, nodePath, + asList(ImmutableMap.of("new", nodeName, "previous", "", "name", "Name"), + ImmutableMap.of("new", HOLD1, "previous", "", "name", "Hold Name"))); + } + + /** + * Given an unsuccessful add to hold action + * When I view the audit log + * Then the add to hold event isn't audited + */ + @Test + public void unsuccessfulAddToHoldIsNotAudited() throws Exception + { + STEP("Create a new record"); + Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record"); + + rmAuditService.clearAuditLog(); + + STEP("Try to add the record to a hold by an user with no rights."); + holdsAPI.addItemsToHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(), + SC_INTERNAL_SERVER_ERROR, Collections.singletonList(recordToBeAdded.getId()), + Collections.singletonList(hold1NodeRef)); + + STEP("Check the audit log doesn't contain the entry for the unsuccessful add to hold."); + assertTrue("The list of events should not contain Add to Hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD).isEmpty()); + } + + /** + * Given a not empty record folder is added to a hold + * When I view the audit log + * Then only an entry has been created in the audit log for the record folder added + */ + @Test + public void addToHoldIsNotAuditedForRecordFolderChildren() throws Exception + { + STEP("Create a new record folder with a record inside"); + RecordCategoryChild notEmptyRecFolder = createRecordFolder(recordCategory.getId(), PREFIX + "notEmptyRecFolder"); + Record record = createElectronicRecord(notEmptyRecFolder.getId(), PREFIX + "record"); + + rmAuditService.clearAuditLog(); + + STEP("Add record folder to hold."); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1); + + auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD); + + STEP("Check the audit log contains only an entry for add to hold."); + assertEquals("The list of events should contain only an entry", 1, auditEntries.size()); + assertTrue("The list of events should not contain Add to Hold entry for the record", + auditEntries.stream().noneMatch(entry -> entry.getNodeName().equals(record.getName()))); + } + + /** + * Given a record is added to multiple holds + * When I view the audit log + * Then multiple entries have been created in the audit log for each add to hold event + */ + @Test + public void addToHoldIsAuditedInBulkAddition() throws Exception + { + STEP("Create a new record"); + Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record"); + + rmAuditService.clearAuditLog(); + + STEP("Add record to multiple holds."); + holdsAPI.addItemsToHolds(rmAdmin.getUsername(), rmAdmin.getPassword(), + Collections.singletonList(recordToBeAdded.getId()), holdsList); + + auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), ADD_TO_HOLD); + + STEP("Check the audit log contains entries for both additions."); + assertEquals("The list of events should contain Add to Hold entries for both holds", 2, auditEntries.size()); + assertTrue("The hold name value for the first add to hold is not audited.", + auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains( + ImmutableMap.of("new", HOLD1, "previous", "", "name", "Hold Name")))); + assertTrue("The hold name value for the second add to hold is not audited.", + auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains( + ImmutableMap.of("new", HOLD2, "previous", "", "name", "Hold Name")))); + } + + /** + * Given a document is added to a hold + * When I view the audit log as an user with no Read permissions over the document + * Then the add to hold entry isn't visible + */ + @Test + public void addToHoldAuditEntryNotVisible() + { + STEP("Create a new file"); + FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + rmAuditService.clearAuditLog(); + + STEP("Add file to hold."); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1); + + STEP("Check that an user with no Read permissions can't see the entry for the add to hold event."); + assertTrue("The list of events should not contain Add to Hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnNode, ADD_TO_HOLD).isEmpty()); + } + + /** + * Given a document is added to a hold + * When I view the audit log as an user with no Read permissions over the hold + * Then the the hold name is replaced in the add to hold entry + */ + @Test + public void addToHoldAuditEntryHoldNameNotVisible() + { + STEP("Create a new file"); + FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + rmAuditService.clearAuditLog(); + + STEP("Add file to hold."); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), contentToBeAdded.getNodeRefWithoutVersion(), HOLD1); + + auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, ADD_TO_HOLD); + + STEP("Check that an user with no Read permissions can't see the hold name in the add to hold event."); + String replacementHoldName = "You don't have permission to view this hold."; + assertEquals("The list of events should contain the Add to Hold entry", 1, auditEntries.size()); + assertTrue("The hold name should not be visible in the Add to Hold entry ", + auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains( + ImmutableMap.of("new", replacementHoldName, "previous", "", "name", "Hold Name")))); + } + + @AfterClass (alwaysRun = true) + public void cleanUpAuditAddToHoldTests() + { + holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef)); + dataSite.usingAdmin().deleteSite(privateSite); + asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user)); + getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(recordCategory.getId()); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditCreateHoldTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditCreateHoldTests.java new file mode 100644 index 0000000000..01541c9832 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditCreateHoldTests.java @@ -0,0 +1,189 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ +package org.alfresco.rest.rm.community.audit; + +import static java.util.Arrays.asList; + +import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION; +import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON; +import static org.alfresco.rest.rm.community.model.audit.AuditEvents.CREATE_HOLD; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.ImmutableMap; + +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.audit.AuditEntry; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.v0.HoldsAPI; +import org.alfresco.rest.v0.service.RMAuditService; +import org.alfresco.rest.v0.service.RoleService; +import org.alfresco.test.AlfrescoTest; +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; + +/** + * This class contains the tests that check the create hold event is audited + * + * @author Claudia Agache + * @since 3.3 + */ +@AlfrescoTest (jira = "RM-6859") +public class AuditCreateHoldTests extends BaseRMRestTest +{ + private final String PREFIX = generateTestPrefix(AuditCreateHoldTests.class); + private final String HOLD1 = PREFIX + "createHold"; + private final String HOLD2 = PREFIX + "createHold2"; + private final String HOLD3 = PREFIX + "createHold3"; + private List holdsListRef = new ArrayList<>(); + + @Autowired + private RMAuditService rmAuditService; + @Autowired + private HoldsAPI holdsAPI; + @Autowired + private RoleService roleService; + + private UserModel rmAdmin, rmManager; + + @BeforeClass (alwaysRun = true) + public void preconditionForAuditCreateHoldTests() + { + STEP("Create test users."); + rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId); + rmManager = roleService.createUserWithRMRole(UserRoles.ROLE_RM_MANAGER.roleId); + } + + /** + * Given a new hold is created + * When I view the audit log + * Then an entry has been created in the audit log which contains the following: + * name of the hold + * reason for hold + * user who created the hold + * date the creation occurred + */ + @Test + public void createHoldEventIsAuditedForNewHold() + { + rmAuditService.clearAuditLog(); + + STEP("Create a new hold."); + String hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD1, + HOLD_REASON, HOLD_DESCRIPTION); + holdsListRef.add(hold1NodeRef); + STEP("Check the audit log contains the entry for the created hold with the hold details."); + rmAuditService.checkAuditLogForEvent(getAdminUser(), CREATE_HOLD, rmAdmin, HOLD1, + asList(ImmutableMap.of("new", HOLD_REASON, "previous", "", "name", "Hold Reason"), + ImmutableMap.of("new", HOLD1, "previous", "", "name", "Hold Name"))); + } + + /** + * Given an unsuccessful create hold action + * When I view the audit log + * Then the create hold event isn't audited + */ + @Test + public void createHoldEventIsNotAuditedForExistingHold() + { + STEP("Create a new hold."); + String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION); + holdsListRef.add(hold2NodeRef); + rmAuditService.clearAuditLog(); + + STEP("Try to create again the same hold and expect action to fail."); + holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION, + SC_INTERNAL_SERVER_ERROR); + + STEP("Check the audit log doesn't contain the entry for the second create hold event."); + assertTrue("The list of events should not contain Create Hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD).isEmpty()); + } + + /** + * Given a new hold is created and then deleted + * When I view the audit log + * Then the create hold entry still contains the initial details + */ + @Test + public void createHoldAuditEntryIsNotLost() + { + final String holdName = PREFIX + "holdToBeDeleted"; + rmAuditService.clearAuditLog(); + + STEP("Create a new hold."); + holdsAPI.createHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName, HOLD_REASON, HOLD_DESCRIPTION); + + STEP("Get the list of audit entries for the create hold event."); + List auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD); + + STEP("Delete the created hold."); + holdsAPI.deleteHold(rmAdmin.getUsername(), rmAdmin.getPassword(), holdName); + + STEP("Get again the list of audit entries for the create hold event."); + List auditEntriesAfterDelete = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), CREATE_HOLD); + + STEP("Check that the audit entry for the created hold didn't change after hold deletion."); + assertEquals("The audit entry for Create Hold has been changed", auditEntries, auditEntriesAfterDelete); + } + + /** + * Given a new hold is created + * When I view the audit log as an user with no Read permissions over the created hold + * Then the create hold entry isn't visible + */ + @Test + public void createHoldAuditEntryNotVisible() + { + rmAuditService.clearAuditLog(); + + STEP("Create a new hold."); + String hold3NodeRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD3, + HOLD_REASON, HOLD_DESCRIPTION); + holdsListRef.add(hold3NodeRef); + + STEP("Check that an user with no Read permissions over the hold can't see the entry for the create hold event"); + assertTrue("The list of events should not contain Create Hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(rmManager, CREATE_HOLD).isEmpty()); + } + + @AfterClass (alwaysRun = true) + public void cleanUpAuditCreateHoldTests() + { + holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef)); + asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user)); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditDeleteHoldTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditDeleteHoldTests.java new file mode 100644 index 0000000000..c5723bcd6e --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditDeleteHoldTests.java @@ -0,0 +1,139 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ +package org.alfresco.rest.rm.community.audit; + +import static java.util.Arrays.asList; + +import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION; +import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON; +import static org.alfresco.rest.rm.community.model.audit.AuditEvents.DELETE_HOLD; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.Collections; + +import com.google.common.collect.ImmutableMap; + +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.v0.HoldsAPI; +import org.alfresco.rest.v0.service.RMAuditService; +import org.alfresco.rest.v0.service.RoleService; +import org.alfresco.test.AlfrescoTest; +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; + +/** + * This class contains the tests that check the delete hold event is audited + * + * @author Claudia Agache + * @since 3.3 + */ +@AlfrescoTest (jira = "RM-6859") +public class AuditDeleteHoldTests extends BaseRMRestTest +{ + private final String PREFIX = generateTestPrefix(AuditDeleteHoldTests.class); + private final String HOLD = PREFIX + "holdToBeDeleted"; + private final String HOLD2 = PREFIX + "deleteHold"; + + @Autowired + private RMAuditService rmAuditService; + @Autowired + private HoldsAPI holdsAPI; + @Autowired + private RoleService roleService; + + private UserModel rmAdmin, rmManager; + private String holdNodeRef; + + @BeforeClass (alwaysRun = true) + public void preconditionForAuditDeleteHoldTests() + { + STEP("Create a new hold."); + holdNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD, + HOLD_REASON, HOLD_DESCRIPTION); + + STEP("Create 2 users with different permissions for the created hold."); + rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId); + rmManager = roleService.createUserWithRMRole(UserRoles.ROLE_RM_MANAGER.roleId); + } + + /** + * Given a hold is deleted + * When I view the audit log + * Then an entry has been created in the audit log which contains the following: + * name of the hold + * user who deleted the hold + * date the delete occurred + */ + @Test + public void deleteHoldEventIsAudited() + { + STEP("Create a new hold."); + String holdRef = holdsAPI.createHoldAndGetNodeRef(rmAdmin.getUsername(), rmAdmin.getPassword(), HOLD2, + HOLD_REASON, HOLD_DESCRIPTION); + + rmAuditService.clearAuditLog(); + + STEP("Delete the created hold."); + holdsAPI.deleteHold(rmAdmin, holdRef); + + STEP("Check the audit log contains the entry for the deleted hold with the hold details."); + rmAuditService.checkAuditLogForEvent(getAdminUser(), DELETE_HOLD, rmAdmin, HOLD2, + Collections.singletonList(ImmutableMap.of("new", "", "previous", HOLD2, "name", "Hold Name"))); + } + + /** + * Given an unsuccessful delete hold action + * When I view the audit log + * Then the delete hold event isn't audited + */ + @Test + public void unsuccessfulDeleteHoldIsNotAudited() + { + rmAuditService.clearAuditLog(); + + STEP("Try to delete a hold by an user with no Read permissions over the hold."); + holdsAPI.deleteHold(rmManager.getUsername(), rmManager.getPassword(), holdNodeRef, SC_INTERNAL_SERVER_ERROR); + + STEP("Check the audit log doesn't contain the entry for the unsuccessful delete hold."); + assertTrue("The list of events should not contain Delete Hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), DELETE_HOLD).isEmpty()); + } + + @AfterClass (alwaysRun = true) + public void cleanUpAuditDeleteHoldTests() + { + holdsAPI.deleteHold(getAdminUser(), holdNodeRef); + asList(rmAdmin, rmManager).forEach(user -> getDataUser().usingAdmin().deleteUser(user)); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditRemoveFromHoldTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditRemoveFromHoldTests.java new file mode 100644 index 0000000000..75f7a9a433 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/audit/AuditRemoveFromHoldTests.java @@ -0,0 +1,329 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ +package org.alfresco.rest.rm.community.audit; + +import static java.util.Arrays.asList; + +import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION; +import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON; +import static org.alfresco.rest.rm.community.model.audit.AuditEvents.REMOVE_FROM_HOLD; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH; +import static org.alfresco.utility.Utility.buildPath; +import static org.alfresco.utility.Utility.removeLastSlash; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.apache.commons.httpclient.HttpStatus.SC_INTERNAL_SERVER_ERROR; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.google.common.collect.ImmutableMap; + +import org.alfresco.dataprep.CMISUtil; +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.audit.AuditEntry; +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.user.UserPermissions; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.v0.HoldsAPI; +import org.alfresco.rest.v0.service.RMAuditService; +import org.alfresco.rest.v0.service.RoleService; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.constants.UserRole; +import org.alfresco.utility.model.FileModel; +import org.alfresco.utility.model.SiteModel; +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.DataProvider; +import org.testng.annotations.Test; + +/** + * This class contains the tests that check the remove from hold event is audited + * + * @author Claudia Agache + * @since 3.3 + */ +@AlfrescoTest (jira = "RM-6859") +public class AuditRemoveFromHoldTests extends BaseRMRestTest +{ + private final String PREFIX = generateTestPrefix(AuditRemoveFromHoldTests.class); + private final String HOLD1 = PREFIX + "hold1"; + private final String HOLD2 = PREFIX + "hold2"; + private final String HOLD3 = PREFIX + "hold3"; + private final String DELETED_HOLD = PREFIX + "deletedHold"; + + @Autowired + private RMAuditService rmAuditService; + @Autowired + private HoldsAPI holdsAPI; + @Autowired + private RoleService roleService; + + private UserModel rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode; + private SiteModel privateSite; + private RecordCategory recordCategory; + private RecordCategoryChild recordFolder, heldRecordFolder; + private Record heldRecord; + private List auditEntries; + private List holdsList = asList(HOLD1, HOLD2, HOLD3); + private List holdsListRef = new ArrayList<>(); + private FileModel heldContent; + private String hold1NodeRef; + + @BeforeClass (alwaysRun = true) + public void preconditionForAuditRemoveFromHoldTests() throws Exception + { + STEP("Create an user with full rights to remove content from a hold."); + rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId); + + STEP("Create a collaboration site."); + privateSite = dataSite.usingUser(rmAdmin).createPrivateRandomSite(); + + STEP("Create new holds."); + hold1NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), + HOLD1, HOLD_REASON, HOLD_DESCRIPTION); + String hold2NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD2, HOLD_REASON, HOLD_DESCRIPTION); + String hold3NodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), HOLD3, HOLD_REASON, HOLD_DESCRIPTION); + String deleteNodeRef = holdsAPI.createHoldAndGetNodeRef(getAdminUser().getUsername(), getAdminUser().getPassword(), DELETED_HOLD, HOLD_REASON, HOLD_DESCRIPTION); + holdsListRef = asList(hold1NodeRef, hold2NodeRef, hold3NodeRef); + + STEP("Create a new record category with a record folder."); + recordCategory = createRootCategory(getRandomName("recordCategory")); + recordFolder = createRecordFolder(recordCategory.getId(), getRandomName("recFolder")); + + STEP("Create some held items"); + heldContent = dataContent.usingAdmin().usingSite(privateSite) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + heldRecordFolder = createRecordFolder(recordCategory.getId(), PREFIX + "heldRecFolder"); + heldRecord = createElectronicRecord(recordFolder.getId(), PREFIX + "record"); + + holdsAPI.addItemsToHolds(getAdminUser().getUsername(), getAdminUser().getPassword(), + asList(heldContent.getNodeRefWithoutVersion(), heldRecordFolder.getId(), heldRecord.getId()), + holdsList); + + STEP("Create users without rights to remove content from a hold."); + rmManagerNoReadOnHold = roleService.createUserWithSiteRoleRMRoleAndPermission(privateSite, + UserRole.SiteManager, recordCategory.getId(), UserRoles.ROLE_RM_MANAGER, UserPermissions.PERMISSION_FILING); + rmManagerNoReadOnNode = roleService.createUserWithRMRoleAndRMNodePermission(UserRoles.ROLE_RM_MANAGER.roleId, + hold1NodeRef, UserPermissions.PERMISSION_FILING); + } + + /** + * Data provider with valid nodes that can be removed from a hold + * + * @return the node id, the node name and the node path + */ + @DataProvider (name = "validNodesForRemoveFromHold") + public Object[][] getValidNodesForRemoveFromHold() + { + String recordFolderPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(), + heldRecordFolder.getName())); + String recordPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(), + recordFolder.getName(), heldRecord.getName())); + String contentPath = "/Company Home" + heldContent.getCmisLocation(); + + return new String[][] + { + // a record folder + { heldRecordFolder.getId(), heldRecordFolder.getName(), recordFolderPath }, + // a record + { heldRecord.getId(), heldRecord.getName(), recordPath }, + //an active content, + { heldContent.getNodeRefWithoutVersion(), heldContent.getName(), contentPath } + }; + } + + /** + * Given a document/record/record folder is removed from a hold + * When I view the audit log + * Then an entry has been created in the audit log that contains the following: + * name of the hold + * name of the document/record/record folder removed + * user who removed the content + * date the content was removed + * path of the node + */ + @Test (dataProvider = "validNodesForRemoveFromHold") + public void removeFromHoldEventIsAudited(String nodeId, String nodeName, String nodePath) + { + rmAuditService.clearAuditLog(); + + STEP("Remove node from hold."); + holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), nodeId, HOLD3); + + STEP("Check the audit log contains the entry for the remove from hold event."); + rmAuditService.checkAuditLogForEvent(getAdminUser(), REMOVE_FROM_HOLD, rmAdmin, nodeName, nodePath, + asList(ImmutableMap.of("new", "", "previous", nodeName, "name", "Name"), + ImmutableMap.of("new", "", "previous", HOLD3, "name", "Hold Name"))); + } + + /** + * Given an unsuccessful remove from hold action + * When I view the audit log + * Then the remove from hold event isn't audited + */ + @Test + public void unsuccessfulRemoveFromHoldIsNotAudited() + { + rmAuditService.clearAuditLog(); + + STEP("Try to remove the record from a hold by an user with no rights."); + holdsAPI.removeItemsFromHolds(rmManagerNoReadOnHold.getUsername(), rmManagerNoReadOnHold.getPassword(), + SC_INTERNAL_SERVER_ERROR, Collections.singletonList(heldRecord.getId()), + Collections.singletonList(hold1NodeRef)); + + STEP("Check the audit log doesn't contain the entry for the unsuccessful remove from hold."); + assertTrue("The list of events should not contain remove from hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD).isEmpty()); + } + + /** + * Given a not empty record folder is removed from a hold + * When I view the audit log + * Then only an entry has been created in the audit log for the record folder removed + */ + @Test + public void removeFromHoldNotAuditedForRecordFolderChildren() throws Exception + { + STEP("Create a new record folder with a record inside"); + RecordCategoryChild notEmptyRecFolder = createRecordFolder(recordCategory.getId(), PREFIX + "notEmptyRecFolder"); + Record record = createElectronicRecord(notEmptyRecFolder.getId(), PREFIX + "record"); + + STEP("Add the record folder to a hold."); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1); + + rmAuditService.clearAuditLog(); + + STEP("Remove record folder from hold."); + holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), notEmptyRecFolder.getId(), HOLD1); + + STEP("Get the list of audit entries for the remove from hold event."); + auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD); + + STEP("Check the audit log contains only an entry for remove from hold."); + assertEquals("The list of events should contain only an entry", 1, auditEntries.size()); + assertTrue("The list of events should not contain Remove from Hold entry for the record", + auditEntries.stream().noneMatch(entry -> entry.getNodeName().equals(record.getName()))); + } + + /** + * Given a record folder is removed from multiple holds + * When I view the audit log + * Then multiple entries have been created in the audit log for each remove from hold event + */ + @Test + public void removeFromHoldIsAuditedInBulkRemoval() + { + rmAuditService.clearAuditLog(); + + STEP("Remove record folder from multiple holds."); + holdsAPI.removeItemsFromHolds(rmAdmin.getUsername(), rmAdmin.getPassword(), + Collections.singletonList(heldRecordFolder.getId()), asList(HOLD1, HOLD2)); + + STEP("Get the list of audit entries for the remove from hold event."); + auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(getAdminUser(), REMOVE_FROM_HOLD); + + STEP("Check the audit log contains entries for both removal."); + assertEquals("The list of events should contain remove from Hold entries for both holds", 2, + auditEntries.size()); + assertTrue("The hold name value for the first remove from hold is not audited.", + auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains( + ImmutableMap.of("new", "", "previous", HOLD1, "name", "Hold Name")))); + assertTrue("The hold name value for the second remove from hold is not audited.", + auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains( + ImmutableMap.of("new", "", "previous", HOLD2, "name", "Hold Name")))); + } + + /** + * Given a document/record/record folder is removed from a hold + * When I view the audit log as an user with no Read permissions over the node + * Then the remove from hold entry isn't visible + */ + @Test + public void removeFromHoldAuditEntryNotVisible() + { + STEP("Add content to a hold."); + FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1); + + rmAuditService.clearAuditLog(); + + STEP("Remove held content from the hold."); + holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1); + + STEP("Check that an user with no Read permissions can't see the entry for the remove from hold event."); + assertTrue("The list of events should not contain Remove from Hold entry ", + rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnNode, REMOVE_FROM_HOLD).isEmpty()); + } + + /** + * Given a document/record/record folder is removed from a hold + * When I view the audit log as an user with no Read permissions over the hold + * Then the the hold name is replaced in the remove from hold entry + */ + @Test + public void removeFromHoldAuditEntryHoldNameNotVisible() + { + STEP("Add content to a hold."); + FileModel heldFile = dataContent.usingAdmin().usingSite(privateSite) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + holdsAPI.addItemToHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1); + + rmAuditService.clearAuditLog(); + + STEP("Remove held content from the hold."); + holdsAPI.removeItemFromHold(rmAdmin.getUsername(), rmAdmin.getPassword(), heldFile.getNodeRefWithoutVersion(), HOLD1); + + auditEntries = rmAuditService.getAuditEntriesFilteredByEvent(rmManagerNoReadOnHold, REMOVE_FROM_HOLD); + + STEP("Check that an user with no Read permissions can't see the hold name in the remove from hold event."); + String replacementHoldName = "You don't have permission to view this hold."; + assertEquals("The list of events should contain the Remove from Hold entry", 1, auditEntries.size()); + assertTrue("The hold name should not be visible in the Remove from Hold entry ", + auditEntries.stream().anyMatch(entry -> entry.getChangedValues().contains( + ImmutableMap.of("new", "", "previous", replacementHoldName, "name", "Hold Name")))); + } + + @AfterClass (alwaysRun = true) + public void cleanUpAuditRemoveFromHoldTests() + { + holdsListRef.forEach(holdRef -> holdsAPI.deleteHold(getAdminUser(), holdRef)); + dataSite.usingAdmin().deleteSite(privateSite); + asList(rmAdmin, rmManagerNoReadOnHold, rmManagerNoReadOnNode).forEach(user -> getDataUser().usingAdmin().deleteUser(user)); + getRestAPIFactory().getRecordCategoryAPI().deleteRecordCategory(recordCategory.getId()); + } +} diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml index d8033cc8a1..3596e79165 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml @@ -130,4 +130,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java new file mode 100644 index 0000000000..34fb578d5c --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java @@ -0,0 +1,85 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.EVERY_EVENT; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * Add to hold audit event. + * + * @author Sara Aspery + * @since 3.3 + */ +@BehaviourBean +public class AddToHoldAuditEvent extends AuditEvent implements HoldServicePolicies.OnAddToHoldPolicy +{ + /** + * Node Service + */ + private NodeService nodeService; + + /** + * Sets the node service + * + * @param nodeService nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnAddToHoldPolicy#onAddToHold(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + type = "rma:hold", + notificationFrequency = EVERY_EVENT + ) + public void onAddToHold(NodeRef holdNodeRef, NodeRef contentNodeRef) + { + Map auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService); + auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(contentNodeRef, ContentModel.PROP_NAME)); + + recordsManagementAuditService.auditEvent(contentNodeRef, getName(), null, auditProperties, true, false); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java new file mode 100644 index 0000000000..85bf2e38b8 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java @@ -0,0 +1,88 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * Create hold audit event. + * This listens to the NodeServicePolicies.OnCreateNodePolicy in order to cover the create hold action from Share + * since that does not call the createHold from HoldService + * + * @author Sara Aspery + * @since 3.3 + */ +@BehaviourBean +public class CreateHoldAuditEvent extends AuditEvent implements NodeServicePolicies.OnCreateNodePolicy +{ + /** + * Node Service + */ + private NodeService nodeService; + + /** + * Sets the node service + * + * @param nodeService nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + type = "rma:hold", + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + public void onCreateNode(ChildAssociationRef childAssociationRef) + { + NodeRef holdNodeRef = childAssociationRef.getChildRef(); + + Map auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService); + auditProperties.put(PROP_HOLD_REASON, nodeService.getProperty(holdNodeRef, PROP_HOLD_REASON)); + + recordsManagementAuditService.auditEvent(holdNodeRef, getName(), null, auditProperties); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEvent.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEvent.java new file mode 100644 index 0000000000..6699ff629c --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEvent.java @@ -0,0 +1,82 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.EVERY_EVENT; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * Delete hold audit event. + * This listens to the NodeServicePolicies.BeforeDeleteNodePolicy in order to cover the delete hold using nodes service + * + * @author Sara Aspery + * @since 3.3 + */ +@BehaviourBean +public class DeleteHoldAuditEvent extends AuditEvent implements NodeServicePolicies.BeforeDeleteNodePolicy +{ + /** + * Node Service + */ + private NodeService nodeService; + + /** + * Sets the node service + * + * @param nodeService nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Behaviour ( + kind = BehaviourKind.CLASS, + type = "rma:hold", + notificationFrequency = EVERY_EVENT + ) + public void beforeDeleteNode(NodeRef holdNodeRef) + { + Map auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService); + recordsManagementAuditService.auditEvent(holdNodeRef, getName(), auditProperties, null, true, false); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java new file mode 100644 index 0000000000..23b225ef8c --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java @@ -0,0 +1,69 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class for creating audit events about holds. + * + * @author Sara Aspery + * @since 3.3 + */ +class HoldUtils +{ + /** A QName to display for the hold name. */ + public static final QName HOLD_NAME = QName.createQName(RecordsManagementModel.RM_URI, "Hold Name"); + /** A QName to display for the hold node ref. */ + public static final QName HOLD_NODEREF = QName.createQName(RecordsManagementModel.RM_URI, "Hold NodeRef"); + + /** + * Create a properties map containing the hold name and node ref for the given hold. + * + * @param nodeRef The nodeRef of the hold. + * @param nodeService The node service. + * @return A map containing the name and noderef of the hold. + */ + static Map makePropertiesMap(NodeRef nodeRef, NodeService nodeService) + { + Map auditProperties = new HashMap<>(); + + auditProperties.put(HOLD_NAME, nodeService.getProperty(nodeRef, ContentModel.PROP_NAME)); + auditProperties.put(HOLD_NODEREF, nodeRef); + + return auditProperties; + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEvent.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEvent.java new file mode 100644 index 0000000000..d9e2111fa3 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEvent.java @@ -0,0 +1,84 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * Delete from hold audit event. + * + * @author Chris Shields + * @since 3.3 + */ +@BehaviourBean +public class RemoveFromHoldAuditEvent extends AuditEvent implements HoldServicePolicies.OnRemoveFromHoldPolicy +{ + /** + * Node Service + */ + private NodeService nodeService; + + /** + * Sets the node service + * + * @param nodeService nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnRemoveFromHoldPolicy#onRemoveFromHold(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + type = "rma:hold", + notificationFrequency = NotificationFrequency.EVERY_EVENT + ) + public void onRemoveFromHold(NodeRef holdNodeRef, NodeRef contentNodeRef) + { + Map auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService); + auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(contentNodeRef, ContentModel.PROP_NAME)); + + recordsManagementAuditService.auditEvent(contentNodeRef, getName(), auditProperties, null, true); + } +} diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java new file mode 100644 index 0000000000..11159f2d1c --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java @@ -0,0 +1,92 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.GUID; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * Unit tests for {@link AddToHoldAuditEvent}. + * + * @author Sara Aspery + * @since 3.3 + */ +public class AddToHoldAuditEventUnitTest extends BaseUnitTest +{ + @InjectMocks + private AddToHoldAuditEvent addToHoldAuditEvent; + + @Mock + private NodeService mockedNodeService; + + private NodeRef holdNodeRef; + private NodeRef contentNodeRef; + + /** Set up the mocks. */ + @Before + public void setUp() + { + initMocks(this); + + holdNodeRef = generateNodeRef(); + String holdName = "Hold " + GUID.generate(); + + contentNodeRef = generateNodeRef(); + String contentName = "Content " + GUID.generate(); + + when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName); + when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName); + } + + /** + * Check that the add to hold event calls an audit event. + * + */ + @Test + public void testAddToHoldCausesAuditEvent() + { + addToHoldAuditEvent.onAddToHold(holdNodeRef, contentNodeRef); + verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), isNull(Map.class), any(Map.class), eq(true), eq(false)); + } +} diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java new file mode 100644 index 0000000000..f41c321fd0 --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java @@ -0,0 +1,93 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.GUID; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * Unit tests for {@link CreateHoldAuditEvent}. + * + * @author Sara Aspery + * @since 3.3 + */ +public class CreateHoldAuditEventUnitTest extends BaseUnitTest +{ + @InjectMocks + private CreateHoldAuditEvent createHoldAuditEvent; + + @Mock + private NodeService mockedNodeService; + + private NodeRef holdNodeRef; + private ChildAssociationRef childAssociationRef; + + /** Set up the mocks. */ + @Before + public void setUp() + { + initMocks(this); + + holdNodeRef = generateNodeRef(); + String holdName = "Hold " + GUID.generate(); + String holdReason = "Reason " + GUID.generate(); + childAssociationRef = generateChildAssociationRef(null, holdNodeRef); + + when(childAssociationRef.getChildRef()).thenReturn(holdNodeRef); + when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName); + when(mockedNodeService.getProperty(holdNodeRef, PROP_HOLD_REASON)).thenReturn(holdReason); + } + + /** + * Check that the create hold event calls an audit event. + * + */ + @Test + public void testCreateHoldCausesAuditEvent() + { + createHoldAuditEvent.onCreateNode(childAssociationRef); + verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(holdNodeRef), any(String.class), isNull(Map.class), any(Map.class)); + } +} diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEventUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEventUnitTest.java new file mode 100644 index 0000000000..8ef99fe9b6 --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/DeleteHoldAuditEventUnitTest.java @@ -0,0 +1,89 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + + package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.GUID; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; + +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * Unit tests for {@link DeleteHoldAuditEvent}. + * + * @author Sara Aspery + * @since 3.3 + */ +public class DeleteHoldAuditEventUnitTest extends BaseUnitTest +{ + @InjectMocks + private DeleteHoldAuditEvent deleteHoldAuditEvent; + + @Mock + private NodeService mockedNodeService; + + private NodeRef holdNodeRef; + + /** Set up the mocks. */ + @Before + public void setUp() + { + initMocks(this); + + holdNodeRef = generateNodeRef(); + String holdName = "Hold " + GUID.generate(); + + when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName); + } + + /** + * Check that the delete hold event calls an audit event. + * + */ + @Test + public void testDeleteHoldCausesAuditEvent() + { + deleteHoldAuditEvent.beforeDeleteNode(holdNodeRef); + verify(mockedRecordsManagementAuditService, times(1)) + .auditEvent(eq(holdNodeRef), any(String.class), any(Map.class), isNull(Map.class), Matchers.eq(true), Matchers.eq(false)); + } +} diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEventUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEventUnitTest.java new file mode 100644 index 0000000000..2ed91b0e96 --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/RemoveFromHoldAuditEventUnitTest.java @@ -0,0 +1,95 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2021 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.GUID; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** + * Unit tests for {@link RemoveFromHoldAuditEvent}. + * + * @author Chris Shields + * @since 3.3 + */ +public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest +{ + @InjectMocks + private RemoveFromHoldAuditEvent removeFromHoldAuditEvent; + + @Mock + private NodeService mockedNodeService; + + private NodeRef holdNodeRef; + private NodeRef contentNodeRef; + + /** + * Set up the mocks. + */ + @Before + public void setUp() + { + initMocks(this); + + holdNodeRef = generateNodeRef(); + String holdName = "Hold " + GUID.generate(); + + contentNodeRef = generateNodeRef(); + String contentName = "Content " + GUID.generate(); + + when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName); + when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName); + } + + /** + * Check that the remove from hold event calls an audit event. + */ + @Test + public void testRemoveFromHoldCausesAuditEvent() + { + removeFromHoldAuditEvent.onRemoveFromHold(holdNodeRef, contentNodeRef); + verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), any(Map.class), isNull(Map.class), eq(true)); + } + +}