mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-1724 (Inheritance is not off for root categories, unfiled records, holds and transfers)
RM-1725 (Inheritance is not working properly) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@88182 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -21,10 +21,8 @@ package org.alfresco.module.org_alfresco_module_rm.security;
|
|||||||
import static org.apache.commons.lang.BooleanUtils.isTrue;
|
import static org.apache.commons.lang.BooleanUtils.isTrue;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
|
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||||
@@ -43,7 +41,6 @@ import org.alfresco.service.cmr.security.AccessPermission;
|
|||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
|
||||||
import org.alfresco.util.ParameterCheck;
|
import org.alfresco.util.ParameterCheck;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -404,11 +401,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void setUpPermissions(final NodeRef nodeRef)
|
||||||
*
|
|
||||||
* @param nodeRef
|
|
||||||
*/
|
|
||||||
public void setUpPermissions(final NodeRef nodeRef)
|
|
||||||
{
|
{
|
||||||
setUpPermissions(nodeRef, null);
|
setUpPermissions(nodeRef, null);
|
||||||
}
|
}
|
||||||
@@ -421,7 +414,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
public Object doWork()
|
public Object doWork()
|
||||||
{
|
{
|
||||||
// break inheritance
|
// set inheritance
|
||||||
permissionService.setInheritParentPermissions(nodeRef, isInheritanceAllowed(nodeRef, isParentNodeFilePlan));
|
permissionService.setInheritParentPermissions(nodeRef, isInheritanceAllowed(nodeRef, isParentNodeFilePlan));
|
||||||
|
|
||||||
// set extended reader permissions
|
// set extended reader permissions
|
||||||
@@ -436,7 +429,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
|
|
||||||
private boolean isInheritanceAllowed(NodeRef nodeRef, Boolean isParentNodeFilePlan)
|
private boolean isInheritanceAllowed(NodeRef nodeRef, Boolean isParentNodeFilePlan)
|
||||||
{
|
{
|
||||||
return !(isFilePlan(nodeRef) || isHold(nodeRef) || isTransfer(nodeRef) || (isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan)));
|
return !(isFilePlan(nodeRef) || isTransfer(nodeRef) || isHold(nodeRef) || isUnfiledRecordsContainer(nodeRef) || (isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -452,12 +445,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
public Boolean doWork() throws Exception
|
public Boolean doWork() throws Exception
|
||||||
{
|
{
|
||||||
if (filePlanService.isFilePlan(nodeRef) ||
|
if (canPerformPermissionAction(nodeRef))
|
||||||
filePlanService.isFilePlanContainer(nodeRef) ||
|
|
||||||
recordsManagementService.isRecordFolder(nodeRef) ||
|
|
||||||
recordService.isRecord(nodeRef))
|
|
||||||
{
|
{
|
||||||
setPermissionDown(nodeRef, authority, permission);
|
if (RMPermissionModel.FILING.equals(permission))
|
||||||
|
{
|
||||||
|
// Remove record read permission before adding filing permission
|
||||||
|
permissionService.deletePermission(nodeRef, authority, RMPermissionModel.READ_RECORDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the permission on the node
|
||||||
|
permissionService.setPermission(nodeRef, authority, permission, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -472,57 +469,6 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to set the permission down the hierarchy
|
|
||||||
*
|
|
||||||
* @param nodeRef node reference
|
|
||||||
* @param authority authority
|
|
||||||
* @param permission permission
|
|
||||||
*/
|
|
||||||
private void setPermissionDown(NodeRef nodeRef, String authority, String permission)
|
|
||||||
{
|
|
||||||
// set permissions
|
|
||||||
setPermissionImpl(nodeRef, authority, permission);
|
|
||||||
|
|
||||||
// skip out node's that inherit (for example hold and transfer)
|
|
||||||
if (!permissionService.getInheritParentPermissions(nodeRef) &&
|
|
||||||
(filePlanService.isFilePlanContainer(nodeRef) ||
|
|
||||||
recordsManagementService.isRecordFolder(nodeRef)))
|
|
||||||
{
|
|
||||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
for (ChildAssociationRef assoc : assocs)
|
|
||||||
{
|
|
||||||
NodeRef child = assoc.getChildRef();
|
|
||||||
if (filePlanService.isFilePlanContainer(child) ||
|
|
||||||
recordsManagementService.isRecordFolder(child) ||
|
|
||||||
recordService.isRecord(child) ||
|
|
||||||
instanceOf(child, TYPE_HOLD) ||
|
|
||||||
instanceOf(child, TYPE_TRANSFER))
|
|
||||||
{
|
|
||||||
setPermissionDown(child, authority, permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the permission, taking into account that filing is a superset of read
|
|
||||||
*
|
|
||||||
* @param nodeRef
|
|
||||||
* @param authority
|
|
||||||
* @param permission
|
|
||||||
*/
|
|
||||||
private void setPermissionImpl(NodeRef nodeRef, String authority, String permission)
|
|
||||||
{
|
|
||||||
if (RMPermissionModel.FILING.equals(permission) == true)
|
|
||||||
{
|
|
||||||
// Remove record read permission before adding filing permission
|
|
||||||
permissionService.deletePermission(nodeRef, authority, RMPermissionModel.READ_RECORDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
permissionService.setPermission(nodeRef, authority, permission, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#deletePermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String)
|
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#deletePermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@@ -532,26 +478,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
public Boolean doWork() throws Exception
|
public Boolean doWork() throws Exception
|
||||||
{
|
{
|
||||||
// Delete permission on this node
|
if (canPerformPermissionAction(nodeRef))
|
||||||
permissionService.deletePermission(nodeRef, authority, permission);
|
|
||||||
|
|
||||||
// can't delete permissions if inherited (eg hold and transfer containers)
|
|
||||||
if (!permissionService.getInheritParentPermissions(nodeRef) &&
|
|
||||||
(filePlanService.isFilePlanContainer(nodeRef) ||
|
|
||||||
recordsManagementService.isRecordFolder(nodeRef)))
|
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
// Delete permission on this node
|
||||||
for (ChildAssociationRef assoc : assocs)
|
permissionService.deletePermission(nodeRef, authority, permission);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
{
|
{
|
||||||
NodeRef child = assoc.getChildRef();
|
logger.warn("Deleting permissions for this node is not supported. (nodeRef=" + nodeRef + ", authority=" + authority + ", permission=" + permission + ")");
|
||||||
if (filePlanService.isFilePlanContainer(child) ||
|
|
||||||
recordsManagementService.isRecordFolder(child) ||
|
|
||||||
recordService.isRecord(child)||
|
|
||||||
instanceOf(child, TYPE_HOLD) ||
|
|
||||||
instanceOf(child, TYPE_TRANSFER))
|
|
||||||
{
|
|
||||||
deletePermission(child, authority, permission);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,4 +495,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
|||||||
}
|
}
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canPerformPermissionAction(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
return filePlanService.isFilePlanContainer(nodeRef) || recordsManagementService.isRecordFolder(nodeRef) || recordService.isRecord(nodeRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ import org.springframework.context.ApplicationContextAware;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper base class for service implementations.
|
* Helper base class for service implementations.
|
||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +54,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
|
|
||||||
/** Application context */
|
/** Application context */
|
||||||
protected ApplicationContext applicationContext;
|
protected ApplicationContext applicationContext;
|
||||||
|
|
||||||
/** internal node service */
|
/** internal node service */
|
||||||
private NodeService internalNodeService;
|
private NodeService internalNodeService;
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
{
|
{
|
||||||
this.dictionaryService = dictionaryService;
|
this.dictionaryService = dictionaryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to get internal node service.
|
* Helper to get internal node service.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -94,10 +94,10 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
{
|
{
|
||||||
internalNodeService = (NodeService)applicationContext.getBean("dbNodeService");
|
internalNodeService = (NodeService)applicationContext.getBean("dbNodeService");
|
||||||
}
|
}
|
||||||
|
|
||||||
return internalNodeService;
|
return internalNodeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the file plan component kind from the given node reference
|
* Gets the file plan component kind from the given node reference
|
||||||
*
|
*
|
||||||
@@ -117,7 +117,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
if (isFilePlanComponent(nodeRef))
|
if (isFilePlanComponent(nodeRef))
|
||||||
{
|
{
|
||||||
result = FilePlanComponentKind.FILE_PLAN_COMPONENT;
|
result = FilePlanComponentKind.FILE_PLAN_COMPONENT;
|
||||||
|
|
||||||
if (isFilePlan(nodeRef))
|
if (isFilePlan(nodeRef))
|
||||||
{
|
{
|
||||||
result = FilePlanComponentKind.FILE_PLAN;
|
result = FilePlanComponentKind.FILE_PLAN;
|
||||||
@@ -146,12 +146,12 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
{
|
{
|
||||||
result = FilePlanComponentKind.DISPOSITION_SCHEDULE;
|
result = FilePlanComponentKind.DISPOSITION_SCHEDULE;
|
||||||
}
|
}
|
||||||
else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER))
|
else if (isUnfiledRecordsContainer(nodeRef))
|
||||||
{
|
{
|
||||||
result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER;
|
result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
map.put(nodeRef, result);
|
map.put(nodeRef, result);
|
||||||
@@ -297,7 +297,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
|
|
||||||
boolean isHold = false;
|
boolean isHold = false;
|
||||||
if (getInternalNodeService().exists(nodeRef) &&
|
if (getInternalNodeService().exists(nodeRef) &&
|
||||||
instanceOf(nodeRef, TYPE_HOLD))
|
instanceOf(nodeRef, TYPE_HOLD))
|
||||||
{
|
{
|
||||||
isHold = true;
|
isHold = true;
|
||||||
@@ -316,10 +316,23 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
|
|
||||||
return instanceOf(nodeRef, TYPE_TRANSFER);
|
return instanceOf(nodeRef, TYPE_TRANSFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the given node reference is an unfiled records container or not.
|
||||||
|
*
|
||||||
|
* @param nodeRef node reference
|
||||||
|
* @return boolean true if rma:unfiledRecordContainer or sub-type, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isUnfiledRecordsContainer(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
|
|
||||||
|
return instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether a record is complete or not.
|
* Indicates whether a record is complete or not.
|
||||||
*
|
*
|
||||||
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
public boolean isDeclared(NodeRef record)
|
public boolean isDeclared(NodeRef record)
|
||||||
@@ -338,12 +351,12 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
public NodeRef getFilePlan(final NodeRef nodeRef)
|
public NodeRef getFilePlan(final NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
NodeRef result = null;
|
NodeRef result = null;
|
||||||
if (nodeRef != null)
|
if (nodeRef != null)
|
||||||
{
|
{
|
||||||
Map<NodeRef, NodeRef> transactionCache = TransactionalResourceHelper.getMap("rm.servicebase.getFilePlan");
|
Map<NodeRef, NodeRef> transactionCache = TransactionalResourceHelper.getMap("rm.servicebase.getFilePlan");
|
||||||
if (transactionCache.containsKey(nodeRef))
|
if (transactionCache.containsKey(nodeRef))
|
||||||
{
|
{
|
||||||
result = transactionCache.get(nodeRef);
|
result = transactionCache.get(nodeRef);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -363,7 +376,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache result in transaction
|
// cache result in transaction
|
||||||
transactionCache.put(nodeRef, result);
|
transactionCache.put(nodeRef, result);
|
||||||
}
|
}
|
||||||
@@ -381,11 +394,11 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
protected boolean instanceOf(NodeRef nodeRef, QName ofClassName)
|
protected boolean instanceOf(NodeRef nodeRef, QName ofClassName)
|
||||||
{
|
{
|
||||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
ParameterCheck.mandatory("ofClassName", ofClassName);
|
ParameterCheck.mandatory("ofClassName", ofClassName);
|
||||||
QName className = getInternalNodeService().getType(nodeRef);
|
QName className = getInternalNodeService().getType(nodeRef);
|
||||||
return instanceOf(className, ofClassName);
|
return instanceOf(className, ofClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Boolean> instanceOfCache = new HashMap<String, Boolean>();
|
private static Map<String, Boolean> instanceOfCache = new HashMap<String, Boolean>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -399,25 +412,25 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
|||||||
{
|
{
|
||||||
ParameterCheck.mandatory("className", className);
|
ParameterCheck.mandatory("className", className);
|
||||||
ParameterCheck.mandatory("ofClassName", ofClassName);
|
ParameterCheck.mandatory("ofClassName", ofClassName);
|
||||||
|
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
|
||||||
String key = className.toString() + "|" + ofClassName.toString();
|
String key = className.toString() + "|" + ofClassName.toString();
|
||||||
if (instanceOfCache.containsKey(key))
|
if (instanceOfCache.containsKey(key))
|
||||||
{
|
{
|
||||||
result = instanceOfCache.get(key);
|
result = instanceOfCache.get(key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ofClassName.equals(className) ||
|
if (ofClassName.equals(className) ||
|
||||||
dictionaryService.isSubClass(className, ofClassName))
|
dictionaryService.isSubClass(className, ofClassName))
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceOfCache.put(key, result);
|
instanceOfCache.put(key, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user