diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index caf754fcf4..9badc078e4 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -886,7 +886,7 @@ public class RecordServiceImpl extends BaseBehaviourBean ParameterCheck.mandatory("isLinked", isLinked); recordCreationSanityCheckOnNode(nodeRef); - final NodeRef checkedFilePlan = recordCreationSanityCheckOnFilePlan(filePlan); + final NodeRef newRecordContainer = recordCreationSanityCheckOnDestinationNode(destinationNodeRef, filePlan); invokeBeforeRecordDeclaration(nodeRef); // do the work of creating the record as the system user @@ -901,34 +901,6 @@ public class RecordServiceImpl extends BaseBehaviourBean ruleService.disableRuleType("outbound"); try { - NodeRef newRecordContainer = destinationNodeRef; - // if optional location not specified, use the unfiledContainer - if (newRecordContainer == null) - { - // get the new record container for the file plan - newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan); - if (newRecordContainer == null) - { - throw new AlfrescoRuntimeException("Unable to create record, because record container could not be found."); - } - } - // if optional location supplied, check that it is a valid record folder - else - { - QName nodeType = nodeService.getType(newRecordContainer); - if(!(nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER) || - nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER))) - { - throw new AlfrescoRuntimeException("Unable to create record, because container is not a valid type for new record."); - } - - Boolean isClosed = (Boolean) nodeService.getProperty(newRecordContainer, PROP_IS_CLOSED); - if (isClosed != null && isClosed) - { - throw new AlfrescoRuntimeException("Unable to create record, because container is closed."); - } - } - // get the documents readers and writers Pair, Set> readersAndWriters = extendedPermissionService.getReadersAndWriters(nodeRef); @@ -1051,6 +1023,59 @@ public class RecordServiceImpl extends BaseBehaviourBean return result; } + /** + * Helper method to check the given destination before trying to declare a record in it. + * + * @param destinationNodeRef The reference of the container in which the record will be created + * @param filePlan The reference of the file plan node + */ + private NodeRef recordCreationSanityCheckOnDestinationNode(NodeRef destinationNodeRef, final NodeRef filePlan) + { + final NodeRef checkedFilePlan = recordCreationSanityCheckOnFilePlan(filePlan); + NodeRef newRecordContainer = destinationNodeRef; + // if optional location not specified, use the unfiledContainer + if (newRecordContainer == null) + { + // get the new record container for the file plan + newRecordContainer = AuthenticationUtil.runAs(new RunAsWork() + { + @Override + public NodeRef doWork() + { + return filePlanService.getUnfiledContainer(checkedFilePlan); + } + }, AuthenticationUtil.getAdminUserName()); + + if (newRecordContainer == null) + { + throw new AlfrescoRuntimeException("Unable to create record, because record container could not be found."); + } + } + // if optional location supplied, check that it is a valid record folder + else + { + QName nodeType = nodeService.getType(newRecordContainer); + if(!(nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER) || + nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER))) + { + throw new AlfrescoRuntimeException("Unable to create record, because container is not a valid type for new record."); + } + + Boolean isClosed = (Boolean) nodeService.getProperty(newRecordContainer, PROP_IS_CLOSED); + if (isClosed != null && isClosed) + { + throw new AlfrescoRuntimeException("Unable to create record, because container is closed."); + } + + if (extendedPermissionService.hasPermission(newRecordContainer, RMPermissionModel.FILING) == AccessStatus.DENIED) + { + throw new AccessDeniedException(I18NUtil.getMessage("permissions.err_access_denied")); + } + } + + return newRecordContainer; + } + /** * Helper method to check the given node before trying to declare it as record * diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index 5574d1a1ae..d1314d94b2 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -47,9 +47,11 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.repo.policy.Behaviour; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; @@ -550,6 +552,21 @@ public class RecordServiceImplUnitTest extends BaseUnitTest recordService.createRecord(filePlan, dmNodeRef, recordCategory); } + /** + * Given a file that is not yet a record + * When I create the record specifying a location + * Then the record is created in the specified record folder + */ + @Test (expected = AccessDeniedException.class) + public void createRecordIntoSpecifiedRecordFolderWithoutFilePermission() + { + mocksForRecordCreation(); + when(mockedExtendedPermissionService.hasPermission(recordFolder, RMPermissionModel.FILING)).thenReturn(AccessStatus.DENIED); + + // create the record + recordService.createRecord(filePlan, dmNodeRef, recordFolder); + } + /* Helper method to set up the mocks for record creation */ private void mocksForRecordCreation() {