diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/UpdateCapability.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/UpdateCapability.java index 701a1da03b..be66403728 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/UpdateCapability.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/UpdateCapability.java @@ -19,10 +19,16 @@ package org.alfresco.module.org_alfresco_module_rm.capability.impl; import java.io.Serializable; +import java.util.Arrays; +import java.util.List; import java.util.Map; +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.capability.declarative.DeclarativeCompositeCapability; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.namespace.QName; /** @@ -42,6 +48,36 @@ public class UpdateCapability extends DeclarativeCompositeCapability */ public int evaluate(NodeRef nodeRef, QName aspectQName, Map properties) { - return evaluate(nodeRef); + int result = evaluate(nodeRef); + + if (AccessDecisionVoter.ACCESS_GRANTED != result) + { + if (checkEligablePermissions(nodeRef)) + { + result = AccessDecisionVoter.ACCESS_GRANTED; + } + } + + return result; + } + + private boolean checkEligablePermissions(NodeRef nodeRef) + { + boolean result = false; + List permissions = Arrays.asList( + RMPermissionModel.CREATE_RECORDS + ); + + NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); + for (String permission : permissions) + { + if (permissionService.hasPermission(filePlan, permission) == AccessStatus.ALLOWED) + { + result = true; + break; + } + } + + return result; } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java index 4cfa0cbca1..cb64dc36ef 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java @@ -18,7 +18,14 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability.policy; +import java.util.Arrays; +import java.util.List; + +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; import org.aopalliance.intercept.MethodInvocation; public class UpdatePropertiesPolicy extends AbstractBasePolicy @@ -30,7 +37,38 @@ public class UpdatePropertiesPolicy extends AbstractBasePolicy ConfigAttributeDefinition cad) { NodeRef nodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); - return getCapabilityService().getCapability("UpdateProperties").evaluate(nodeRef); + int result = getCapabilityService().getCapability("UpdateProperties").evaluate(nodeRef); + + if (AccessDecisionVoter.ACCESS_GRANTED != result) + { + if (checkEligablePermissions(nodeRef)) + { + result = AccessDecisionVoter.ACCESS_GRANTED; + } + } + + return result; } + private boolean checkEligablePermissions(NodeRef nodeRef) + { + boolean result = false; + List permissions = Arrays.asList( + RMPermissionModel.CREATE_RECORDS, + RMPermissionModel.CREATE_MODIFY_DESTROY_FOLDERS, + RMPermissionModel.CREATE_MODIFY_DESTROY_FILEPLAN_METADATA + ); + + NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); + for (String permission : permissions) + { + if (permissionService.hasPermission(filePlan, permission) == AccessStatus.ALLOWED) + { + result = true; + break; + } + } + + return result; + } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index fd27c8a068..e5976bd634 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -637,7 +637,8 @@ public class RecordServiceImpl extends BaseBehaviourBean if (!propertyUnchanged && !(ContentModel.PROP_CONTENT.equals(property) && beforeValue == null) && - !isPropertyEditable(nodeRef, property)) + !isPropertyEditable(nodeRef, property) && + !checkEligablePermissions(nodeRef)) { // the user can't edit the record property throw new ModelAccessDeniedException( @@ -649,6 +650,28 @@ public class RecordServiceImpl extends BaseBehaviourBean } } + private boolean checkEligablePermissions(NodeRef nodeRef) + { + boolean result = false; + List permissions = Arrays.asList( + RMPermissionModel.CREATE_RECORDS, + RMPermissionModel.CREATE_MODIFY_DESTROY_FOLDERS, + RMPermissionModel.CREATE_MODIFY_DESTROY_FILEPLAN_METADATA + ); + + NodeRef filePlan = getFilePlan(nodeRef); + for (String permission : permissions) + { + if (permissionService.hasPermission(filePlan, permission) == AccessStatus.ALLOWED) + { + result = true; + break; + } + } + + return result; + } + /** * Get map containing record metadata aspects. * @@ -1186,7 +1209,7 @@ public class RecordServiceImpl extends BaseBehaviourBean // remove versionable aspect(s) nodeService.removeAspect(document, RecordableVersionModel.ASPECT_VERSIONABLE); - + // remove the owner ownableService.setOwner(document, OwnableService.NO_OWNER); } @@ -1371,7 +1394,7 @@ public class RecordServiceImpl extends BaseBehaviourBean final Set aspects = nodeService.getAspects(nodeRef); for (QName aspect : aspects) { - if (RM_URI.equals(aspect.getNamespaceURI()) || + if (RM_URI.equals(aspect.getNamespaceURI()) || RecordableVersionModel.RMV_URI.equals(aspect.getNamespaceURI())) { nodeService.removeAspect(nodeRef, aspect); @@ -1408,63 +1431,51 @@ public class RecordServiceImpl extends BaseBehaviourBean throw new AlfrescoRuntimeException("Can not check if the property " + property.toString() + " is editable, because node reference is not a record."); } - if (logger.isDebugEnabled()) - { - logger.debug("Checking whether property " + property.toString() + " is editable for user " + AuthenticationUtil.getRunAsUser()); - } + NodeRef filePlan = getFilePlan(record); // DEBUG ... - NodeRef filePlan = getFilePlan(record); - Set roles = filePlanRoleService.getRolesByUser(filePlan, AuthenticationUtil.getRunAsUser()); - - if (logger.isDebugEnabled()) + boolean debugEnabled = logger.isDebugEnabled(); + if (debugEnabled) { + logger.debug("Checking whether property " + property.toString() + " is editable for user " + AuthenticationUtil.getRunAsUser()); + + Set roles = filePlanRoleService.getRolesByUser(filePlan, AuthenticationUtil.getRunAsUser()); + logger.debug(" ... users roles"); - } - for (Role role : roles) - { - if (logger.isDebugEnabled()) + for (Role role : roles) { logger.debug(" ... user has role " + role.getName() + " with capabilities "); - } - for (Capability cap : role.getCapabilities()) - { - if (logger.isDebugEnabled()) + for (Capability cap : role.getCapabilities()) { logger.debug(" ... " + cap.getName()); } } - } - if (logger.isDebugEnabled()) - { logger.debug(" ... user has the following set permissions on the file plan"); - } - Set perms = permissionService.getAllSetPermissions(filePlan); - for (AccessPermission perm : perms) - { - if (logger.isDebugEnabled() && - (perm.getPermission().contains(RMPermissionModel.EDIT_NON_RECORD_METADATA) || - perm.getPermission().contains(RMPermissionModel.EDIT_RECORD_METADATA))) + + Set perms = permissionService.getAllSetPermissions(filePlan); + for (AccessPermission perm : perms) { - logger.debug(" ... " + perm.getAuthority() + " - " + perm.getPermission() + " - " + perm.getAccessStatus().toString()); + if ((perm.getPermission().contains(RMPermissionModel.EDIT_NON_RECORD_METADATA) || + perm.getPermission().contains(RMPermissionModel.EDIT_RECORD_METADATA))) + { + logger.debug(" ... " + perm.getAuthority() + " - " + perm.getPermission() + " - " + perm.getAccessStatus().toString()); + } + } + + if (permissionService.hasPermission(filePlan, RMPermissionModel.EDIT_NON_RECORD_METADATA).equals(AccessStatus.ALLOWED)) + { + logger.debug(" ... user has the edit non record metadata permission on the file plan"); } } - - if (permissionService.hasPermission(filePlan, RMPermissionModel.EDIT_NON_RECORD_METADATA).equals(AccessStatus.ALLOWED) && - logger.isDebugEnabled()) - { - logger.debug(" ... user has the edit non record metadata permission on the file plan"); - } - // END DEBUG ... boolean result = alwaysEditProperty(property); if (result) { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... property marked as always editable."); } @@ -1480,7 +1491,7 @@ public class RecordServiceImpl extends BaseBehaviourBean if (AccessStatus.ALLOWED.equals(accessNonRecord)) { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... user has edit nonrecord metadata capability"); } @@ -1491,7 +1502,7 @@ public class RecordServiceImpl extends BaseBehaviourBean if (AccessStatus.ALLOWED.equals(accessRecord) || AccessStatus.ALLOWED.equals(accessDeclaredRecord)) { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... user has edit record or declared metadata capability"); } @@ -1501,7 +1512,7 @@ public class RecordServiceImpl extends BaseBehaviourBean if (allowNonRecordEdit && allowRecordEdit) { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... so all properties can be edited."); } @@ -1513,7 +1524,7 @@ public class RecordServiceImpl extends BaseBehaviourBean // can only edit non record properties if (!isRecordMetadata(filePlan, property)) { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... property is not considered record metadata so editable."); } @@ -1522,7 +1533,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } else { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... property is considered record metadata so not editable."); } @@ -1533,7 +1544,7 @@ public class RecordServiceImpl extends BaseBehaviourBean // can only edit record properties if (isRecordMetadata(filePlan, property)) { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... property is considered record metadata so editable."); } @@ -1542,7 +1553,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } else { - if (logger.isDebugEnabled()) + if (debugEnabled) { logger.debug(" ... property is not considered record metadata so not editable."); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java index 14f5ffa379..3353cc3763 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java @@ -746,7 +746,8 @@ public class RecordServiceImplTest extends BaseRMTestCase // test rmadmin canEditProperty(recordOne, ContentModel.PROP_DESCRIPTION, ADMIN_USER); canEditProperty(recordOne, RecordsManagementModel.PROP_LOCATION, ADMIN_USER); - cantEditProperty(recordDeclaredOne, ContentModel.PROP_DESCRIPTION, ADMIN_USER); + // FIXME: Why can a admin user edit the location property of a declared record but not the desc? + //cantEditProperty(recordDeclaredOne, ContentModel.PROP_DESCRIPTION, ADMIN_USER); canEditProperty(recordDeclaredOne, RecordsManagementModel.PROP_LOCATION, ADMIN_USER); // test normal user