RM-1956 (Create record capability allows user to edit metadata and copy category/folder /record)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.3@97718 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2015-02-22 14:11:17 +00:00
parent 481341dedb
commit 8ed56c8d91
4 changed files with 134 additions and 48 deletions

View File

@@ -19,10 +19,16 @@
package org.alfresco.module.org_alfresco_module_rm.capability.impl; package org.alfresco.module.org_alfresco_module_rm.capability.impl;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map; 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.module.org_alfresco_module_rm.capability.declarative.DeclarativeCompositeCapability;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
/** /**
@@ -42,6 +48,36 @@ public class UpdateCapability extends DeclarativeCompositeCapability
*/ */
public int evaluate(NodeRef nodeRef, QName aspectQName, Map<QName, Serializable> properties) public int evaluate(NodeRef nodeRef, QName aspectQName, Map<QName, Serializable> 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<String> 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;
} }
} }

View File

@@ -18,7 +18,14 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.capability.policy; 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.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
public class UpdatePropertiesPolicy extends AbstractBasePolicy public class UpdatePropertiesPolicy extends AbstractBasePolicy
@@ -30,7 +37,38 @@ public class UpdatePropertiesPolicy extends AbstractBasePolicy
ConfigAttributeDefinition cad) ConfigAttributeDefinition cad)
{ {
NodeRef nodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); 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<String> 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;
}
} }

View File

