mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge BRANCHES/V2.1.0.x to BRANCHES/V2.2:
68559: Change base Alfresco version from 4.2.0-RC4 to 4.2.0 68568: Merge from HEAD to BRANCHES/V2.1.0.x 68569: Update module version to 2.1.0.1 76475: Merge HEAD to BRANCHES/V2.1.0.x: 76597: Merge HEAD to BRANCHES/V2.1.0.x: 74932: RM-1461: CLONE - RM slower then standard repo/sites when rendering document details when folder contains 15k documents 76598: Merged HEAD to BRANCHES/V2.1.0.x: 75102: RM Performance testing 76599: Update module version to 2.1.0.2 76601: Merged HEAD to BRANCHES/V2.1.0.x: 75186: RM Performance Improvements 76673: Root container cache to improve unfiled record browse performance * relates to RM-1594 and RM-1595 76850: RM performance enhancements * serach improvements * in-place record browse improvements * saved search via file plan browse improvements 76851: Additional unit test to check extended security with cache is working as expected. 76852: Rollback checked in config 77709: RM-1630: Error on manage references page * regression caused by performance improvements 84337: Update version to 2.1.0.3 84421: Transaction level cahcing of declarative capability evaluation 84676: Fix build 84677: Prevent unnessary repeated creation of QName 84678: Improvements to extended dynamic authorities * requiredFor set * direct access to extended permission information, not via service 84679: Correct requiredFor value 88087: RM-1661 (Performance on setting permissions at a high category level) 88092: RM-1661 (Performance on setting permissions at a high category level) * Fixed failing unit tests 88144: RM-1661 (Performance on setting permissions at a high category level) 88182: RM-1724 (Inheritance is not off for root categories, unfiled records, holds and transfers) 88192: RM-1661 (Performance on setting permissions at a high category level) * Added unit tests 88193: RM-1661 (Performance on setting permissions at a high category level) * Fixed failing unit tests 88358: RM-1661 (Performance on setting permissions at a high category level) * Added unit tests 88685: RM-1742 (Locally Set Permissions for moved Record duplicate parent folder Locally Set Permissions) 88686: RM-1741 (Moved root category doesn't inherit permissions) 88687: RM-1741 (Moved root category doesn't inherit permissions) * Unit test added 88688: RM-1742 (Locally Set Permissions for moved Record duplicate parent folder Locally Set Permissions) * Unit test added 88691: RM-1745 (RM Admin role can only be added with read permission on the manage permission page) 88772: RM-1741 (Moved root category doesn't inherit permissions) 88860: RM-1661 (Performance on setting permissions at a high category level) 88864: RM-1661 (Performance on setting permissions at a high category level) * Fixed failing unit tests 88959: RM-1746 (Moved record/category always have the inheritance on) 88960: RM-1661 (Performance on setting permissions at a high category level) * Fixed failing unit tests 88961: RM-1661 (Performance on setting permissions at a high category level) * Fixed failing unit tests 88962: RM-1661 (Performance on setting permissions at a high category level) * Fixed failing unit tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.2@89251 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
package org.alfresco.module.org_alfresco_module_rm.capability;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
|
||||
|
||||
/**
|
||||
@@ -34,13 +35,32 @@ public interface RMPermissionModel
|
||||
String FILE_RECORDS = "FileRecords";
|
||||
|
||||
// Roles
|
||||
String ROLE_NAME_USER = "User";
|
||||
String ROLE_NAME_POWER_USER = "PowerUser";
|
||||
String ROLE_NAME_SECURITY_OFFICER = "SecurityOfficer";
|
||||
String ROLE_NAME_RECORDS_MANAGER = "RecordsManager";
|
||||
|
||||
String ROLE_NAME_ADMINISTRATOR = "Administrator";
|
||||
String ROLE_ADMINISTRATOR = SimplePermissionReference.getPermissionReference(RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT, ROLE_NAME_ADMINISTRATOR).toString();
|
||||
/**
|
||||
* @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_USER} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ROLE_NAME_USER = FilePlanRoleService.ROLE_USER;
|
||||
/**
|
||||
* @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_POWER_USER} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ROLE_NAME_POWER_USER = FilePlanRoleService.ROLE_POWER_USER;
|
||||
/**
|
||||
* @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_SECURITY_OFFICER} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ROLE_NAME_SECURITY_OFFICER = FilePlanRoleService.ROLE_SECURITY_OFFICER;
|
||||
/**
|
||||
* @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_RECORDS_MANAGER} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ROLE_NAME_RECORDS_MANAGER = FilePlanRoleService.ROLE_RECORDS_MANAGER;
|
||||
/**
|
||||
* @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_ADMIN} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ROLE_NAME_ADMINISTRATOR = FilePlanRoleService.ROLE_ADMIN;
|
||||
public static final String ROLE_ADMINISTRATOR = SimplePermissionReference.getPermissionReference(RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT, FilePlanRoleService.ROLE_ADMIN).toString();
|
||||
|
||||
// Capability permissions
|
||||
|
||||
|
@@ -18,14 +18,16 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.capability;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigComponent;
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.TransactionalResourceHelper;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -33,6 +35,7 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -201,54 +204,82 @@ public class RMSecurityCommon implements ApplicationContextAware
|
||||
}
|
||||
|
||||
/**
|
||||
* Core RM read check
|
||||
*
|
||||
* @param nodeRef
|
||||
* @return
|
||||
* @param nodeRef node reference
|
||||
* @return int see {@link AccessDecisionVoter}
|
||||
*/
|
||||
public int checkRmRead(NodeRef nodeRef)
|
||||
{
|
||||
int result = getTransactionCache("checkRmRead", nodeRef);
|
||||
if (result != NOSET_VALUE)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
int result = AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
|
||||
if (permissionService.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS) == AccessStatus.DENIED)
|
||||
{
|
||||
// log message
|
||||
RMMethodSecurityInterceptor.addMessage("User does not have read record permission on node, access denied. (nodeRef={0}, user={1})", nodeRef, AuthenticationUtil.getRunAsUser());
|
||||
Map<Pair<String, NodeRef>, Integer> transactionCache = TransactionalResourceHelper.getMap("rm.security.checkRMRead");
|
||||
Pair<String, NodeRef> key = new Pair<String, NodeRef>(AuthenticationUtil.getRunAsUser(), nodeRef);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\t\tUser does not have read record permission on node, access denied. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")");
|
||||
}
|
||||
if (transactionCache.containsKey(key))
|
||||
{
|
||||
result = transactionCache.get(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (permissionService.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS) == AccessStatus.DENIED)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\t\tUser does not have read record permission on node, access denied. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")");
|
||||
}
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the file plan for the node
|
||||
NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef);
|
||||
if (hasViewCapability(filePlan) == AccessStatus.DENIED)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\t\tUser does not have view records capability permission on node, access denied. (filePlan=" + filePlan.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")");
|
||||
}
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else if (!caveatConfigComponent.hasAccess(nodeRef))
|
||||
{
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = AccessDecisionVoter.ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED);
|
||||
}
|
||||
|
||||
// Get the file plan for the node
|
||||
NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef);
|
||||
if (permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS) == AccessStatus.DENIED)
|
||||
{
|
||||
// log capability details
|
||||
RMMethodSecurityInterceptor.reportCapabilityStatus(RMPermissionModel.VIEW_RECORDS, AccessDecisionVoter.ACCESS_DENIED);
|
||||
// cache result
|
||||
transactionCache.put(key, result);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\t\tUser does not have view records capability permission on node, access denied. (filePlan=" + filePlan.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")");
|
||||
}
|
||||
return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (caveatConfigComponent.hasAccess(nodeRef))
|
||||
{
|
||||
return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_GRANTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED);
|
||||
}
|
||||
/**
|
||||
* Helper method to determine whether the current user has view capability on the file plan
|
||||
*
|
||||
* @param filePlan file plan
|
||||
* @return {@link AccessStatus}
|
||||
*/
|
||||
private AccessStatus hasViewCapability(NodeRef filePlan)
|
||||
{
|
||||
Map<Pair<String, NodeRef>, AccessStatus> transactionCache = TransactionalResourceHelper.getMap("rm.security.hasViewCapability");
|
||||
Pair<String, NodeRef> key = new Pair<String, NodeRef>(AuthenticationUtil.getRunAsUser(), filePlan);
|
||||
|
||||
if (transactionCache.containsKey(key))
|
||||
{
|
||||
return transactionCache.get(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
AccessStatus result = permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS);
|
||||
transactionCache.put(key, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
@@ -30,6 +30,8 @@ import org.alfresco.module.org_alfresco_module_rm.capability.AbstractCapability;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.TransactionalResourceHelper;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -289,29 +291,41 @@ public class DeclarativeCapability extends AbstractCapability
|
||||
{
|
||||
int result = AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
|
||||
// Check we are dealing with a file plan component
|
||||
if (getFilePlanService().isFilePlanComponent(nodeRef))
|
||||
// check transaction cache
|
||||
Map<String, Integer> map = TransactionalResourceHelper.getMap("rm.declarativeCapability");
|
||||
String key = getName() + "|" + nodeRef.toString() + "|" + AuthenticationUtil.getRunAsUser();
|
||||
if (map.containsKey(key))
|
||||
{
|
||||
// Check the kind of the object, the permissions and the conditions
|
||||
if (checkKinds(nodeRef) && checkPermissions(nodeRef) && checkConditions(nodeRef))
|
||||
{
|
||||
// Opportunity for child implementations to extend
|
||||
result = evaluateImpl(nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
result = map.get(key);
|
||||
}
|
||||
|
||||
// Last chance for child implementations to veto/change the result
|
||||
result = onEvaluate(nodeRef, result);
|
||||
|
||||
// log access denied to help with debug
|
||||
if (LOGGER.isDebugEnabled() && AccessDecisionVoter.ACCESS_DENIED == result)
|
||||
else
|
||||
{
|
||||
LOGGER.debug("FAIL: Capability " + getName() + " returned an Access Denied result during evaluation of node " + nodeRef.toString());
|
||||
}
|
||||
// Check we are dealing with a file plan component
|
||||
if (getFilePlanService().isFilePlanComponent(nodeRef) == true)
|
||||
{
|
||||
// Check the kind of the object, the permissions and the conditions
|
||||
if (checkKinds(nodeRef) == true && checkPermissions(nodeRef) == true && checkConditions(nodeRef) == true)
|
||||
{
|
||||
// Opportunity for child implementations to extend
|
||||
result = evaluateImpl(nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
// Last chance for child implementations to veto/change the result
|
||||
result = onEvaluate(nodeRef, result);
|
||||
|
||||
// log access denied to help with debug
|
||||
if (LOGGER.isDebugEnabled() == true && AccessDecisionVoter.ACCESS_DENIED == result)
|
||||
{
|
||||
LOGGER.debug("Capability " + getName() + " returned an Access Denied result during evaluation of node " + nodeRef.toString());
|
||||
}
|
||||
|
||||
map.put(key, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -43,6 +43,11 @@ public class AtLeastOneCondition extends AbstractCapabilityCondition
|
||||
this.conditions = conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't use the transaction cache for the composite condition
|
||||
*
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public boolean evaluate(NodeRef nodeRef)
|
||||
{
|
||||
|
@@ -34,6 +34,7 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition
|
||||
{
|
||||
/** property name (eg: rma:location) */
|
||||
private String propertyName;
|
||||
private QName propertyQName;
|
||||
|
||||
/** namespace service */
|
||||
private NamespaceService namespaceService;
|
||||
@@ -59,7 +60,11 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition
|
||||
*/
|
||||
protected QName getPropertyQName()
|
||||
{
|
||||
return QName.createQName(propertyName, namespaceService);
|
||||
if (propertyQName == null)
|
||||
{
|
||||
propertyQName = QName.createQName(propertyName, namespaceService);
|
||||
}
|
||||
return propertyQName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -30,12 +30,21 @@ import java.util.Set;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.site.SiteInfo;
|
||||
import org.alfresco.service.cmr.site.SiteService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
@@ -52,7 +61,8 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
||||
* @since 2.1
|
||||
*/
|
||||
public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
implements FilePlanService
|
||||
implements FilePlanService,
|
||||
RecordsManagementModel
|
||||
{
|
||||
/** I18N */
|
||||
private static final String MSG_DUP_ROOT = "rm.service.dup-root";
|
||||
@@ -72,36 +82,41 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
/** RM site file plan container */
|
||||
private static final String FILE_PLAN_CONTAINER = "documentLibrary";
|
||||
|
||||
/** node DAO */
|
||||
private NodeDAO nodeDAO;
|
||||
|
||||
/** file plan permission service */
|
||||
private FilePlanPermissionService filePlanPermissionService;
|
||||
/** root container cache */
|
||||
private SimpleCache<Pair<NodeRef, String>, NodeRef> rootContainerCache;
|
||||
|
||||
/**
|
||||
* @param nodeDAO node DAO
|
||||
* @return file plan role service
|
||||
*/
|
||||
public void setNodeDAO(NodeDAO nodeDAO)
|
||||
protected FilePlanRoleService getFilePlanRoleService()
|
||||
{
|
||||
this.nodeDAO = nodeDAO;
|
||||
return (FilePlanRoleService)applicationContext.getBean("FilePlanRoleService");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return site service
|
||||
* @return permission service
|
||||
*/
|
||||
protected PermissionService getPermissionService()
|
||||
{
|
||||
return (PermissionService)applicationContext.getBean("permissionService");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return node DAO
|
||||
*/
|
||||
protected NodeDAO getNodeDAO()
|
||||
{
|
||||
return (NodeDAO)applicationContext.getBean("nodeDAO");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return site service
|
||||
*/
|
||||
protected SiteService getSiteService()
|
||||
{
|
||||
return (SiteService)applicationContext.getBean("siteService");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePlanPermissionService file plan permission service
|
||||
*/
|
||||
public void setFilePlanPermissionService(FilePlanPermissionService filePlanPermissionService)
|
||||
{
|
||||
this.filePlanPermissionService = filePlanPermissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlans()
|
||||
*/
|
||||
@@ -111,6 +126,14 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
return getFilePlans(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rootContainerCache root container cache
|
||||
*/
|
||||
public void setRootContainerCache(SimpleCache<Pair<NodeRef, String>, NodeRef> rootContainerCache)
|
||||
{
|
||||
this.rootContainerCache = rootContainerCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlans(org.alfresco.service.cmr.repository.StoreRef)
|
||||
*/
|
||||
@@ -122,7 +145,7 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
final Set<NodeRef> results = new HashSet<NodeRef>();
|
||||
Set<QName> aspects = new HashSet<QName>(1);
|
||||
aspects.add(ASPECT_RECORDS_MANAGEMENT_ROOT);
|
||||
nodeDAO.getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback()
|
||||
getNodeDAO().getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback()
|
||||
{
|
||||
@Override
|
||||
public boolean handle(Pair<Long, NodeRef> nodePair)
|
||||
@@ -198,10 +221,11 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file root container for the given type.
|
||||
*
|
||||
* @param filePlan
|
||||
* @param containerName
|
||||
* @return
|
||||
* @param filePlan file plan
|
||||
* @param containerName container type
|
||||
* @return {@link NodeRef} file plan container
|
||||
*/
|
||||
private NodeRef getFilePlanRootContainer(NodeRef filePlan, String containerName)
|
||||
{
|
||||
@@ -212,16 +236,25 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
|
||||
NodeRef result = null;
|
||||
Pair<NodeRef, String> key = new Pair<NodeRef, String>(filePlan, containerName);
|
||||
|
||||
// try and get the unfiled record container
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ContentModel.ASSOC_CONTAINS, QName.createQName(RM_URI, containerName));
|
||||
if (assocs.size() > 1)
|
||||
if (!rootContainerCache.contains(key))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to get unfiled conatiner " + containerName + ".");
|
||||
// try and get the unfiled record container
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ContentModel.ASSOC_CONTAINS, QName.createQName(RM_URI, containerName));
|
||||
if (assocs.size() > 1)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to get unfiled conatiner " + containerName + ".");
|
||||
}
|
||||
else if (assocs.size() == 1)
|
||||
{
|
||||
result = assocs.get(0).getChildRef();
|
||||
rootContainerCache.put(key, result);
|
||||
}
|
||||
}
|
||||
else if (assocs.size() == 1)
|
||||
else
|
||||
{
|
||||
result = assocs.get(0).getChildRef();
|
||||
result = rootContainerCache.get(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -269,6 +302,8 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
throw new AlfrescoRuntimeException("Unable to create file plan root container, because passed node is not a file plan.");
|
||||
}
|
||||
|
||||
String allRoles = getFilePlanRoleService().getAllRolesContainerGroup(filePlan);
|
||||
|
||||
// create the properties map
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(1);
|
||||
properties.put(ContentModel.PROP_NAME, containerName);
|
||||
@@ -281,8 +316,23 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
|
||||
containerType,
|
||||
properties).getChildRef();
|
||||
|
||||
// setup the permissions
|
||||
filePlanPermissionService.setupPermissions(filePlan, container);
|
||||
// if (inheritPermissions == false)
|
||||
// {
|
||||
// set inheritance to false
|
||||
getPermissionService().setInheritParentPermissions(container, false);
|
||||
getPermissionService().setPermission(container, allRoles, RMPermissionModel.READ_RECORDS, true);
|
||||
getPermissionService().setPermission(container, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||
getPermissionService().setPermission(container, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
|
||||
|
||||
// TODO set the admin users to have filing permissions on the unfiled container!!!
|
||||
// TODO we will need to be able to get a list of the admin roles from the service
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// just inherit eveything
|
||||
// TODO will change this when we are able to set permissions on holds and transfers!
|
||||
// getPermissionService().setInheritParentPermissions(container, true);
|
||||
// }
|
||||
|
||||
return container;
|
||||
}
|
||||
|
@@ -38,7 +38,6 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -107,109 +106,6 @@ public class FreezeServiceImpl extends ServiceBaseImpl
|
||||
return nodeService.hasAspect(nodeRef, ASPECT_FROZEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasFrozenChildren(final NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// check that we are dealing with a record folder
|
||||
if (isRecordFolder(nodeRef))
|
||||
{
|
||||
int heldCount = 0;
|
||||
|
||||
if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN))
|
||||
{
|
||||
heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService");
|
||||
|
||||
heldCount = AuthenticationUtil.runAsSystem(new RunAsWork<Integer>()
|
||||
{
|
||||
@Override
|
||||
public Integer doWork()
|
||||
{
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Integer>()
|
||||
{
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
int heldCount = 0;
|
||||
|
||||
// NOTE: this process remains to 'patch' older systems to improve performance next time around
|
||||
List<ChildAssociationRef> childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
if (childAssocs != null && !childAssocs.isEmpty())
|
||||
{
|
||||
for (ChildAssociationRef childAssociationRef : childAssocs)
|
||||
{
|
||||
NodeRef record = childAssociationRef.getChildRef();
|
||||
if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record))
|
||||
{
|
||||
heldCount ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add aspect and set count
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||
props.put(PROP_HELD_CHILDREN_COUNT, heldCount);
|
||||
getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props);
|
||||
|
||||
return heldCount;
|
||||
}
|
||||
},
|
||||
false, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// true if more than one child held
|
||||
result = (heldCount > 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public Date getFreezeDate(NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
if (isFrozen(nodeRef))
|
||||
{
|
||||
Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT);
|
||||
if (property != null) { return (Date) property; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public String getFreezeInitiator(NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
if (isFrozen(nodeRef))
|
||||
{
|
||||
Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY);
|
||||
if (property != null) { return (String) property; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated Method Implementations
|
||||
*/
|
||||
@@ -357,6 +253,112 @@ public class FreezeServiceImpl extends ServiceBaseImpl
|
||||
return new HashSet<NodeRef>(getHoldService().getHolds(filePlan));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasFrozenChildren(final NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// check that we are dealing with a record folder
|
||||
if (isRecordFolder(nodeRef))
|
||||
{
|
||||
int heldCount = 0;
|
||||
|
||||
if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN))
|
||||
{
|
||||
heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService");
|
||||
|
||||
heldCount = AuthenticationUtil.runAsSystem(new RunAsWork<Integer>()
|
||||
{
|
||||
@Override
|
||||
public Integer doWork()
|
||||
{
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Integer>()
|
||||
{
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
int heldCount = 0;
|
||||
|
||||
// NOTE: this process remains to 'patch' older systems to improve performance next time around
|
||||
List<ChildAssociationRef> childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, null);
|
||||
if (childAssocs != null && !childAssocs.isEmpty())
|
||||
{
|
||||
for (ChildAssociationRef childAssociationRef : childAssocs)
|
||||
{
|
||||
NodeRef record = childAssociationRef.getChildRef();
|
||||
if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record))
|
||||
{
|
||||
heldCount ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add aspect and set count
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||
props.put(PROP_HELD_CHILDREN_COUNT, heldCount);
|
||||
getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props);
|
||||
|
||||
return heldCount;
|
||||
}
|
||||
},
|
||||
false, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// true if more than one child held
|
||||
result = (heldCount > 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public Date getFreezeDate(NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
if (isFrozen(nodeRef))
|
||||
{
|
||||
Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT);
|
||||
if (property != null) { return (Date) property; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public String getFreezeInitiator(NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
if (isFrozen(nodeRef))
|
||||
{
|
||||
Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY);
|
||||
if (property != null) { return (String) property; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper Methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a hold using the given nodeRef and reason
|
||||
*
|
||||
|
@@ -262,7 +262,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
||||
// @since 2.2
|
||||
QName ASPECT_HELD_CHILDREN = QName.createQName(RM_URI, "heldChildren");
|
||||
QName PROP_HELD_CHILDREN_COUNT = QName.createQName(RM_URI, "heldChildrenCount");
|
||||
|
||||
|
||||
// Countable aspect
|
||||
QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable");
|
||||
QName PROP_COUNT = QName.createQName(RM_URI, "count");
|
||||
|
@@ -33,9 +33,7 @@ import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearch
|
||||
import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetailsCompatibility;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
@@ -44,6 +42,7 @@ import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.site.SiteService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.extensions.webscripts.Cache;
|
||||
@@ -199,20 +198,20 @@ public class RMSearchGet extends DeclarativeWebScript
|
||||
}
|
||||
|
||||
// Execute search
|
||||
List<NodeRef> results = recordsManagementSearchService.search(siteId, query, searchParameters);
|
||||
List<Pair<NodeRef, NodeRef>> results = recordsManagementSearchService.search(siteId, query, searchParameters);
|
||||
|
||||
// Reset person data cache
|
||||
personDataCache = new HashMap<String, String>(57);
|
||||
|
||||
// Process the result items
|
||||
List<Item> items = new ArrayList<Item>(results.size());
|
||||
for (NodeRef nodeRef : results)
|
||||
for (Pair<NodeRef, NodeRef> pair : results)
|
||||
{
|
||||
// FIXME: See RM-478
|
||||
// TC 3-3 Create User Groups
|
||||
try
|
||||
{
|
||||
Item item = new Item(nodeRef);
|
||||
Item item = new Item(pair.getFirst(), pair.getSecond());
|
||||
items.add(item);
|
||||
}
|
||||
catch(Exception e) {}
|
||||
@@ -245,7 +244,7 @@ public class RMSearchGet extends DeclarativeWebScript
|
||||
private Map<QName, Serializable> nodeProperties;
|
||||
private Map<String, Serializable> properties;
|
||||
|
||||
public Item(NodeRef nodeRef)
|
||||
public Item(NodeRef parent, NodeRef nodeRef)
|
||||
{
|
||||
// Set node ref
|
||||
this.nodeRef = nodeRef;
|
||||
@@ -265,12 +264,12 @@ public class RMSearchGet extends DeclarativeWebScript
|
||||
}
|
||||
|
||||
// Get parent node reference
|
||||
NodeRef parent = null;
|
||||
ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef);
|
||||
if (assoc != null)
|
||||
{
|
||||
parent = assoc.getParentRef();
|
||||
}
|
||||
// NodeRef parent = null;
|
||||
// ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef);
|
||||
// if (assoc != null)
|
||||
// {
|
||||
// parent = assoc.getParentRef();
|
||||
// }
|
||||
|
||||
if (isContainer)
|
||||
{
|
||||
@@ -334,16 +333,6 @@ public class RMSearchGet extends DeclarativeWebScript
|
||||
if (!NamespaceService.SYSTEM_MODEL_1_0_URI.equals(qName.getNamespaceURI()))
|
||||
{
|
||||
String prefixName = qName.getPrefixString().replace(":", "_");
|
||||
Serializable value = entry.getValue();
|
||||
if (value instanceof NodeRef)
|
||||
{
|
||||
value = value.toString();
|
||||
}
|
||||
else if (value instanceof ContentData)
|
||||
{
|
||||
ContentReader contentReader = contentService.getReader(nodeRef, qName);
|
||||
value = contentReader.getContentString();
|
||||
}
|
||||
properties.put(prefixName, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.search;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Records management search service.
|
||||
@@ -33,10 +34,10 @@ public interface RecordsManagementSearchService
|
||||
* Execute a records management search
|
||||
* @param siteId the id of the rm site to query
|
||||
* @param query search query string
|
||||
* @param searchParameters search parameters
|
||||
* @return {@link List}<{@link NodeRef}> search results
|
||||
* @param searchParameters search parameters
|
||||
* @return {@link List}<{@link Pair}<{@link NodeRef}, {@link NodeRef}> search results as pairs for parent and child nodes
|
||||
*/
|
||||
List<NodeRef> search(String siteId, String query, RecordsManagementSearchParameters searchParameters);
|
||||
List<Pair<NodeRef, NodeRef>> search(String siteId, String query, RecordsManagementSearchParameters searchParameters);
|
||||
|
||||
/**
|
||||
* Get all the searches saved on the given records management site.
|
||||
|
@@ -30,6 +30,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -41,6 +42,7 @@ import org.alfresco.service.cmr.site.SiteService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@@ -173,7 +175,7 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService#search(java.lang.String, java.lang.String, org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchParameters)
|
||||
*/
|
||||
@Override
|
||||
public List<NodeRef> search(String siteId, String query, RecordsManagementSearchParameters rmSearchParameters)
|
||||
public List<Pair<NodeRef, NodeRef>> search(String siteId, String query, RecordsManagementSearchParameters rmSearchParameters)
|
||||
{
|
||||
// build the full RM query
|
||||
StringBuilder fullQuery = new StringBuilder(1024);
|
||||
@@ -206,9 +208,16 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear
|
||||
|
||||
// execute query
|
||||
ResultSet resultSet = searchService.query(searchParameters);
|
||||
|
||||
// process results
|
||||
List<Pair<NodeRef, NodeRef>> result = new ArrayList<Pair<NodeRef, NodeRef>>(resultSet.length());
|
||||
for (ChildAssociationRef childAssoc : resultSet.getChildAssocRefs())
|
||||
{
|
||||
result.add(new Pair<NodeRef, NodeRef>(childAssoc.getParentRef(), childAssoc.getChildRef()));
|
||||
}
|
||||
|
||||
// return results
|
||||
return resultSet.getNodeRefs();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -18,8 +18,12 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.security;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.repo.security.permissions.PermissionReference;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
@@ -40,13 +44,45 @@ public class ExtendedReaderDynamicAuthority extends ExtendedSecurityBaseDynamicA
|
||||
public String getAuthority()
|
||||
{
|
||||
return EXTENDED_READER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor()
|
||||
*/
|
||||
@Override
|
||||
public Set<PermissionReference> requiredFor()
|
||||
{
|
||||
if (requiredFor == null)
|
||||
{
|
||||
requiredFor = Collections.singleton(getModelDAO().getPermissionReference(null, RMPermissionModel.READ_RECORDS));
|
||||
}
|
||||
|
||||
return requiredFor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getAuthorites(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
protected Set<String> getAuthorites(NodeRef nodeRef)
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Set<String> getAuthorites(NodeRef nodeRef)
|
||||
{
|
||||
return getExtendedSecurityService().getExtendedReaders(nodeRef);
|
||||
Set<String> result = null;
|
||||
|
||||
Map<String, Integer> readerMap = (Map<String, Integer>)getNodeService().getProperty(nodeRef, PROP_READERS);
|
||||
if (readerMap != null)
|
||||
{
|
||||
result = readerMap.keySet();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getTransactionCacheName()
|
||||
*/
|
||||
@Override
|
||||
protected String getTransactionCacheName()
|
||||
{
|
||||
return "rm.extendedreaderdynamicauthority";
|
||||
}
|
||||
}
|
||||
|
@@ -24,10 +24,12 @@ import java.util.Set;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.security.permissions.DynamicAuthority;
|
||||
import org.alfresco.repo.security.permissions.PermissionReference;
|
||||
import org.alfresco.repo.security.permissions.impl.ModelDAO;
|
||||
import org.alfresco.repo.transaction.TransactionalResourceHelper;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
@@ -41,9 +43,6 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut
|
||||
RecordsManagementModel,
|
||||
ApplicationContextAware
|
||||
{
|
||||
/** transaction cache key */
|
||||
private static final String KEY_HAS_AUTHORITY_CACHE = "rm.transaction.hasAuthority";
|
||||
|
||||
/** Authority service */
|
||||
private AuthorityService authorityService;
|
||||
|
||||
@@ -56,6 +55,12 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut
|
||||
/** Application context */
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
/** model DAO */
|
||||
protected ModelDAO modelDAO;
|
||||
|
||||
/** permission reference */
|
||||
protected Set<PermissionReference> requiredFor;
|
||||
|
||||
// NOTE: we get the services directly from the application context in this way to avoid
|
||||
// cyclic relationships and issues when loading the application context
|
||||
|
||||
@@ -95,6 +100,23 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return model DAO
|
||||
*/
|
||||
protected ModelDAO getModelDAO()
|
||||
{
|
||||
if (modelDAO == null)
|
||||
{
|
||||
modelDAO = (ModelDAO)applicationContext.getBean("permissionsModelDAO");
|
||||
}
|
||||
return modelDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String transaction cache name
|
||||
*/
|
||||
protected abstract String getTransactionCacheName();
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
@@ -121,63 +143,40 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY))
|
||||
Map<Pair<NodeRef, String>, Boolean> transactionCache = TransactionalResourceHelper.getMap(getTransactionCacheName());
|
||||
Pair<NodeRef, String> key = new Pair<NodeRef, String>(nodeRef, userName);
|
||||
|
||||
if (transactionCache.containsKey(key))
|
||||
{
|
||||
Set<String> authorities = getAuthorites(nodeRef);
|
||||
if (authorities != null)
|
||||
{
|
||||
for (String authority : authorities)
|
||||
{
|
||||
if ("GROUP_EVERYONE".equals(authority))
|
||||
{
|
||||
// 'eveyone' is there so break
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else if (authority.startsWith("GROUP_"))
|
||||
{
|
||||
Map<String, Boolean> transactionCache = TransactionalResourceHelper.getMap(KEY_HAS_AUTHORITY_CACHE);
|
||||
String key = authority + "|" + userName;
|
||||
if (transactionCache.containsKey(key))
|
||||
{
|
||||
result = transactionCache.get(key);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Set<String> contained = getAuthorityService().getAuthoritiesForUser(userName);
|
||||
if (contained.contains(authority))
|
||||
{
|
||||
result = true;
|
||||
transactionCache.put(key, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// presume we have a user
|
||||
if (authority.equals(userName))
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = transactionCache.get(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY) == true)
|
||||
{
|
||||
Set<String> authorities = getAuthorites(nodeRef);
|
||||
if (authorities != null)
|
||||
{
|
||||
// check for everyone or the user
|
||||
if (authorities.contains("GROUP_EVEYONE") ||
|
||||
authorities.contains(userName))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine whether any of the users groups are in the extended security
|
||||
Set<String> contained = getAuthorityService().getAuthoritiesForUser(userName);
|
||||
authorities.retainAll(contained);
|
||||
result = (authorities.size() != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache result
|
||||
transactionCache.put(key, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base implementation
|
||||
*
|
||||
* @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor()
|
||||
*/
|
||||
@Override
|
||||
public Set<PermissionReference> requiredFor()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -18,8 +18,13 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.security;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.repo.security.permissions.PermissionReference;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
@@ -41,12 +46,48 @@ public class ExtendedWriterDynamicAuthority extends ExtendedSecurityBaseDynamicA
|
||||
{
|
||||
return EXTENDED_WRITER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor()
|
||||
*/
|
||||
@Override
|
||||
public Set<PermissionReference> requiredFor()
|
||||
{
|
||||
if (requiredFor == null)
|
||||
{
|
||||
requiredFor = new HashSet<PermissionReference>(3);
|
||||
Collections.addAll(requiredFor,
|
||||
getModelDAO().getPermissionReference(null, RMPermissionModel.READ_RECORDS),
|
||||
getModelDAO().getPermissionReference(null, RMPermissionModel.FILING),
|
||||
getModelDAO().getPermissionReference(null, RMPermissionModel.FILE_RECORDS));
|
||||
}
|
||||
|
||||
return requiredFor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getAuthorites(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
protected Set<String> getAuthorites(NodeRef nodeRef)
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Set<String> getAuthorites(NodeRef nodeRef)
|
||||
{
|
||||
return getExtendedSecurityService().getExtendedWriters(nodeRef);
|
||||
}
|
||||
Set<String> result = null;
|
||||
|
||||
Map<String, Integer> map = (Map<String, Integer>)getNodeService().getProperty(nodeRef, PROP_WRITERS);
|
||||
if (map != null)
|
||||
{
|
||||
result = map.keySet();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getTransactionCacheName()
|
||||
*/
|
||||
@Override
|
||||
protected String getTransactionCacheName()
|
||||
{
|
||||
return "rm.extendedwriterdynamicauthority";
|
||||
}
|
||||
}
|
||||
|
@@ -18,22 +18,27 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.security;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority.EXTENDED_READER;
|
||||
import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority.EXTENDED_WRITER;
|
||||
import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.TRANSACTION_COMMIT;
|
||||
import static org.alfresco.repo.policy.annotation.BehaviourKind.CLASS;
|
||||
import static org.alfresco.repo.security.authentication.AuthenticationUtil.getSystemUserName;
|
||||
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
|
||||
import static org.alfresco.service.cmr.security.OwnableService.NO_OWNER;
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
import static org.apache.commons.lang.BooleanUtils.isTrue;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
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.fileplan.FilePlanComponentKind;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -42,7 +47,6 @@ import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.OwnableService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -59,30 +63,40 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
RMPermissionModel
|
||||
{
|
||||
/** Permission service */
|
||||
protected PermissionService permissionService;
|
||||
private PermissionService permissionService;
|
||||
|
||||
/** Ownable service */
|
||||
protected OwnableService ownableService;
|
||||
private OwnableService ownableService;
|
||||
|
||||
/** Policy component */
|
||||
protected PolicyComponent policyComponent;
|
||||
private PolicyComponent policyComponent;
|
||||
|
||||
/** Logger */
|
||||
protected static final Log LOGGER = LogFactory.getLog(FilePlanPermissionServiceImpl.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(FilePlanPermissionServiceImpl.class);
|
||||
|
||||
/**
|
||||
* Initialisation method
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
policyComponent.bindClassBehaviour(
|
||||
getPolicyComponent().bindClassBehaviour(
|
||||
NodeServicePolicies.OnAddAspectPolicy.QNAME,
|
||||
ASPECT_RECORD,
|
||||
new JavaBehaviour(this, "onAddRecord", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
policyComponent.bindClassBehaviour(
|
||||
new JavaBehaviour(this, "onAddRecord", TRANSACTION_COMMIT));
|
||||
getPolicyComponent().bindClassBehaviour(
|
||||
NodeServicePolicies.OnMoveNodePolicy.QNAME,
|
||||
ASPECT_RECORD,
|
||||
new JavaBehaviour(this, "onMoveRecord", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
new JavaBehaviour(this, "onMoveRecord", TRANSACTION_COMMIT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permission service
|
||||
*
|
||||
* @return The permission service
|
||||
*/
|
||||
protected PermissionService getPermissionService()
|
||||
{
|
||||
return this.permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,6 +107,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the policy component
|
||||
*
|
||||
* @return The policy component
|
||||
*/
|
||||
protected PolicyComponent getPolicyComponent()
|
||||
{
|
||||
return this.policyComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param policyComponent policy component
|
||||
*/
|
||||
@@ -101,6 +125,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
this.policyComponent = policyComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ownable service
|
||||
*
|
||||
* @return The ownable service
|
||||
*/
|
||||
protected OwnableService getOwnableService()
|
||||
{
|
||||
return this.ownableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ownableService ownable service
|
||||
*/
|
||||
@@ -115,7 +149,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
@Override
|
||||
public void setupRecordCategoryPermissions(final NodeRef recordCategory)
|
||||
{
|
||||
ParameterCheck.mandatory("recordCategory", recordCategory);
|
||||
mandatory("recordCategory", recordCategory);
|
||||
|
||||
// assert that we have a record category in our hands
|
||||
if (!instanceOf(recordCategory, TYPE_RECORD_CATEGORY))
|
||||
@@ -136,12 +170,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
@Behaviour
|
||||
(
|
||||
type = "rma:unfiledRecordFolder",
|
||||
kind = BehaviourKind.CLASS,
|
||||
kind = CLASS,
|
||||
policy = "alf:onCreateNode",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
notificationFrequency = TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateUnfiledRecordFolder(ChildAssociationRef childAssocRef)
|
||||
{
|
||||
mandatory("childAssocRef", childAssocRef);
|
||||
setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef());
|
||||
}
|
||||
|
||||
@@ -153,12 +188,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
@Behaviour
|
||||
(
|
||||
type = "rma:recordFolder",
|
||||
kind = BehaviourKind.CLASS,
|
||||
kind = CLASS,
|
||||
policy = "alf:onCreateNode",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
notificationFrequency = TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateRecordFolder(ChildAssociationRef childAssocRef)
|
||||
{
|
||||
mandatory("childAssocRef", childAssocRef);
|
||||
setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef());
|
||||
}
|
||||
|
||||
@@ -170,12 +206,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
@Behaviour
|
||||
(
|
||||
type = "rma:hold",
|
||||
kind = BehaviourKind.CLASS,
|
||||
kind = CLASS,
|
||||
policy = "alf:onCreateNode",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
notificationFrequency = TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateHold(final ChildAssociationRef childAssocRef)
|
||||
{
|
||||
mandatory("childAssocRef", childAssocRef);
|
||||
setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef());
|
||||
}
|
||||
|
||||
@@ -187,13 +224,14 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
@Behaviour
|
||||
(
|
||||
type = "rma:transfer",
|
||||
kind = BehaviourKind.CLASS,
|
||||
kind = CLASS,
|
||||
policy = "alf:onCreateNode",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
notificationFrequency = TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateTransfer(final ChildAssociationRef childAssocRef)
|
||||
{
|
||||
setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef(), false);
|
||||
mandatory("childAssocRef", childAssocRef);
|
||||
setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,92 +242,50 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void setupPermissions(final NodeRef parent, final NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("parent", parent);
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
setupPermissions(parent, nodeRef, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to setup permissions.
|
||||
*
|
||||
* @param parent parent node reference
|
||||
* @param nodeRef child node reference
|
||||
* @param includeInPlace true if in-place permissions should be included, false otherwise
|
||||
*/
|
||||
private void setupPermissions(final NodeRef parent, final NodeRef nodeRef, final boolean includeInPlace)
|
||||
{
|
||||
if (nodeService.exists(nodeRef))
|
||||
mandatory("parent", parent);
|
||||
mandatory("nodeRef", nodeRef);
|
||||
|
||||
if (nodeService.exists(nodeRef) && nodeService.exists(parent))
|
||||
{
|
||||
// initialise permissions
|
||||
initPermissions(nodeRef, includeInPlace);
|
||||
initPermissions(nodeRef, parent);
|
||||
|
||||
if (nodeService.exists(parent))
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
public Object doWork()
|
||||
{
|
||||
public Object doWork()
|
||||
// setup inherited permissions
|
||||
Set<AccessPermission> perms = getPermissionService().getAllSetPermissions(parent);
|
||||
for (AccessPermission perm : perms)
|
||||
{
|
||||
// setup inherited permissions
|
||||
Set<AccessPermission> perms = permissionService.getAllSetPermissions(parent);
|
||||
for (AccessPermission perm : perms)
|
||||
// don't copy the extended reader or writer permissions as they have already been set
|
||||
String authority = perm.getAuthority();
|
||||
if (!EXTENDED_READER.equals(authority) &&
|
||||
!EXTENDED_WRITER.equals(authority))
|
||||
{
|
||||
// only copy filling permissions if the parent is the file plan
|
||||
if (!inheritFillingOnly(parent, nodeRef) ||
|
||||
RMPermissionModel.FILING.equals(perm.getPermission()))
|
||||
// get the access status details
|
||||
AccessStatus accessStatus = perm.getAccessStatus();
|
||||
boolean allow = false;
|
||||
if (ALLOWED.equals(accessStatus))
|
||||
{
|
||||
// don't copy the extended reader or writer permissions as they have already been set
|
||||
if (!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) &&
|
||||
!ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(perm.getAuthority()))
|
||||
{
|
||||
// get the access status details
|
||||
AccessStatus accessStatus = perm.getAccessStatus();
|
||||
boolean allow = false;
|
||||
if (AccessStatus.ALLOWED.equals(accessStatus))
|
||||
{
|
||||
allow = true;
|
||||
}
|
||||
|
||||
// set the permission on the target node
|
||||
permissionService.setPermission(
|
||||
nodeRef,
|
||||
perm.getAuthority(),
|
||||
perm.getPermission(),
|
||||
allow);
|
||||
}
|
||||
allow = true;
|
||||
}
|
||||
|
||||
// set the permission on the target node
|
||||
getPermissionService().setPermission(
|
||||
nodeRef,
|
||||
authority,
|
||||
perm.getPermission(),
|
||||
allow);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to determine whether all or just filling permissions should be inherited.
|
||||
*
|
||||
* @param parent parent node
|
||||
* @param child child node
|
||||
* @return boolean true if inherit filling only, false otherwise
|
||||
*/
|
||||
private boolean inheritFillingOnly(NodeRef parent, NodeRef child)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
// if root category or
|
||||
// if in root of unfiled container or
|
||||
// if in root of hold container
|
||||
if ((isFilePlan(parent) && isRecordCategory(child)) ||
|
||||
FilePlanComponentKind.UNFILED_RECORD_CONTAINER.equals(getFilePlanComponentKind(parent)) ||
|
||||
FilePlanComponentKind.HOLD_CONTAINER.equals(getFilePlanComponentKind(parent)))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ups records permission when aspect is added.
|
||||
*
|
||||
@@ -300,6 +296,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void onAddRecord(final NodeRef record, final QName aspectTypeQName)
|
||||
{
|
||||
mandatory("childAssocRef", record);
|
||||
mandatory("childAssocRef", aspectTypeQName);
|
||||
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
@@ -323,27 +322,32 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void onMoveRecord(final ChildAssociationRef sourceAssocRef, final ChildAssociationRef destinationAssocRef)
|
||||
{
|
||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>()
|
||||
mandatory("sourceAssocRef", sourceAssocRef);
|
||||
mandatory("destinationAssocRef", destinationAssocRef);
|
||||
|
||||
runAs(new AuthenticationUtil.RunAsWork<Void>()
|
||||
{
|
||||
public Void doWork()
|
||||
{
|
||||
NodeRef record = sourceAssocRef.getChildRef();
|
||||
if (nodeService.exists(record) && nodeService.hasAspect(record, ASPECT_RECORD))
|
||||
{
|
||||
Set<AccessPermission> keepPerms = new HashSet<AccessPermission>(5);
|
||||
boolean inheritParentPermissions = permissionService.getInheritParentPermissions(record);
|
||||
|
||||
// record any permissions specifically set on the record (ie any filling or record_file permisions not on the parent)
|
||||
Set<AccessPermission> origionalParentPerms = permissionService.getAllSetPermissions(sourceAssocRef.getParentRef());
|
||||
Set<AccessPermission> keepPerms = new HashSet<AccessPermission>(5);
|
||||
Set<AccessPermission> origionalRecordPerms= permissionService.getAllSetPermissions(record);
|
||||
for (AccessPermission perm : origionalRecordPerms)
|
||||
|
||||
for (AccessPermission recordPermission : origionalRecordPerms)
|
||||
{
|
||||
if (!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) &&
|
||||
!ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(perm.getAuthority()) &&
|
||||
(perm.getPermission().equals(RMPermissionModel.FILING) || perm.getPermission().equals(RMPermissionModel.FILE_RECORDS)) &&
|
||||
!origionalParentPerms.contains(perm))
|
||||
String permission = recordPermission.getPermission();
|
||||
String authority = recordPermission.getAuthority();
|
||||
if ((RMPermissionModel.FILING.equals(permission) || RMPermissionModel.READ_RECORDS.equals(permission)) &&
|
||||
recordPermission.isSetDirectly() &&
|
||||
!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(authority) &&
|
||||
!ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(authority))
|
||||
{
|
||||
// then we can assume this is a permission we want to preserve
|
||||
keepPerms.add(perm);
|
||||
keepPerms.add(recordPermission);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,20 +362,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
setPermission(record, keeper.getAuthority(), keeper.getPermission());
|
||||
}
|
||||
|
||||
permissionService.setInheritParentPermissions(record, inheritParentPermissions);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}, getSystemUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the permissions for the given node.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param includeInPlace true if in-place
|
||||
*/
|
||||
private void initPermissions(final NodeRef nodeRef, final boolean includeInPlace)
|
||||
|
||||
private void initPermissions(final NodeRef nodeRef, final boolean isParentNodeFilePlan)
|
||||
{
|
||||
if (nodeService.exists(nodeRef))
|
||||
{
|
||||
@@ -379,21 +379,22 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
// break inheritance
|
||||
permissionService.setInheritParentPermissions(nodeRef, false);
|
||||
// set inheritance
|
||||
boolean inheritanceAllowed = isInheritanceAllowed(nodeRef, isParentNodeFilePlan);
|
||||
getPermissionService().setInheritParentPermissions(nodeRef, inheritanceAllowed);
|
||||
|
||||
// clear all existing permissions
|
||||
permissionService.clearPermission(nodeRef, null);
|
||||
getPermissionService().clearPermission(nodeRef, null);
|
||||
|
||||
if (includeInPlace)
|
||||
if (!inheritanceAllowed)
|
||||
{
|
||||
// set extended reader permissions
|
||||
permissionService.setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||
permissionService.setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
|
||||
getPermissionService().setPermission(nodeRef, EXTENDED_READER, READ_RECORDS, true);
|
||||
getPermissionService().setPermission(nodeRef, EXTENDED_WRITER, FILING, true);
|
||||
}
|
||||
|
||||
// remove owner
|
||||
ownableService.setOwner(nodeRef, OwnableService.NO_OWNER);
|
||||
getOwnableService().setOwner(nodeRef, NO_OWNER);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -401,6 +402,22 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the permissions for the given node.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param includeInPlace true if in-place
|
||||
*/
|
||||
private void initPermissions(final NodeRef nodeRef, final NodeRef parent)
|
||||
{
|
||||
initPermissions(nodeRef, (isRecordCategory(nodeRef) && isFilePlan(parent)));
|
||||
}
|
||||
|
||||
private boolean isInheritanceAllowed(NodeRef nodeRef, Boolean isParentNodeFilePlan)
|
||||
{
|
||||
return !(isFilePlan(nodeRef) || isTransfer(nodeRef) || isHold(nodeRef) || isUnfiledRecordsContainer(nodeRef) || (isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#setPermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String, boolean)
|
||||
*/
|
||||
@@ -414,21 +431,10 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
public Void doWork()
|
||||
{
|
||||
if (isFilePlan(nodeRef))
|
||||
if (canPerformPermissionAction(nodeRef))
|
||||
{
|
||||
// set the permission down the file plan hierarchy
|
||||
setPermissionDown(nodeRef, authority, permission);
|
||||
}
|
||||
else if (isFilePlanContainer(nodeRef) ||
|
||||
isRecordFolder(nodeRef) ||
|
||||
isRecord(nodeRef) ||
|
||||
isHold(nodeRef))
|
||||
{
|
||||
// set read permission to the parents of the node
|
||||
setReadPermissionUp(nodeRef, authority);
|
||||
|
||||
// set the permission on the node and it's children
|
||||
setPermissionDown(nodeRef, authority, permission);
|
||||
// Set the permission on the node
|
||||
getPermissionService().setPermission(nodeRef, authority, permission, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -443,146 +449,29 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the read permission up the hierarchy
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param authority authority
|
||||
*/
|
||||
private void setReadPermissionUp(NodeRef nodeRef, String authority)
|
||||
{
|
||||
NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef();
|
||||
if (parent != null && isFilePlanComponent(parent))
|
||||
{
|
||||
setReadPermissionUpImpl(parent, authority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method used to set the read permission up the hierarchy
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param authority authority
|
||||
*/
|
||||
private void setReadPermissionUpImpl(NodeRef nodeRef, String authority)
|
||||
{
|
||||
setPermissionImpl(nodeRef, authority, RMPermissionModel.READ_RECORDS);
|
||||
|
||||
NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef();
|
||||
if (parent != null && isFilePlanComponent(parent))
|
||||
{
|
||||
setReadPermissionUpImpl(parent, authority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// skip out node's that inherit (for example hold and transfer)
|
||||
if (!permissionService.getInheritParentPermissions(nodeRef))
|
||||
{
|
||||
// set permissions
|
||||
setPermissionImpl(nodeRef, authority, permission);
|
||||
|
||||
if (isFilePlanContainer(nodeRef) ||
|
||||
isRecordFolder(nodeRef))
|
||||
{
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||
for (ChildAssociationRef assoc : assocs)
|
||||
{
|
||||
NodeRef child = assoc.getChildRef();
|
||||
if (isFilePlanContainer(child) ||
|
||||
isRecordFolder(child) ||
|
||||
isRecord(child) ||
|
||||
isHold(child) ||
|
||||
instanceOf(child, TYPE_TRANSFER))
|
||||
{
|
||||
setPermissionDown(child, authority, permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permission, taking into account that filing is a superset of read
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param authority authority
|
||||
* @param permission permission
|
||||
*/
|
||||
private void setPermissionImpl(NodeRef nodeRef, String authority, String permission)
|
||||
{
|
||||
boolean hasRead = false;
|
||||
boolean hasFilling = false;
|
||||
|
||||
Set<AccessPermission> perms = permissionService.getAllSetPermissions(nodeRef);
|
||||
for (AccessPermission perm : perms)
|
||||
{
|
||||
if (perm.getAuthority().equals(authority))
|
||||
{
|
||||
if (perm.getPermission().equals(FILING))
|
||||
{
|
||||
hasFilling = true;
|
||||
}
|
||||
else if (perm.getPermission().equals(READ_RECORDS))
|
||||
{
|
||||
hasRead = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FILING.equals(permission) && hasRead)
|
||||
{
|
||||
// remove read permission
|
||||
permissionService.deletePermission(nodeRef, authority, RMPermissionModel.READ_RECORDS);
|
||||
hasRead = false;
|
||||
}
|
||||
|
||||
if (!hasRead && !hasFilling)
|
||||
{
|
||||
// add permission
|
||||
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)
|
||||
*/
|
||||
public void deletePermission(final NodeRef nodeRef, final String authority, final String permission)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
ParameterCheck.mandatory("authority", authority);
|
||||
ParameterCheck.mandatory("permission", permission);
|
||||
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Void doWork()
|
||||
{
|
||||
// can't delete permissions if inherited (eg hold and transfer containers)
|
||||
if (!permissionService.getInheritParentPermissions(nodeRef))
|
||||
if (canPerformPermissionAction(nodeRef))
|
||||
{
|
||||
// Delete permission on this node
|
||||
permissionService.deletePermission(nodeRef, authority, permission);
|
||||
|
||||
if (isFilePlanContainer(nodeRef) ||
|
||||
isRecordFolder(nodeRef))
|
||||
getPermissionService().deletePermission(nodeRef, authority, permission);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOGGER.isWarnEnabled())
|
||||
{
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||
for (ChildAssociationRef assoc : assocs)
|
||||
{
|
||||
NodeRef child = assoc.getChildRef();
|
||||
if (isFilePlanContainer(child) ||
|
||||
isRecordFolder(child) ||
|
||||
isRecord(child)||
|
||||
isHold(child) ||
|
||||
instanceOf(child, TYPE_TRANSFER))
|
||||
{
|
||||
deletePermission(child, authority, permission);
|
||||
}
|
||||
}
|
||||
LOGGER.warn("Deleting permissions for this node is not supported. (nodeRef=" + nodeRef + ", authority=" + authority + ", permission=" + permission + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,4 +479,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean canPerformPermissionAction(NodeRef nodeRef)
|
||||
{
|
||||
return isFilePlanContainer(nodeRef) || isRecordFolder(nodeRef) || isRecord(nodeRef);
|
||||
}
|
||||
}
|
||||
|
@@ -55,7 +55,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
|
||||
/** Application context */
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
|
||||
/** internal node service */
|
||||
private NodeService internalNodeService;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to get internal node service.
|
||||
* <p>
|
||||
@@ -95,10 +95,10 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
{
|
||||
internalNodeService = (NodeService)applicationContext.getBean("dbNodeService");
|
||||
}
|
||||
|
||||
|
||||
return internalNodeService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the file plan component kind from the given node reference
|
||||
*
|
||||
@@ -118,7 +118,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
if (isFilePlanComponent(nodeRef))
|
||||
{
|
||||
result = FilePlanComponentKind.FILE_PLAN_COMPONENT;
|
||||
|
||||
|
||||
if (isFilePlan(nodeRef))
|
||||
{
|
||||
result = FilePlanComponentKind.FILE_PLAN;
|
||||
@@ -164,7 +164,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
result = FilePlanComponentKind.UNFILED_RECORD_FOLDER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
map.put(nodeRef, result);
|
||||
@@ -310,7 +310,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
boolean isHold = false;
|
||||
if (getInternalNodeService().exists(nodeRef) &&
|
||||
if (getInternalNodeService().exists(nodeRef) &&
|
||||
instanceOf(nodeRef, TYPE_HOLD))
|
||||
{
|
||||
isHold = true;
|
||||
@@ -329,10 +329,23 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
|
||||
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.
|
||||
*
|
||||
*
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public boolean isDeclared(NodeRef record)
|
||||
@@ -352,22 +365,33 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
{
|
||||
NodeRef result = null;
|
||||
if (nodeRef != null)
|
||||
{
|
||||
result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF);
|
||||
if (result == null || !instanceOf(result, TYPE_FILE_PLAN))
|
||||
{
|
||||
Map<NodeRef, NodeRef> transactionCache = TransactionalResourceHelper.getMap("rm.servicebase.getFilePlan");
|
||||
if (transactionCache.containsKey(nodeRef))
|
||||
{
|
||||
if (instanceOf(nodeRef, TYPE_FILE_PLAN))
|
||||
result = transactionCache.get(nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF);
|
||||
if (result == null || !instanceOf(result, TYPE_FILE_PLAN))
|
||||
{
|
||||
result = nodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef);
|
||||
if (parentAssocRef != null)
|
||||
if (instanceOf(nodeRef, TYPE_FILE_PLAN))
|
||||
{
|
||||
result = getFilePlan(parentAssocRef.getParentRef());
|
||||
result = nodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef);
|
||||
if (parentAssocRef != null)
|
||||
{
|
||||
result = getFilePlan(parentAssocRef.getParentRef());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache result in transaction
|
||||
transactionCache.put(nodeRef, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,11 +407,11 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
protected boolean instanceOf(NodeRef nodeRef, QName ofClassName)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
ParameterCheck.mandatory("ofClassName", ofClassName);
|
||||
QName className = getInternalNodeService().getType(nodeRef);
|
||||
ParameterCheck.mandatory("ofClassName", ofClassName);
|
||||
QName className = getInternalNodeService().getType(nodeRef);
|
||||
return instanceOf(className, ofClassName);
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, Boolean> instanceOfCache = new HashMap<String, Boolean>();
|
||||
|
||||
/**
|
||||
@@ -401,25 +425,25 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
{
|
||||
ParameterCheck.mandatory("className", className);
|
||||
ParameterCheck.mandatory("ofClassName", ofClassName);
|
||||
|
||||
|
||||
boolean result = false;
|
||||
|
||||
|
||||
String key = className.toString() + "|" + ofClassName.toString();
|
||||
if (instanceOfCache.containsKey(key))
|
||||
{
|
||||
result = instanceOfCache.get(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (ofClassName.equals(className) ||
|
||||
dictionaryService.isSubClass(className, ofClassName))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
|
||||
instanceOfCache.put(key, result);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -18,18 +18,26 @@
|
||||
*/
|
||||
package org.alfresco.repo.security.permissions.impl;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
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.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.security.permissions.AccessControlEntry;
|
||||
import org.alfresco.repo.security.permissions.AccessControlList;
|
||||
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.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
@@ -48,6 +56,29 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl
|
||||
/** Writers simple cache */
|
||||
protected SimpleCache<Serializable, Set<String>> writersCache;
|
||||
|
||||
/** File plan service */
|
||||
private FilePlanService filePlanService;
|
||||
|
||||
/**
|
||||
* Gets the file plan service
|
||||
*
|
||||
* @return the filePlanService
|
||||
*/
|
||||
public FilePlanService getFilePlanService()
|
||||
{
|
||||
return this.filePlanService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file plan service
|
||||
*
|
||||
* @param filePlanService the filePlanService to set
|
||||
*/
|
||||
public void setFilePlanService(FilePlanService filePlanService)
|
||||
{
|
||||
this.filePlanService = filePlanService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.security.permissions.impl.PermissionServiceImpl#setAnyDenyDenies(boolean)
|
||||
*/
|
||||
@@ -87,15 +118,15 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl
|
||||
public AccessStatus hasPermission(NodeRef nodeRef, String perm)
|
||||
{
|
||||
AccessStatus acs = super.hasPermission(nodeRef, perm);
|
||||
if (AccessStatus.DENIED.equals(acs) &&
|
||||
PermissionService.READ.equals(perm) &&
|
||||
nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT))
|
||||
if (AccessStatus.DENIED.equals(acs) == true &&
|
||||
PermissionService.READ.equals(perm) == true &&
|
||||
nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) == true)
|
||||
{
|
||||
return super.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS);
|
||||
}
|
||||
else if (AccessStatus.DENIED.equals(acs) &&
|
||||
PermissionService.WRITE.equals(perm) &&
|
||||
nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT))
|
||||
else if (AccessStatus.DENIED.equals(acs) == true &&
|
||||
PermissionService.WRITE.equals(perm) == true &&
|
||||
nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) == true)
|
||||
{
|
||||
return super.hasPermission(nodeRef, RMPermissionModel.FILE_RECORDS);
|
||||
}
|
||||
@@ -263,4 +294,50 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl
|
||||
writersCache.put((Serializable)acl.getProperties(), aclWriters);
|
||||
return aclWriters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.security.permissions.impl.PermissionServiceImpl#setInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef, boolean)
|
||||
*/
|
||||
@Override
|
||||
public void setInheritParentPermissions(final NodeRef nodeRef, boolean inheritParentPermissions)
|
||||
{
|
||||
final String adminRole = getAdminRole(nodeRef);
|
||||
if (nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) && isNotBlank(adminRole))
|
||||
{
|
||||
if (inheritParentPermissions)
|
||||
{
|
||||
Set<AccessPermission> accessPermissions = getAllSetPermissions(nodeRef);
|
||||
for (AccessPermission accessPermission : accessPermissions)
|
||||
{
|
||||
String authority = accessPermission.getAuthority();
|
||||
String permission = accessPermission.getPermission();
|
||||
if (accessPermission.isSetDirectly() &&
|
||||
(RMPermissionModel.FILING.equals(permission) || RMPermissionModel.READ_RECORDS.equals(permission)) &&
|
||||
(ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(authority) || ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(authority)) || adminRole.equals(authority))
|
||||
{
|
||||
// FIXME!!!
|
||||
//deletePermission(nodeRef, authority, permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||
setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
|
||||
setPermission(nodeRef, adminRole, RMPermissionModel.FILING, true);
|
||||
}
|
||||
}
|
||||
super.setInheritParentPermissions(nodeRef, inheritParentPermissions);
|
||||
}
|
||||
|
||||
private String getAdminRole(NodeRef nodeRef)
|
||||
{
|
||||
String adminRole = null;
|
||||
NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef);
|
||||
if (filePlan != null)
|
||||
{
|
||||
adminRole = authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId());
|
||||
}
|
||||
return adminRole;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user