/* * #%L * Alfresco Records Management Module * %% * Copyright (C) 2005 - 2016 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.module.org_alfresco_module_rm.security; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.util.HashSet; import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.repo.security.permissions.impl.AccessPermissionImpl; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.namespace.QName; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Spy; import org.mockito.verification.VerificationMode; /** * File plan permission service implementation unit test. * <p> * Primarily tests the file plan permission service interaction with the * permission service. * * @author Roy Wetherall * @since 2.2 */ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest { /** test authority */ protected static final String AUTHORITY = "anAuthority"; protected static final String AUTHORITY2 = "anOtherAuthority"; /** fileplan nodes */ protected NodeRef rootRecordCategory; protected NodeRef recordCategory; protected NodeRef newRecordFolder; protected NodeRef newRecord; /** unfiled nodes */ protected NodeRef unfiledRecordContainer; protected NodeRef unfiledRecordFolder; protected NodeRef unfiledRecordFolderChild; protected NodeRef unfiledRecord; /** held nodes */ protected NodeRef holdContainer; protected NodeRef hold; protected NodeRef heldRecord; /** file plan permission service implementation */ @Spy @InjectMocks FilePlanPermissionServiceImpl filePlanPermissionService; /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before() */ @Override public void before() throws Exception { super.before(); // initialize node's unfiledRecordContainer = generateContainerNodeRef(TYPE_UNFILED_RECORD_CONTAINER); unfiledRecordFolder = generateContainerNodeRef(TYPE_UNFILED_RECORD_FOLDER); unfiledRecordFolderChild = generateContainerNodeRef(TYPE_UNFILED_RECORD_FOLDER); unfiledRecord = generateRecord(); holdContainer = generateContainerNodeRef(TYPE_HOLD_CONTAINER); hold = generateHoldNodeRef("my test hold"); heldRecord = generateRecord(); rootRecordCategory = generateContainerNodeRef(TYPE_RECORD_CATEGORY); recordCategory = generateContainerNodeRef(TYPE_RECORD_CATEGORY); newRecordFolder = generateRecordFolder(); newRecord = generateRecord(); // setup parent hierarchy makePrimaryParentOf(filePlan, generateNodeRef(ContentModel.TYPE_FOLDER)); makePrimaryParentOf(rootRecordCategory, filePlan); makePrimaryParentOf(recordCategory, rootRecordCategory); makePrimaryParentOf(newRecordFolder, recordCategory); makePrimaryParentOf(newRecord, newRecordFolder); makePrimaryParentOf(unfiledRecordFolder, unfiledRecordContainer); makePrimaryParentOf(unfiledRecordContainer, filePlan); makePrimaryParentOf(hold, holdContainer); makePrimaryParentOf(holdContainer, filePlan); // setup child hierarchy makeChildrenOf(filePlan, rootRecordCategory); makeChildrenOf(rootRecordCategory, recordCategory); makeChildrenOf(recordCategory, newRecordFolder); makeChildrenOf(newRecordFolder, newRecord); makeChildrenOf(unfiledRecordFolder, unfiledRecordFolderChild); makeChildrenOf(unfiledRecordFolderChild, unfiledRecord); makeChildrenOf(holdContainer, hold); makeChildrenOf(hold, heldRecord); doReturn(FilePlanComponentKind.FILE_PLAN).when(filePlanPermissionService).getFilePlanComponentKind(filePlan); doReturn(FilePlanComponentKind.RECORD_CATEGORY).when(filePlanPermissionService).getFilePlanComponentKind(rootRecordCategory); doReturn(FilePlanComponentKind.RECORD_CATEGORY).when(filePlanPermissionService).getFilePlanComponentKind(recordCategory); doReturn(FilePlanComponentKind.RECORD_FOLDER).when(filePlanPermissionService).getFilePlanComponentKind(newRecordFolder); doReturn(FilePlanComponentKind.RECORD).when(filePlanPermissionService).getFilePlanComponentKind(newRecord); doReturn(FilePlanComponentKind.UNFILED_RECORD_FOLDER).when(filePlanPermissionService).getFilePlanComponentKind(unfiledRecordFolder); doReturn(FilePlanComponentKind.UNFILED_RECORD_CONTAINER).when(filePlanPermissionService).getFilePlanComponentKind(unfiledRecordContainer); doReturn(FilePlanComponentKind.RECORD).when(filePlanPermissionService).getFilePlanComponentKind(unfiledRecord); doReturn(FilePlanComponentKind.HOLD_CONTAINER).when(filePlanPermissionService).getFilePlanComponentKind(holdContainer); doReturn(FilePlanComponentKind.HOLD).when(filePlanPermissionService).getFilePlanComponentKind(hold); } /** * Helper method to generate a container node ref of a perticular type. * * @param type type of node reference * @return {@link NodeRef} node reference that behaves like a container of the type given. */ private NodeRef generateContainerNodeRef(QName type) { NodeRef nodeRef = generateNodeRef(type); setupAsFilePlanComponent(nodeRef); doReturn(true).when(filePlanPermissionService).isFilePlanContainer(nodeRef); return nodeRef; } /** * Set read permission on unfiled record folder. */ @Test public void setReadPermissionOnUnfiledRecordFolder() { // set read permission on unfiled record folder filePlanPermissionService.setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS); // verify permission set on target node verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS, true); } /** * Set filling permission on unfiled record folder */ @Test public void setReadAndFilePermissionOnUnfileRecordFolder() { // set read permission on unfiled record folder filePlanPermissionService.setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING); // verify permission set on target node verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING, true); } /** * Remove permission from unfiled record folders. */ @Test public void deletePermissionFromUnfiledRecordFolder() { // delete read permission from unfiled record folder filePlanPermissionService.deletePermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS); // verify permission deleted on target node verify(mockedPermissionService, times(1)).deletePermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS); } /** * Set read permission on hold container */ @Test public void setReadPermissionOnHoldContainer() { // set read permission on hold filePlanPermissionService.setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS); // verify permission set on target node verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true); } /** * Set filing permission on hold container */ @Test public void setFilingPermissionOnHoldContainer() { // set read permission on hold filePlanPermissionService.setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING); // verify permission set on target node verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING, true); } /** * Set read permission on hold. */ @Test public void setReadPermissionOnHold() { // set read permission on hold filePlanPermissionService.setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS); // verify permission set on target node verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS, true); } /** * Set filing permission on hold. */ @Test public void setFilingPermissionOnHold() { // set filing permission on hold filePlanPermissionService.setPermission(hold, AUTHORITY, RMPermissionModel.FILING); // verify permission set on target node verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.FILING, true); } /** * Helper method to setup permissions on mock objects */ private void setupPermissions(NodeRef nodeRef) { Set<AccessPermission> perms = new HashSet<AccessPermission>(4); // setup basic file and read for authorities perms.add(new AccessPermissionImpl(RMPermissionModel.READ_RECORDS, AccessStatus.ALLOWED, AUTHORITY, 0)); perms.add(new AccessPermissionImpl(RMPermissionModel.FILING, AccessStatus.ALLOWED, AUTHORITY2, 1)); doReturn(perms).when(mockedPermissionService).getAllSetPermissions(nodeRef); } /** * Helper to verify the core permissions have been initialized correctly */ private void verifyInitPermissions(NodeRef nodeRef, boolean isInherited) { verify(mockedPermissionService).getAllSetPermissions(nodeRef); verify(mockedPermissionService).setInheritParentPermissions(nodeRef, isInherited); verify(mockedPermissionService).clearPermission(nodeRef, null); verify(mockedOwnableService).setOwner(nodeRef, OwnableService.NO_OWNER); } /** * Helper to verify that permissions have been set correctly on the child * * @param parent parent node * @param child child node * @param read verification mode relating to setting read on the child * @param filling verification mode relating to setting filling on the child */ private void verifyInitPermissions(NodeRef parent, NodeRef child, VerificationMode read, VerificationMode filling, boolean isParentFilePlan, boolean isInherited) { // verify the core permissions are set-up correctly verifyInitPermissions(child, isInherited); if (isParentFilePlan) { // verify the permissions came from the correct parent verify(mockedPermissionService).getAllSetPermissions(parent); // verify all the inherited permissions are set correctly (note read are not inherited from fileplan) verify(mockedPermissionService, filling).setPermission(child, AUTHORITY2, RMPermissionModel.FILING, true); verify(mockedPermissionService, read).setPermission(child, AUTHORITY, RMPermissionModel.READ_RECORDS, true); } } /** * Test the initialisation of permissions for a new root category */ @Test public void initPermissionsForNewRootRecordCategory() { // setup permissions for file plan setupPermissions(filePlan); // setup permissions filePlanPermissionService.setupRecordCategoryPermissions(rootRecordCategory); // verify permission init verifyInitPermissions(filePlan, rootRecordCategory, never(), times(1), true, false); } /** * Test the initialisation of permissions for a new category */ @Test public void initPermissionsForNewRecordCategory() { // setup permissions for parent setupPermissions(rootRecordCategory); // setup permissions filePlanPermissionService.setupRecordCategoryPermissions(recordCategory); // verify permission init verifyInitPermissions(rootRecordCategory, recordCategory, times(1), times(1), false, true); } /** * Test initialisation new record folder permissions */ @Test public void initPermissionsForNewRecordFolder() { // setup permissions for parent setupPermissions(recordCategory); // setup permissions filePlanPermissionService.setupPermissions(recordCategory, newRecordFolder); // verify permission init verifyInitPermissions(recordCategory, newRecordFolder, times(1), times(1), false, true); } /** * Test setup of new record permissions */ @Test public void initPermissionsForNewRecord() { // setup permissions for parent setupPermissions(newRecordFolder); // setup permissions for record filePlanPermissionService.setupPermissions(newRecordFolder, newRecord); // verify permission init verifyInitPermissions(newRecordFolder, newRecord, times(1), times(1), false, true); } /** * Test setup of permissions for new hold container */ @Test public void initPermnissionsForNewHoldContainer() { // setup permissions for parent setupPermissions(filePlan); // setup permissions for record filePlanPermissionService.setupPermissions(filePlan, holdContainer); // verify permissions are set-up correctly verifyInitPermissions(filePlan, holdContainer, times(1), times(1), false, true); } /** * Test setup of permissions for new hold */ @Test public void initPermissionsForNewHold() { // setup permissions for parent setupPermissions(holdContainer); // setup permissions for record filePlanPermissionService.setupPermissions(holdContainer, hold); // verify permissions are set-up correctly verifyInitPermissions(holdContainer, hold, never(), times(1), false, false); } /** * Test setup of permissions for new unfiled container */ @Test public void initPermissionsForNewUnfiledContainer() { // setup permissions for parent setupPermissions(filePlan); // setup permissions for record filePlanPermissionService.setupPermissions(filePlan, unfiledRecordContainer); // verify permissions are set-up correctly verifyInitPermissions(filePlan, unfiledRecordContainer, times(1), times(1), false, false); } /** * Test setup of permissions for new unfiled record folder */ @Test public void initPermissionsForNewUnfiledRecordFolder() { // setup permissions for parent setupPermissions(unfiledRecordContainer); // setup permissions for record filePlanPermissionService.setupPermissions(unfiledRecordContainer, unfiledRecordFolder); // verify permissions are set-up correctly verifyInitPermissions(unfiledRecordContainer, unfiledRecordFolder, never(), times(1), false, true); } /** * Test setup of permissions for new unfiled record */ @Test public void initPermissionsForNewUnfiledRecord() { // setup permissions for parent setupPermissions(unfiledRecordFolder); // setup permissions for record filePlanPermissionService.setupPermissions(unfiledRecordFolder, unfiledRecord); // verify permission init verifyInitPermissions(unfiledRecordFolder, unfiledRecord, times(1), times(1), false, true); } }