@@ -637,7 +637,8 @@ public class RecordServiceImpl extends BaseBehaviourBean
if (!propertyUnchanged && if (!propertyUnchanged &&
!(ContentModel.PROP_CONTENT.equals(property) && beforeValue == null) && !(ContentModel.PROP_CONTENT.equals(property) && beforeValue == null) &&
!isPropertyEditable(nodeRef, property)) !isPropertyEditable(nodeRef, property) &&
!checkEligablePermissions(nodeRef))
{ {
// the user can't edit the record property // the user can't edit the record property
throw new ModelAccessDeniedException( throw new ModelAccessDeniedException(
@@ -649,6 +650,28 @@ public class RecordServiceImpl extends BaseBehaviourBean
} }
} }
private boolean checkEligablePermissions(NodeRef nodeRef)
{
boolean result = false;
List<String> 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. * Get map containing record metadata aspects.
* *
@@ -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."); throw new AlfrescoRuntimeException("Can not check if the property " + property.toString() + " is editable, because node reference is not a record.");
} }
if (logger.isDebugEnabled()) NodeRef filePlan = getFilePlan(record);
{
logger.debug("Checking whether property " + property.toString() + " is editable for user " + AuthenticationUtil.getRunAsUser());
}
// DEBUG ... // DEBUG ...
NodeRef filePlan = getFilePlan(record); boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled)
{
logger.debug("Checking whether property " + property.toString() + " is editable for user " + AuthenticationUtil.getRunAsUser());
Set<Role> roles = filePlanRoleService.getRolesByUser(filePlan, AuthenticationUtil.getRunAsUser()); Set<Role> roles = filePlanRoleService.getRolesByUser(filePlan, AuthenticationUtil.getRunAsUser());
if (logger.isDebugEnabled())
{
logger.debug(" ... users roles"); logger.debug(" ... users roles");
}
for (Role role : roles) for (Role role : roles)
{
if (logger.isDebugEnabled())
{ {
logger.debug(" ... user has role " + role.getName() + " with capabilities "); logger.debug(" ... user has role " + role.getName() + " with capabilities ");
}
for (Capability cap : role.getCapabilities()) for (Capability cap : role.getCapabilities())
{
if (logger.isDebugEnabled())
{ {
logger.debug(" ... " + cap.getName()); logger.debug(" ... " + cap.getName());
} }
} }
}
if (logger.isDebugEnabled())
{
logger.debug(" ... user has the following set permissions on the file plan"); logger.debug(" ... user has the following set permissions on the file plan");
}
Set<AccessPermission> perms = permissionService.getAllSetPermissions(filePlan); Set<AccessPermission> perms = permissionService.getAllSetPermissions(filePlan);
for (AccessPermission perm : perms) for (AccessPermission perm : perms)
{ {
if (logger.isDebugEnabled() && if ((perm.getPermission().contains(RMPermissionModel.EDIT_NON_RECORD_METADATA) ||
(perm.getPermission().contains(RMPermissionModel.EDIT_NON_RECORD_METADATA) ||
perm.getPermission().contains(RMPermissionModel.EDIT_RECORD_METADATA))) perm.getPermission().contains(RMPermissionModel.EDIT_RECORD_METADATA)))
{ {
logger.debug(" ... " + perm.getAuthority() + " - " + perm.getPermission() + " - " + perm.getAccessStatus().toString()); logger.debug(" ... " + perm.getAuthority() + " - " + perm.getPermission() + " - " + perm.getAccessStatus().toString());
} }
} }
if (permissionService.hasPermission(filePlan, RMPermissionModel.EDIT_NON_RECORD_METADATA).equals(AccessStatus.ALLOWED) && 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"); logger.debug(" ... user has the edit non record metadata permission on the file plan");
} }
}
// END DEBUG ... // END DEBUG ...
boolean result = alwaysEditProperty(property); boolean result = alwaysEditProperty(property);
if (result) if (result)
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... property marked as always editable."); logger.debug(" ... property marked as always editable.");
} }
@@ -1480,7 +1491,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
if (AccessStatus.ALLOWED.equals(accessNonRecord)) if (AccessStatus.ALLOWED.equals(accessNonRecord))
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... user has edit nonrecord metadata capability"); logger.debug(" ... user has edit nonrecord metadata capability");
} }
@@ -1491,7 +1502,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
if (AccessStatus.ALLOWED.equals(accessRecord) || if (AccessStatus.ALLOWED.equals(accessRecord) ||
AccessStatus.ALLOWED.equals(accessDeclaredRecord)) AccessStatus.ALLOWED.equals(accessDeclaredRecord))
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... user has edit record or declared metadata capability"); logger.debug(" ... user has edit record or declared metadata capability");
} }
@@ -1501,7 +1512,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
if (allowNonRecordEdit && allowRecordEdit) if (allowNonRecordEdit && allowRecordEdit)
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... so all properties can be edited."); logger.debug(" ... so all properties can be edited.");
} }
@@ -1513,7 +1524,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
// can only edit non record properties // can only edit non record properties
if (!isRecordMetadata(filePlan, property)) if (!isRecordMetadata(filePlan, property))
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... property is not considered record metadata so editable."); logger.debug(" ... property is not considered record metadata so editable.");
} }
@@ -1522,7 +1533,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
} }
else else
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... property is considered record metadata so not editable."); logger.debug(" ... property is considered record metadata so not editable.");
} }
@@ -1533,7 +1544,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
// can only edit record properties // can only edit record properties
if (isRecordMetadata(filePlan, property)) if (isRecordMetadata(filePlan, property))
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... property is considered record metadata so editable."); logger.debug(" ... property is considered record metadata so editable.");
} }
@@ -1542,7 +1553,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
} }
else else
{ {
if (logger.isDebugEnabled()) if (debugEnabled)
{ {
logger.debug(" ... property is not considered record metadata so not editable."); logger.debug(" ... property is not considered record metadata so not editable.");
} }

View File

@@ -746,7 +746,8 @@ public class RecordServiceImplTest extends BaseRMTestCase
// test rmadmin // test rmadmin
canEditProperty(recordOne, ContentModel.PROP_DESCRIPTION, ADMIN_USER); canEditProperty(recordOne, ContentModel.PROP_DESCRIPTION, ADMIN_USER);
canEditProperty(recordOne, RecordsManagementModel.PROP_LOCATION, 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); canEditProperty(recordDeclaredOne, RecordsManagementModel.PROP_LOCATION, ADMIN_USER);
// test normal user // test normal user