mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM: Inplace filing prototype
* extension of seciruty service to allow management of extended readers * extended reader maintained within file plan hierarchy * support ready for removal (ie move) and overlapping of readers in hirearchy (maintained in reference counting map) * general rename to "Unfiled Records" rather than "New Records" * File plan unfiled records filter * Unit tests * Correct permissions on created unfiled container (file for admin as per file plan root) * record readers dynamic authority applied to file plan components on bootstrap and creation git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/INPLACE@42063 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
<!-- Create record action -->
|
<!-- Create record action -->
|
||||||
<bean id="create-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction">
|
<bean id="create-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction">
|
||||||
<property name="recordsManagementService" ref="RecordsManagementService"/>
|
<property name="recordsManagementService" ref="RecordsManagementService"/>
|
||||||
<property name="recordService" ref="RecordService" />
|
<property name="recordsManagementSecurityService" ref="RecordsManagementSecurityService" />
|
||||||
<property name="permissionService" ref="PermissionService" />
|
<property name="permissionService" ref="PermissionService" />
|
||||||
<property name="nodeService" ref="NodeService" />
|
<property name="nodeService" ref="NodeService" />
|
||||||
<property name="applicableTypes">
|
<property name="applicableTypes">
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
<bean id="rmCreate"
|
<bean id="rmCreate"
|
||||||
parent="rmBaseCapability"
|
parent="rmBaseCapability"
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.capability.impl.CreateCapability">
|
class="org.alfresco.module.org_alfresco_module_rm.capability.impl.CreateCapability">
|
||||||
|
<property name="recordService" ref="recordService"/>
|
||||||
<property name="name" value="Create"/>
|
<property name="name" value="Create"/>
|
||||||
<property name="private" value="true"/>
|
<property name="private" value="true"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -90,8 +90,8 @@
|
|||||||
|
|
||||||
</type>
|
</type>
|
||||||
|
|
||||||
<type name="rma:newRecordsContainer">
|
<type name="rma:unfiledRecordContainer">
|
||||||
<title>New Records Container</title>
|
<title>Unfiled Record Container</title>
|
||||||
<parent>rma:recordsManagementContainer</parent>
|
<parent>rma:recordsManagementContainer</parent>
|
||||||
</type>
|
</type>
|
||||||
|
|
||||||
@@ -624,14 +624,14 @@
|
|||||||
</target>
|
</target>
|
||||||
</child-association>
|
</child-association>
|
||||||
|
|
||||||
<child-association name="rma:newRecords">
|
<child-association name="rma:unfiledRecords">
|
||||||
<title>New Records</title>
|
<title>Unfiled Records</title>
|
||||||
<source>
|
<source>
|
||||||
<mandatory>true</mandatory>
|
<mandatory>true</mandatory>
|
||||||
<many>false</many>
|
<many>false</many>
|
||||||
</source>
|
</source>
|
||||||
<target>
|
<target>
|
||||||
<class>rma:newRecordsContainer</class>
|
<class>rma:unfiledRecordContainer</class>
|
||||||
<mandatory>true</mandatory>
|
<mandatory>true</mandatory>
|
||||||
<many>true</many>
|
<many>true</many>
|
||||||
</target>
|
</target>
|
||||||
@@ -844,13 +844,12 @@
|
|||||||
</mandatory-aspects>
|
</mandatory-aspects>
|
||||||
</aspect>
|
</aspect>
|
||||||
|
|
||||||
<!-- Details used for DM-RM security mapping -->
|
<!-- Extended readers for RM object -->
|
||||||
<!-- @since 2.1 -->
|
<!-- @since 2.1 -->
|
||||||
<aspect name="rma:extendedRecordSecurity">
|
<aspect name="rma:extendedReaders">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="rma:readers">
|
<property name="rma:readers">
|
||||||
<type>d:text</type>
|
<type>d:any</type>
|
||||||
<multiple>true</multiple>
|
|
||||||
</property>
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
</aspect>
|
</aspect>
|
||||||
|
@@ -46,12 +46,12 @@
|
|||||||
<list>
|
<list>
|
||||||
<ref bean="ownerDynamicAuthority" />
|
<ref bean="ownerDynamicAuthority" />
|
||||||
<ref bean="lockOwnerDynamicAuthority" />
|
<ref bean="lockOwnerDynamicAuthority" />
|
||||||
<ref bean="recordReadersDynamicAuthority" />
|
<ref bean="extendedReaderDynamicAuthority" />
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="recordReadersDynamicAuthority" class="org.alfresco.module.org_alfresco_module_rm.permission.RecordReadersDynamicAuthority" />
|
<bean id="extendedReaderDynamicAuthority" class="org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority" />
|
||||||
|
|
||||||
<!-- Bootstrap records management data -->
|
<!-- Bootstrap records management data -->
|
||||||
<bean id="org_alfresco_module_rm_bootstrapData"
|
<bean id="org_alfresco_module_rm_bootstrapData"
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
<property name="permissionService" ref="permissionService"/>
|
<property name="permissionService" ref="permissionService"/>
|
||||||
<property name="recordsManagementService" ref="recordsManagementService"/>
|
<property name="recordsManagementService" ref="recordsManagementService"/>
|
||||||
<property name="caveatConfigComponent" ref="caveatConfigComponent"/>
|
<property name="caveatConfigComponent" ref="caveatConfigComponent"/>
|
||||||
|
<!-- <property name="recordService" ref="recordService"/> -->
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- ====== -->
|
<!-- ====== -->
|
||||||
|
@@ -67,6 +67,7 @@
|
|||||||
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isFilePlanComponent=RM.Read.0
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isFilePlanComponent=RM.Read.0
|
||||||
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getFilePlanComponentKind=ACL_NODE.0.sys:base.ReadProperties, RM.Read.0
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getFilePlanComponentKind=ACL_NODE.0.sys:base.ReadProperties, RM.Read.0
|
||||||
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getFilePlanComponentKindFromType=RM_ALLOW
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getFilePlanComponentKindFromType=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordsManagementContainer=RM.Read.0
|
||||||
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isFilePlan=RM.Read.0
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isFilePlan=RM.Read.0
|
||||||
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordCategory=RM.Read.0
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordCategory=RM.Read.0
|
||||||
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordFolder=RM.Read.0
|
org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordFolder=RM.Read.0
|
||||||
@@ -480,7 +481,12 @@
|
|||||||
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.createRole=RM_ALLOW
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.createRole=RM_ALLOW
|
||||||
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.updateRole=RM_ALLOW
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.updateRole=RM_ALLOW
|
||||||
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.deleteRole=RM_ALLOW
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.deleteRole=RM_ALLOW
|
||||||
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.assignRoleToAuthority=RM_ALLOW
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.assignRoleToAuthority=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.getExtendedReaders=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.setExtendedReaders=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.removeExtendedReaders=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.removeAllExtendedReaders=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.*=RM_DENY
|
||||||
]]>
|
]]>
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
class="org.alfresco.module.org_alfresco_module_rm.jscript.app.JSONConversionComponent"
|
class="org.alfresco.module.org_alfresco_module_rm.jscript.app.JSONConversionComponent"
|
||||||
parent="baseJsonConversionComponent">
|
parent="baseJsonConversionComponent">
|
||||||
<property name="recordsManagementService" ref="RecordsManagementService"/>
|
<property name="recordsManagementService" ref="RecordsManagementService"/>
|
||||||
|
<property name="recordService" ref="RecordService"/>
|
||||||
<property name="capabilityService" ref="CapabilityService"/>
|
<property name="capabilityService" ref="CapabilityService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
abstract="true">
|
abstract="true">
|
||||||
<property name="jsonConversionComponent" ref="jsonConversionComponent"/>
|
<property name="jsonConversionComponent" ref="jsonConversionComponent"/>
|
||||||
<property name="recordsManagementService" ref="RecordsManagementService"/>
|
<property name="recordsManagementService" ref="RecordsManagementService"/>
|
||||||
|
<property name="recordService" ref="RecordService"/>
|
||||||
<property name="nodeService" ref="NodeService"/>
|
<property name="nodeService" ref="NodeService"/>
|
||||||
<property name="namespaceService" ref="NamespaceService"/>
|
<property name="namespaceService" ref="NamespaceService"/>
|
||||||
<property name="capabilityService" ref="CapabilityService"/>
|
<property name="capabilityService" ref="CapabilityService"/>
|
||||||
|
@@ -179,6 +179,13 @@ Filters.getFilterParams = function RecordsManagementFilter_getFilterParams(filte
|
|||||||
filterParams.query = "+PARENT:\"" + filterData + "\"";
|
filterParams.query = "+PARENT:\"" + filterData + "\"";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "unfiledRecords":
|
||||||
|
filterParams.variablePath = false;
|
||||||
|
filterQuery = "+PATH:\"" + parsedArgs.pathNode.qnamePath + "/rma:Unfiled_x0020_Records/*\"";
|
||||||
|
filterParams.query = filterQuery + filterQueryDefaults;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
filterParams.variablePath = false;
|
filterParams.variablePath = false;
|
||||||
|
@@ -120,7 +120,7 @@ function itemIsAllowed(item)
|
|||||||
var typeShort = String(item.typeShort);
|
var typeShort = String(item.typeShort);
|
||||||
|
|
||||||
// Don't show Hold and Transfer top-level containers
|
// Don't show Hold and Transfer top-level containers
|
||||||
if (typeShort == "rma:hold" || typeShort == "rma:transfer")
|
if (typeShort == "rma:hold" || typeShort == "rma:transfer" || typeShort == "rma:unfiledRecordContainer")
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -73,6 +73,14 @@ public interface RecordsManagementService
|
|||||||
*/
|
*/
|
||||||
FilePlanComponentKind getFilePlanComponentKindFromType(QName type);
|
FilePlanComponentKind getFilePlanComponentKindFromType(QName type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the given node is a records management container or not.
|
||||||
|
*
|
||||||
|
* @param nodeRef node reference
|
||||||
|
* @return boolean true if node is a record container, false otherwise.
|
||||||
|
*/
|
||||||
|
boolean isRecordsManagementContainer(NodeRef nodeRef);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the given node is file plan node or not.
|
* Indicates whether the given node is file plan node or not.
|
||||||
*
|
*
|
||||||
|
@@ -436,6 +436,15 @@ public class RecordsManagementServiceImpl implements RecordsManagementService,
|
|||||||
return instanceOf(nodeRef, TYPE_FILE_PLAN);
|
return instanceOf(nodeRef, TYPE_FILE_PLAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementService#isRecordsManagementContainer(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isRecordsManagementContainer(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
return instanceOf(nodeRef, TYPE_RECORDS_MANAGEMENT_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified.
|
* Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified.
|
||||||
*/
|
*/
|
||||||
|
@@ -18,19 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.action.dm;
|
package org.alfresco.module.org_alfresco_module_rm.action.dm;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
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.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.permission.RecordReadersDynamicAuthority;
|
import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
|
||||||
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
@@ -40,7 +35,6 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
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.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,8 +50,8 @@ public class CreateRecordAction extends ActionExecuterAbstractBase
|
|||||||
public static final String NAME = "create-record";
|
public static final String NAME = "create-record";
|
||||||
|
|
||||||
private RecordsManagementService recordsManagementService;
|
private RecordsManagementService recordsManagementService;
|
||||||
|
|
||||||
private RecordService recordService;
|
private RecordsManagementSecurityService recordsManagementSecurityService;
|
||||||
|
|
||||||
private PermissionService permissionService;
|
private PermissionService permissionService;
|
||||||
|
|
||||||
@@ -68,9 +62,9 @@ public class CreateRecordAction extends ActionExecuterAbstractBase
|
|||||||
this.recordsManagementService = recordsManagementService;
|
this.recordsManagementService = recordsManagementService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecordService(RecordService recordService)
|
public void setRecordsManagementSecurityService(RecordsManagementSecurityService recordsManagementSecurityService)
|
||||||
{
|
{
|
||||||
this.recordService = recordService;
|
this.recordsManagementSecurityService = recordsManagementSecurityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPermissionService(PermissionService permissionService)
|
public void setPermissionService(PermissionService permissionService)
|
||||||
@@ -111,29 +105,15 @@ public class CreateRecordAction extends ActionExecuterAbstractBase
|
|||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found.");
|
throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the document into the file plan
|
// move the document into the file plan
|
||||||
nodeService.moveNode(actionedUponNodeRef, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName());
|
nodeService.moveNode(actionedUponNodeRef, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName());
|
||||||
|
|
||||||
// maintain the original primary location
|
// maintain the original primary location
|
||||||
nodeService.addChild(parentAssoc.getParentRef(), actionedUponNodeRef, parentAssoc.getTypeQName(), parentAssoc.getQName());
|
nodeService.addChild(parentAssoc.getParentRef(), actionedUponNodeRef, parentAssoc.getTypeQName(), parentAssoc.getQName());
|
||||||
|
|
||||||
// add extended security information to the record
|
// set the readers
|
||||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
recordsManagementSecurityService.setExtendedReaders(actionedUponNodeRef, readers);
|
||||||
props.put(PROP_READERS, (Serializable)readers);
|
|
||||||
nodeService.addAspect(actionedUponNodeRef, ASPECT_EXTENDED_RECORD_SECURITY, props);
|
|
||||||
|
|
||||||
// add permission so readers can still 'see' the new record
|
|
||||||
// Note: using the regular permission service as we don't want to reflect this permission up (and down) the
|
|
||||||
// hierarchy
|
|
||||||
permissionService.setPermission(actionedUponNodeRef,
|
|
||||||
RecordReadersDynamicAuthority.RECORD_READERS,
|
|
||||||
RMPermissionModel.READ_RECORDS,
|
|
||||||
true);
|
|
||||||
permissionService.setPermission(filePlan,
|
|
||||||
RecordReadersDynamicAuthority.RECORD_READERS,
|
|
||||||
RMPermissionModel.VIEW_RECORDS,
|
|
||||||
true);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -141,13 +121,13 @@ public class CreateRecordAction extends ActionExecuterAbstractBase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Unable to file file plan.");
|
throw new AlfrescoRuntimeException("Unable to find file plan.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NodeRef getNewRecordContainer(NodeRef filePlan)
|
private NodeRef getNewRecordContainer(NodeRef filePlan)
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ASSOC_NEW_RECORDS, RegexQNamePattern.MATCH_ALL);
|
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ASSOC_UNFILED_RECORDS, RegexQNamePattern.MATCH_ALL);
|
||||||
if (assocs.size() != 1)
|
if (assocs.size() != 1)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Error getting the new record container, because the container cannot be indentified.");
|
throw new AlfrescoRuntimeException("Error getting the new record container, because the container cannot be indentified.");
|
||||||
|
@@ -61,6 +61,9 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RM After Invocation Provider
|
||||||
|
*/
|
||||||
public class RMAfterInvocationProvider extends RMSecurityCommon
|
public class RMAfterInvocationProvider extends RMSecurityCommon
|
||||||
implements AfterInvocationProvider, InitializingBean
|
implements AfterInvocationProvider, InitializingBean
|
||||||
{
|
{
|
||||||
|
@@ -31,6 +31,9 @@ import org.alfresco.service.cmr.security.AccessStatus;
|
|||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
@@ -42,10 +45,11 @@ public class RMSecurityCommon
|
|||||||
|
|
||||||
private static Log logger = LogFactory.getLog(RMSecurityCommon.class);
|
private static Log logger = LogFactory.getLog(RMSecurityCommon.class);
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
protected NodeService nodeService;
|
protected NodeService nodeService;
|
||||||
protected PermissionService permissionService;
|
protected PermissionService permissionService;
|
||||||
protected RecordsManagementService rmService;
|
protected RecordsManagementService rmService;
|
||||||
protected RecordService recordService;
|
|
||||||
protected RMCaveatConfigComponent caveatConfigComponent;
|
protected RMCaveatConfigComponent caveatConfigComponent;
|
||||||
|
|
||||||
public void setNodeService(NodeService nodeService)
|
public void setNodeService(NodeService nodeService)
|
||||||
@@ -63,11 +67,6 @@ public class RMSecurityCommon
|
|||||||
this.rmService = rmService;
|
this.rmService = rmService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecordService(RecordService recordService)
|
|
||||||
{
|
|
||||||
this.recordService = recordService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCaveatConfigComponent(RMCaveatConfigComponent caveatConfigComponent)
|
public void setCaveatConfigComponent(RMCaveatConfigComponent caveatConfigComponent)
|
||||||
{
|
{
|
||||||
this.caveatConfigComponent = caveatConfigComponent;
|
this.caveatConfigComponent = caveatConfigComponent;
|
||||||
|
@@ -26,6 +26,7 @@ import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
|||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
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.capability.declarative.DeclarativeCapability;
|
import org.alfresco.module.org_alfresco_module_rm.capability.declarative.DeclarativeCapability;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
@@ -37,6 +38,13 @@ import org.alfresco.service.namespace.QName;
|
|||||||
*/
|
*/
|
||||||
public class CreateCapability extends DeclarativeCapability
|
public class CreateCapability extends DeclarativeCapability
|
||||||
{
|
{
|
||||||
|
private RecordService recordService;
|
||||||
|
|
||||||
|
public void setRecordService(RecordService recordService)
|
||||||
|
{
|
||||||
|
this.recordService = recordService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.module.org_alfresco_module_rm.capability.Capability#evaluate(org.alfresco.service.cmr.repository.NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.capability.Capability#evaluate(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
|
@@ -57,8 +57,8 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
|||||||
// Records management root container
|
// Records management root container
|
||||||
public static final QName TYPE_FILE_PLAN = QName.createQName(RM_URI, "filePlan");
|
public static final QName TYPE_FILE_PLAN = QName.createQName(RM_URI, "filePlan");
|
||||||
|
|
||||||
// New records container
|
// Unfiled record container
|
||||||
public static final QName TYPE_NEW_RECORDS_CONTAINER = QName.createQName(RM_URI, "newRecordsContainer");
|
public static final QName TYPE_UNFILED_RECORD_CONTAINER = QName.createQName(RM_URI, "unfiledRecordContainer");
|
||||||
|
|
||||||
// Disposition instructions aspect
|
// Disposition instructions aspect
|
||||||
public static final QName ASPECT_SCHEDULED = QName.createQName(RM_URI, "scheduled");
|
public static final QName ASPECT_SCHEDULED = QName.createQName(RM_URI, "scheduled");
|
||||||
@@ -170,7 +170,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
|||||||
public static final QName ASPECT_RECORDS_MANAGEMENT_ROOT = QName.createQName(RM_URI, "recordsManagementRoot");
|
public static final QName ASPECT_RECORDS_MANAGEMENT_ROOT = QName.createQName(RM_URI, "recordsManagementRoot");
|
||||||
public static final QName ASSOC_HOLDS = QName.createQName(RM_URI, "holds");
|
public static final QName ASSOC_HOLDS = QName.createQName(RM_URI, "holds");
|
||||||
public static final QName ASSOC_TRANSFERS = QName.createQName(RM_URI, "transfers");
|
public static final QName ASSOC_TRANSFERS = QName.createQName(RM_URI, "transfers");
|
||||||
public static final QName ASSOC_NEW_RECORDS = QName.createQName(RM_URI, "newRecords");
|
public static final QName ASSOC_UNFILED_RECORDS = QName.createQName(RM_URI, "unfiledRecords");
|
||||||
|
|
||||||
// Hold type
|
// Hold type
|
||||||
public static final QName TYPE_HOLD = QName.createQName(RM_URI, "hold");
|
public static final QName TYPE_HOLD = QName.createQName(RM_URI, "hold");
|
||||||
@@ -224,7 +224,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
|||||||
public static final QName PROP_RS_DISPOITION_AUTHORITY = QName.createQName(RM_URI, "recordSearchDispositionAuthority");
|
public static final QName PROP_RS_DISPOITION_AUTHORITY = QName.createQName(RM_URI, "recordSearchDispositionAuthority");
|
||||||
public static final QName PROP_RS_HOLD_REASON = QName.createQName(RM_URI, "recordSearchHoldReason");
|
public static final QName PROP_RS_HOLD_REASON = QName.createQName(RM_URI, "recordSearchHoldReason");
|
||||||
|
|
||||||
// Extended record security aspect
|
// Extended readers aspect
|
||||||
public static final QName ASPECT_EXTENDED_RECORD_SECURITY = QName.createQName(RM_URI, "extendedRecordSecurity");
|
public static final QName ASPECT_EXTENDED_READERS = QName.createQName(RM_URI, "extendedReaders");
|
||||||
public static final QName PROP_READERS = QName.createQName(RM_URI, "readers");
|
public static final QName PROP_READERS = QName.createQName(RM_URI, "readers");
|
||||||
}
|
}
|
||||||
|
@@ -18,21 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
|
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.repo.node.NodeServicePolicies;
|
import org.alfresco.repo.node.NodeServicePolicies;
|
||||||
import org.alfresco.repo.policy.JavaBehaviour;
|
|
||||||
import org.alfresco.repo.policy.PolicyComponent;
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
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.NodeService;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behaviour associated with the file plan type
|
* Behaviour associated with the file plan type
|
||||||
@@ -82,10 +73,10 @@ public class FilePlanType implements RecordsManagementModel,
|
|||||||
*/
|
*/
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
policyComponent.bindClassBehaviour(
|
// policyComponent.bindClassBehaviour(
|
||||||
NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
// NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
||||||
TYPE_FILE_PLAN,
|
// TYPE_FILE_PLAN,
|
||||||
new JavaBehaviour(this, "onCreateNode", NotificationFrequency.TRANSACTION_COMMIT));
|
// new JavaBehaviour(this, "onCreateNode", NotificationFrequency.TRANSACTION_COMMIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,22 +85,6 @@ public class FilePlanType implements RecordsManagementModel,
|
|||||||
@Override
|
@Override
|
||||||
public void onCreateNode(ChildAssociationRef assoc)
|
public void onCreateNode(ChildAssociationRef assoc)
|
||||||
{
|
{
|
||||||
// grab the newly created file plan
|
// TODO refactor the file plan behaviours from the service code
|
||||||
NodeRef filePlan = assoc.getChildRef();
|
|
||||||
|
|
||||||
// create the properties map
|
|
||||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(1);
|
|
||||||
properties.put(ContentModel.PROP_NAME, NAME_NR_CONTAINER);
|
|
||||||
|
|
||||||
// create the 'new records' folder
|
|
||||||
NodeRef container = nodeService.createNode(
|
|
||||||
filePlan,
|
|
||||||
ASSOC_NEW_RECORDS,
|
|
||||||
QName.createQName(RM_URI, NAME_NR_CONTAINER),
|
|
||||||
TYPE_NEW_RECORDS_CONTAINER,
|
|
||||||
properties).getChildRef();
|
|
||||||
|
|
||||||
// set inheritance to false
|
|
||||||
permissionService.setInheritParentPermissions(container, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -56,6 +56,9 @@ public class RmSiteType implements RecordsManagementModel,
|
|||||||
/** Record Management Search Service */
|
/** Record Management Search Service */
|
||||||
private RecordsManagementSearchService recordsManagementSearchService;
|
private RecordsManagementSearchService recordsManagementSearchService;
|
||||||
|
|
||||||
|
/** Behaviour */
|
||||||
|
JavaBehaviour behaviour = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the policy component
|
* Set the policy component
|
||||||
* @param policyComponent policy component
|
* @param policyComponent policy component
|
||||||
@@ -99,7 +102,7 @@ public class RmSiteType implements RecordsManagementModel,
|
|||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
||||||
TYPE_RM_SITE,
|
TYPE_RM_SITE,
|
||||||
new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT));
|
behaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,33 +111,41 @@ public class RmSiteType implements RecordsManagementModel,
|
|||||||
@Override
|
@Override
|
||||||
public void onCreateNode(ChildAssociationRef childAssocRef)
|
public void onCreateNode(ChildAssociationRef childAssocRef)
|
||||||
{
|
{
|
||||||
final NodeRef rmSite = childAssocRef.getChildRef();
|
behaviour.disable();
|
||||||
|
try
|
||||||
// Do not execute behaviour if this has been created in the archive store
|
{
|
||||||
if(rmSite.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE) == true)
|
final NodeRef rmSite = childAssocRef.getChildRef();
|
||||||
{
|
|
||||||
// This is not the spaces store - probably the archive store
|
// Do not execute behaviour if this has been created in the archive store
|
||||||
return;
|
if(rmSite.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE) == true)
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeService.exists(rmSite) == true)
|
|
||||||
{
|
|
||||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
|
||||||
{
|
{
|
||||||
public Object doWork()
|
// This is not the spaces store - probably the archive store
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeService.exists(rmSite) == true)
|
||||||
|
{
|
||||||
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
SiteInfo siteInfo = siteService.getSite(rmSite);
|
public Object doWork()
|
||||||
if (siteInfo != null)
|
{
|
||||||
{
|
SiteInfo siteInfo = siteService.getSite(rmSite);
|
||||||
// Create the file plan component
|
if (siteInfo != null)
|
||||||
siteService.createContainer(siteInfo.getShortName(), COMPONENT_DOCUMENT_LIBRARY, TYPE_FILE_PLAN, null);
|
{
|
||||||
|
// Create the file plan component
|
||||||
// Add the reports
|
siteService.createContainer(siteInfo.getShortName(), COMPONENT_DOCUMENT_LIBRARY, TYPE_FILE_PLAN, null);
|
||||||
recordsManagementSearchService.addReports(siteInfo.getShortName());
|
|
||||||
}
|
// Add the reports
|
||||||
return null;
|
recordsManagementSearchService.addReports(siteInfo.getShortName());
|
||||||
}
|
}
|
||||||
}, AuthenticationUtil.getAdminUserName());
|
return null;
|
||||||
}
|
}
|
||||||
|
}, AuthenticationUtil.getAdminUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
behaviour.enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Record Service Interface.
|
||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
|
@@ -88,7 +88,7 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel
|
|||||||
{
|
{
|
||||||
policyComponent.bindAssociationBehaviour(
|
policyComponent.bindAssociationBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"),
|
||||||
TYPE_NEW_RECORDS_CONTAINER,
|
TYPE_UNFILED_RECORD_CONTAINER,
|
||||||
ContentModel.ASSOC_CONTAINS,
|
ContentModel.ASSOC_CONTAINS,
|
||||||
new JavaBehaviour(this, "onCreateNewRecord", NotificationFrequency.TRANSACTION_COMMIT));
|
new JavaBehaviour(this, "onCreateNewRecord", NotificationFrequency.TRANSACTION_COMMIT));
|
||||||
}
|
}
|
||||||
|
@@ -16,13 +16,10 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.permission;
|
package org.alfresco.module.org_alfresco_module_rm.security;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.FilePlanComponentKind;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.repo.security.permissions.DynamicAuthority;
|
import org.alfresco.repo.security.permissions.DynamicAuthority;
|
||||||
import org.alfresco.repo.security.permissions.PermissionReference;
|
import org.alfresco.repo.security.permissions.PermissionReference;
|
||||||
@@ -30,44 +27,42 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityService;
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityType;
|
import org.alfresco.service.cmr.security.AuthorityType;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Extended readers dynamic authority implementation.
|
||||||
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public class RecordReadersDynamicAuthority implements DynamicAuthority, RecordsManagementModel, ApplicationContextAware
|
public class ExtendedReaderDynamicAuthority implements DynamicAuthority,
|
||||||
|
RecordsManagementModel,
|
||||||
|
ApplicationContextAware
|
||||||
{
|
{
|
||||||
public static final String RECORD_READERS = "ROLE_RECORD_READERS";
|
/** Extended reader role */
|
||||||
|
public static final String EXTENDED_READER = "ROLE_EXTENDED_READER";
|
||||||
private RecordsManagementService recordsManagementService;
|
|
||||||
|
|
||||||
private NodeService nodeService;
|
|
||||||
|
|
||||||
|
/** Authority service */
|
||||||
private AuthorityService authorityService;
|
private AuthorityService authorityService;
|
||||||
|
|
||||||
|
/** Records management security service */
|
||||||
|
private RecordsManagementSecurityService recordsManagementSecurityService;
|
||||||
|
|
||||||
|
/** Node service */
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
/** Application context */
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
private RecordsManagementService getRecordsManagementService()
|
// NOTE: we get the services directly from the application context in this way to avoid
|
||||||
{
|
// cyclic relationships and issues when loading the application context
|
||||||
if (recordsManagementService == null)
|
|
||||||
{
|
|
||||||
recordsManagementService = (RecordsManagementService)applicationContext.getBean("recordsManagementService");
|
|
||||||
}
|
|
||||||
return recordsManagementService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NodeService getNodeService()
|
|
||||||
{
|
|
||||||
if (nodeService == null)
|
|
||||||
{
|
|
||||||
nodeService = (NodeService)applicationContext.getBean("nodeService");
|
|
||||||
}
|
|
||||||
return nodeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return authority service
|
||||||
|
*/
|
||||||
private AuthorityService getAuthorityService()
|
private AuthorityService getAuthorityService()
|
||||||
{
|
{
|
||||||
if (authorityService == null)
|
if (authorityService == null)
|
||||||
@@ -76,7 +71,34 @@ public class RecordReadersDynamicAuthority implements DynamicAuthority, RecordsM
|
|||||||
}
|
}
|
||||||
return authorityService;
|
return authorityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return records management security service
|
||||||
|
*/
|
||||||
|
public RecordsManagementSecurityService getRecordsManagementSecurityService()
|
||||||
|
{
|
||||||
|
if (recordsManagementSecurityService == null)
|
||||||
|
{
|
||||||
|
recordsManagementSecurityService = (RecordsManagementSecurityService)applicationContext.getBean("recordsManagementSecurityService");
|
||||||
|
}
|
||||||
|
return recordsManagementSecurityService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return node service
|
||||||
|
*/
|
||||||
|
public NodeService getNodeService()
|
||||||
|
{
|
||||||
|
if (nodeService == null)
|
||||||
|
{
|
||||||
|
nodeService = (NodeService)applicationContext.getBean("nodeService");
|
||||||
|
}
|
||||||
|
return nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||||
{
|
{
|
||||||
@@ -89,34 +111,37 @@ public class RecordReadersDynamicAuthority implements DynamicAuthority, RecordsM
|
|||||||
@Override
|
@Override
|
||||||
public String getAuthority()
|
public String getAuthority()
|
||||||
{
|
{
|
||||||
return RECORD_READERS;
|
return EXTENDED_READER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.repo.security.permissions.DynamicAuthority#hasAuthority(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
* @see org.alfresco.repo.security.permissions.DynamicAuthority#hasAuthority(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasAuthority(NodeRef nodeRef, String userName)
|
public boolean hasAuthority(NodeRef nodeRef, String userName)
|
||||||
{
|
{
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
|
||||||
FilePlanComponentKind kind = getRecordsManagementService().getFilePlanComponentKind(nodeRef);
|
if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_READERS) == true)
|
||||||
if (FilePlanComponentKind.RECORD.equals(kind) == true)
|
|
||||||
{
|
{
|
||||||
if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_RECORD_SECURITY) == true)
|
Set<String> readers = getRecordsManagementSecurityService().getExtendedReaders(nodeRef);
|
||||||
|
if (readers != null)
|
||||||
{
|
{
|
||||||
List<String> readers = (List<String>)nodeService.getProperty(nodeRef, PROP_READERS);
|
|
||||||
for (String reader : readers)
|
for (String reader : readers)
|
||||||
{
|
{
|
||||||
if (reader.startsWith("GROUP_") == true)
|
if ("GROUP_EVERYONE".equals(reader) == true)
|
||||||
{
|
{
|
||||||
|
// 'eveyone' has read
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (reader.startsWith("GROUP_") == true)
|
||||||
|
{
|
||||||
|
// check group to see if the user is contained
|
||||||
Set<String> contained = getAuthorityService().getContainedAuthorities(AuthorityType.USER, reader, false);
|
Set<String> contained = getAuthorityService().getContainedAuthorities(AuthorityType.USER, reader, false);
|
||||||
if (contained.isEmpty() == false &&
|
if (contained.isEmpty() == false &&
|
||||||
contained.contains(userName) == true)
|
contained.contains(userName) == true)
|
||||||
{
|
{
|
||||||
System.out.println("User " + userName + " is contained in the read group " + reader);
|
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -126,8 +151,6 @@ public class RecordReadersDynamicAuthority implements DynamicAuthority, RecordsM
|
|||||||
// presume we have a user
|
// presume we have a user
|
||||||
if (reader.equals(userName) == true)
|
if (reader.equals(userName) == true)
|
||||||
{
|
{
|
||||||
System.out.println("User " + userName + " matches read user " + reader);
|
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -135,10 +158,6 @@ public class RecordReadersDynamicAuthority implements DynamicAuthority, RecordsM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (FilePlanComponentKind.FILE_PLAN.equals(kind) == true)
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
@@ -152,4 +152,31 @@ public interface RecordsManagementSecurityService
|
|||||||
* @param permission permission
|
* @param permission permission
|
||||||
*/
|
*/
|
||||||
void deletePermission(NodeRef nodeRef, String authority, String permission);
|
void deletePermission(NodeRef nodeRef, String authority, String permission);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Set<String> getExtendedReaders(NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
* @param readers
|
||||||
|
*/
|
||||||
|
void setExtendedReaders(NodeRef nodeRef, Set<String> readers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
* @param readers
|
||||||
|
*/
|
||||||
|
void removeExtendedReaders(NodeRef nodeRef, Set<String> readers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
*/
|
||||||
|
void removeAllExtendedReaders(NodeRef nodeRef);
|
||||||
}
|
}
|
||||||
|
@@ -22,8 +22,11 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
@@ -56,6 +59,9 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Records management permission service implementation
|
* Records management permission service implementation
|
||||||
@@ -63,7 +69,8 @@ import org.json.JSONObject;
|
|||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
*/
|
*/
|
||||||
public class RecordsManagementSecurityServiceImpl implements RecordsManagementSecurityService,
|
public class RecordsManagementSecurityServiceImpl implements RecordsManagementSecurityService,
|
||||||
RecordsManagementModel
|
RecordsManagementModel,
|
||||||
|
ApplicationContextAware
|
||||||
|
|
||||||
{
|
{
|
||||||
/** Capability service */
|
/** Capability service */
|
||||||
@@ -90,9 +97,24 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
/** Records management role zone */
|
/** Records management role zone */
|
||||||
public static final String RM_ROLE_ZONE_PREFIX = "rmRoleZone";
|
public static final String RM_ROLE_ZONE_PREFIX = "rmRoleZone";
|
||||||
|
|
||||||
|
/** Unfiled record container name */
|
||||||
|
private static final String NAME_UNFILED_CONTAINER = "Unfiled Records";
|
||||||
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static Log logger = LogFactory.getLog(RecordsManagementSecurityServiceImpl.class);
|
private static Log logger = LogFactory.getLog(RecordsManagementSecurityServiceImpl.class);
|
||||||
|
|
||||||
|
/** Application context */
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||||
|
{
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the capability service
|
* Set the capability service
|
||||||
*
|
*
|
||||||
@@ -204,9 +226,9 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
|
|
||||||
if (nodeService.exists(rmRootNode) == true)
|
if (nodeService.exists(rmRootNode) == true)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
NodeRef unfiledContainer = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
|
||||||
{
|
{
|
||||||
public Object doWork()
|
public NodeRef doWork()
|
||||||
{
|
{
|
||||||
// Create "all" role group for root node
|
// Create "all" role group for root node
|
||||||
String allRoles = authorityService.createAuthority(AuthorityType.GROUP, getAllRolesGroupShortName(rmRootNode), "All Roles", null);
|
String allRoles = authorityService.createAuthority(AuthorityType.GROUP, getAllRolesGroupShortName(rmRootNode), "All Roles", null);
|
||||||
@@ -214,16 +236,47 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
// Set the permissions
|
// Set the permissions
|
||||||
permissionService.setInheritParentPermissions(rmRootNode, false);
|
permissionService.setInheritParentPermissions(rmRootNode, false);
|
||||||
permissionService.setPermission(rmRootNode, allRoles, RMPermissionModel.READ_RECORDS, true);
|
permissionService.setPermission(rmRootNode, allRoles, RMPermissionModel.READ_RECORDS, true);
|
||||||
|
permissionService.setPermission(rmRootNode, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||||
return null;
|
permissionService.setPermission(rmRootNode, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.VIEW_RECORDS, true);
|
||||||
|
|
||||||
|
// Create the unfiled record container
|
||||||
|
return createUnfiledContainer(rmRootNode, allRoles);
|
||||||
}
|
}
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
// Bootstrap in the default set of roles for the newly created root node
|
// Bootstrap in the default set of roles for the newly created root node
|
||||||
bootstrapDefaultRoles(rmRootNode);
|
bootstrapDefaultRoles(rmRootNode, unfiledContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates unfiled container node and sets up permissions
|
||||||
|
*
|
||||||
|
* @param rmRootNode
|
||||||
|
* @param allRoles
|
||||||
|
*/
|
||||||
|
private NodeRef createUnfiledContainer(NodeRef rmRootNode, String allRoles)
|
||||||
|
{
|
||||||
|
// create the properties map
|
||||||
|
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(1);
|
||||||
|
properties.put(ContentModel.PROP_NAME, NAME_UNFILED_CONTAINER);
|
||||||
|
|
||||||
|
// create the unfiled container
|
||||||
|
NodeRef container = nodeService.createNode(
|
||||||
|
rmRootNode,
|
||||||
|
ASSOC_UNFILED_RECORDS,
|
||||||
|
QName.createQName(RM_URI, NAME_UNFILED_CONTAINER),
|
||||||
|
TYPE_UNFILED_RECORD_CONTAINER,
|
||||||
|
properties).getChildRef();
|
||||||
|
|
||||||
|
// set inheritance to false
|
||||||
|
permissionService.setInheritParentPermissions(container, false);
|
||||||
|
permissionService.setPermission(container, allRoles, RMPermissionModel.READ_RECORDS, true);
|
||||||
|
permissionService.setPermission(container, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete root node behaviour
|
* Delete root node behaviour
|
||||||
*
|
*
|
||||||
@@ -293,17 +346,20 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
Set<AccessPermission> perms = permissionService.getAllSetPermissions(catNodeRef);
|
Set<AccessPermission> perms = permissionService.getAllSetPermissions(catNodeRef);
|
||||||
for (AccessPermission perm : perms)
|
for (AccessPermission perm : perms)
|
||||||
{
|
{
|
||||||
AccessStatus accessStatus = perm.getAccessStatus();
|
if (ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) == false)
|
||||||
boolean allow = false;
|
{
|
||||||
if (AccessStatus.ALLOWED.equals(accessStatus) == true)
|
AccessStatus accessStatus = perm.getAccessStatus();
|
||||||
{
|
boolean allow = false;
|
||||||
allow = true;
|
if (AccessStatus.ALLOWED.equals(accessStatus) == true)
|
||||||
}
|
{
|
||||||
permissionService.setPermission(
|
allow = true;
|
||||||
folderNodeRef,
|
}
|
||||||
perm.getAuthority(),
|
permissionService.setPermission(
|
||||||
perm.getPermission(),
|
folderNodeRef,
|
||||||
allow);
|
perm.getAuthority(),
|
||||||
|
perm.getPermission(),
|
||||||
|
allow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -324,8 +380,11 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
{
|
{
|
||||||
public Object doWork()
|
public Object doWork()
|
||||||
{
|
{
|
||||||
// Break inheritance
|
// break inheritance
|
||||||
permissionService.setInheritParentPermissions(nodeRef, false);
|
permissionService.setInheritParentPermissions(nodeRef, false);
|
||||||
|
|
||||||
|
// set extended reader permissions
|
||||||
|
permissionService.setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -352,7 +411,12 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
/**
|
/**
|
||||||
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#bootstrapDefaultRoles(org.alfresco.service.cmr.repository.NodeRef)
|
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#bootstrapDefaultRoles(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
public void bootstrapDefaultRoles(final NodeRef rmRootNode)
|
public void bootstrapDefaultRoles(NodeRef rmRootNode)
|
||||||
|
{
|
||||||
|
bootstrapDefaultRoles(rmRootNode, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bootstrapDefaultRoles(final NodeRef rmRootNode, final NodeRef unfiledContainer)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
@@ -434,7 +498,12 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
// Add any additional admin permissions
|
// Add any additional admin permissions
|
||||||
if (isAdmin == true)
|
if (isAdmin == true)
|
||||||
{
|
{
|
||||||
|
// Admin has filing
|
||||||
permissionService.setPermission(rmRootNode, role.getRoleGroupName(), RMPermissionModel.FILING, true);
|
permissionService.setPermission(rmRootNode, role.getRoleGroupName(), RMPermissionModel.FILING, true);
|
||||||
|
if (unfiledContainer != null)
|
||||||
|
{
|
||||||
|
permissionService.setPermission(unfiledContainer, role.getRoleGroupName(), RMPermissionModel.FILING, true);
|
||||||
|
}
|
||||||
|
|
||||||
// Add the creating user to the administration group
|
// Add the creating user to the administration group
|
||||||
String user = AuthenticationUtil.getFullyAuthenticatedUser();
|
String user = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||||
@@ -597,6 +666,12 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param rmRootNode
|
||||||
|
* @param roleAuthority
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private Set<String> getCapabilitiesImpl(NodeRef rmRootNode, String roleAuthority)
|
private Set<String> getCapabilitiesImpl(NodeRef rmRootNode, String roleAuthority)
|
||||||
{
|
{
|
||||||
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(rmRootNode);
|
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(rmRootNode);
|
||||||
@@ -636,7 +711,7 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
}, AuthenticationUtil.getSystemUserName()).booleanValue();
|
}, AuthenticationUtil.getSystemUserName()).booleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#hasRMAdminRole(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#hasRMAdminRole(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean hasRMAdminRole(NodeRef rmRootNode, String user)
|
public boolean hasRMAdminRole(NodeRef rmRootNode, String user)
|
||||||
@@ -791,7 +866,7 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
public Boolean doWork() throws Exception
|
public Boolean doWork() throws Exception
|
||||||
{
|
{
|
||||||
if (recordsManagementService.isFilePlan(nodeRef) == false &&
|
if (recordsManagementService.isFilePlan(nodeRef) == false &&
|
||||||
recordsManagementService.isRecordCategory(nodeRef) == true)
|
recordsManagementService.isRecordsManagementContainer(nodeRef) == true)
|
||||||
{
|
{
|
||||||
setReadPermissionUp(nodeRef, authority);
|
setReadPermissionUp(nodeRef, authority);
|
||||||
setPermissionDown(nodeRef, authority, permission);
|
setPermissionDown(nodeRef, authority, permission);
|
||||||
@@ -841,13 +916,13 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
private void setPermissionDown(NodeRef nodeRef, String authority, String permission)
|
private void setPermissionDown(NodeRef nodeRef, String authority, String permission)
|
||||||
{
|
{
|
||||||
setPermissionImpl(nodeRef, authority, permission);
|
setPermissionImpl(nodeRef, authority, permission);
|
||||||
if (recordsManagementService.isRecordCategory(nodeRef) == true)
|
if (recordsManagementService.isRecordsManagementContainer(nodeRef) == true)
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
for (ChildAssociationRef assoc : assocs)
|
for (ChildAssociationRef assoc : assocs)
|
||||||
{
|
{
|
||||||
NodeRef child = assoc.getChildRef();
|
NodeRef child = assoc.getChildRef();
|
||||||
if (recordsManagementService.isRecordCategory(child) == true ||
|
if (recordsManagementService.isRecordsManagementContainer(child) == true ||
|
||||||
recordsManagementService.isRecordFolder(child) == true)
|
recordsManagementService.isRecordFolder(child) == true)
|
||||||
{
|
{
|
||||||
setPermissionDown(child, authority, permission);
|
setPermissionDown(child, authority, permission);
|
||||||
@@ -886,13 +961,13 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
// Delete permission on this node
|
// Delete permission on this node
|
||||||
permissionService.deletePermission(nodeRef, authority, permission);
|
permissionService.deletePermission(nodeRef, authority, permission);
|
||||||
|
|
||||||
if (recordsManagementService.isRecordCategory(nodeRef) == true)
|
if (recordsManagementService.isRecordsManagementContainer(nodeRef) == true)
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
for (ChildAssociationRef assoc : assocs)
|
for (ChildAssociationRef assoc : assocs)
|
||||||
{
|
{
|
||||||
NodeRef child = assoc.getChildRef();
|
NodeRef child = assoc.getChildRef();
|
||||||
if (recordsManagementService.isRecordCategory(child) == true ||
|
if (recordsManagementService.isRecordsManagementContainer(child) == true ||
|
||||||
recordsManagementService.isRecordFolder(child) == true)
|
recordsManagementService.isRecordFolder(child) == true)
|
||||||
{
|
{
|
||||||
deletePermission(child, authority, permission);
|
deletePermission(child, authority, permission);
|
||||||
@@ -904,4 +979,95 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
|
|||||||
}
|
}
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Set<String> getExtendedReaders(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
NodeService nodeService = (NodeService)applicationContext.getBean("nodeService");
|
||||||
|
Set<String> result = null;
|
||||||
|
|
||||||
|
Map<String, Integer> readerMap = (Map<String, Integer>)nodeService.getProperty(nodeRef, PROP_READERS);
|
||||||
|
if (readerMap != null)
|
||||||
|
{
|
||||||
|
result = readerMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#setExtendedReaders(org.alfresco.service.cmr.repository.NodeRef, java.util.Set)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void setExtendedReaders(NodeRef nodeRef, Set<String> readers)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
|
ParameterCheck.mandatory("readers", readers);
|
||||||
|
|
||||||
|
NodeService nodeService = (NodeService)applicationContext.getBean("nodeService");
|
||||||
|
RecordsManagementService recordsManagementService = (RecordsManagementService)applicationContext.getBean("recordsManagementService");
|
||||||
|
|
||||||
|
if (nodeRef != null &&
|
||||||
|
readers.isEmpty() == false)
|
||||||
|
{
|
||||||
|
// add the aspect if missing
|
||||||
|
if (nodeService.hasAspect(nodeRef, ASPECT_EXTENDED_READERS) == false)
|
||||||
|
{
|
||||||
|
nodeService.addAspect(nodeRef, ASPECT_EXTENDED_READERS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get reader map
|
||||||
|
Map<String, Integer> readersMap = (Map<String, Integer>)nodeService.getProperty(nodeRef, PROP_READERS);
|
||||||
|
if (readersMap == null)
|
||||||
|
{
|
||||||
|
// create reader map
|
||||||
|
readersMap = new HashMap<String, Integer>(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String reader : readers)
|
||||||
|
{
|
||||||
|
if (readersMap.containsKey(reader) == true)
|
||||||
|
{
|
||||||
|
// increment reference count
|
||||||
|
Integer count = readersMap.get(reader);
|
||||||
|
readersMap.put(reader, Integer.valueOf(count.intValue()+1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add reader with initial count
|
||||||
|
readersMap.put(reader, Integer.valueOf(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the readers property (this will in turn apply the aspect if required)
|
||||||
|
nodeService.setProperty(nodeRef, PROP_READERS, (Serializable)readersMap);
|
||||||
|
|
||||||
|
// apply the extended readers up the file plan primary hierarchy
|
||||||
|
NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef();
|
||||||
|
if (parent != null &&
|
||||||
|
recordsManagementService.isFilePlanComponent(parent) == true)
|
||||||
|
{
|
||||||
|
setExtendedReaders(parent, readers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeExtendedReaders(NodeRef nodeRef, Set<String> readers)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#removeAllExtendedReaders(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeAllExtendedReaders(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,151 @@
|
|||||||
|
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.test.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records management security service test.
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
*/
|
||||||
|
public class NewRecordsManagementSecurityServiceImplTest extends BaseRMTestCase
|
||||||
|
{
|
||||||
|
private NodeRef record;
|
||||||
|
private NodeRef recordToo;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isUserTest()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTestDataImpl()
|
||||||
|
{
|
||||||
|
super.setupTestDataImpl();
|
||||||
|
|
||||||
|
record = utils.createRecord(rmFolder, "record.txt");
|
||||||
|
recordToo = utils.createRecord(rmFolder, "recordToo.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO testGetProtectedAspects
|
||||||
|
|
||||||
|
// TODO getProtectedProperties
|
||||||
|
|
||||||
|
// TODO bootstrapDefaultRoles
|
||||||
|
|
||||||
|
// TODO getRoles
|
||||||
|
|
||||||
|
// TODO getRolesByUser
|
||||||
|
|
||||||
|
// TODO getRole
|
||||||
|
|
||||||
|
// TODO existsRole
|
||||||
|
|
||||||
|
// TODO hasRMAdminRole
|
||||||
|
|
||||||
|
// TODO createRole
|
||||||
|
|
||||||
|
// TODO updateRole
|
||||||
|
|
||||||
|
// TODO deleteRole
|
||||||
|
|
||||||
|
// TODO assignRoleToAuthority
|
||||||
|
|
||||||
|
// TODO setPermission
|
||||||
|
|
||||||
|
// TODO deletePermission
|
||||||
|
|
||||||
|
public void testExtendedReaders()
|
||||||
|
{
|
||||||
|
doTestInTransaction(new Test<Void>()
|
||||||
|
{
|
||||||
|
public Void run()
|
||||||
|
{
|
||||||
|
assertFalse(hasExtendedReadersAspect(filePlan));
|
||||||
|
assertFalse(hasExtendedReadersAspect(rmContainer));
|
||||||
|
assertFalse(hasExtendedReadersAspect(rmFolder));
|
||||||
|
assertFalse(hasExtendedReadersAspect(record));
|
||||||
|
|
||||||
|
assertNull(securityService.getExtendedReaders(record));
|
||||||
|
|
||||||
|
Set<String> extendedReaders = new HashSet<String>(2);
|
||||||
|
extendedReaders.add("monkey");
|
||||||
|
extendedReaders.add("elephant");
|
||||||
|
|
||||||
|
securityService.setExtendedReaders(record, extendedReaders);
|
||||||
|
|
||||||
|
Map<String, Integer> testMap = new HashMap<String, Integer>(2);
|
||||||
|
testMap.put("monkey", Integer.valueOf(1));
|
||||||
|
testMap.put("elephant", Integer.valueOf(1));
|
||||||
|
|
||||||
|
test(filePlan, testMap);
|
||||||
|
test(rmContainer, testMap);
|
||||||
|
test(rmFolder, testMap);
|
||||||
|
test(record, testMap);
|
||||||
|
|
||||||
|
Set<String> extendedReadersToo = new HashSet<String>(2);
|
||||||
|
extendedReadersToo.add("monkey");
|
||||||
|
extendedReadersToo.add("snake");
|
||||||
|
|
||||||
|
securityService.setExtendedReaders(recordToo, extendedReadersToo);
|
||||||
|
|
||||||
|
Map<String, Integer> testMapToo = new HashMap<String, Integer>(2);
|
||||||
|
testMapToo.put("monkey", Integer.valueOf(1));
|
||||||
|
testMapToo.put("snake", Integer.valueOf(1));
|
||||||
|
|
||||||
|
Map<String, Integer> testMapThree = new HashMap<String, Integer>(3);
|
||||||
|
testMapThree.put("monkey", Integer.valueOf(2));
|
||||||
|
testMapThree.put("elephant", Integer.valueOf(1));
|
||||||
|
testMapThree.put("snake", Integer.valueOf(1));
|
||||||
|
|
||||||
|
test(filePlan, testMapThree);
|
||||||
|
test(rmContainer, testMapThree);
|
||||||
|
test(rmFolder, testMapThree);
|
||||||
|
test(recordToo, testMapToo);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasExtendedReadersAspect(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
return nodeService.hasAspect(nodeRef, ASPECT_EXTENDED_READERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test(NodeRef nodeRef, Map<String, Integer> testMap)
|
||||||
|
{
|
||||||
|
assertTrue(hasExtendedReadersAspect(nodeRef));
|
||||||
|
|
||||||
|
Map<String, Integer> readersMap = (Map<String,Integer>)nodeService.getProperty(nodeRef, PROP_READERS);
|
||||||
|
assertNotNull(readersMap);
|
||||||
|
assertEquals(testMap.size(), readersMap.size());
|
||||||
|
|
||||||
|
for (Map.Entry<String, Integer> entry: testMap.entrySet())
|
||||||
|
{
|
||||||
|
assertTrue(readersMap.containsKey(entry.getKey()));
|
||||||
|
assertEquals(entry.getValue(), readersMap.get(entry.getKey()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> readers = securityService.getExtendedReaders(nodeRef);
|
||||||
|
assertNotNull(readers);
|
||||||
|
assertEquals(testMap.size(), readers.size());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO getExtendedReaders
|
||||||
|
|
||||||
|
// TODO setExtendedReaders
|
||||||
|
|
||||||
|
// TODO removeExtendedReaders
|
||||||
|
|
||||||
|
// TODO removeAllExtendedReaders
|
||||||
|
}
|
@@ -20,8 +20,9 @@ package org.alfresco.module.org_alfresco_module_rm.test.service;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction;
|
import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
|
||||||
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.permission.RecordReadersDynamicAuthority;
|
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.site.SiteModel;
|
import org.alfresco.repo.site.SiteModel;
|
||||||
@@ -132,8 +133,6 @@ public class RecordServiceTestImpl extends BaseRMTestCase
|
|||||||
{
|
{
|
||||||
public Void run()
|
public Void run()
|
||||||
{
|
{
|
||||||
//assertFalse(rmService.isRecord(dmDocument));
|
|
||||||
|
|
||||||
assertEquals(AccessStatus.DENIED, dmPermissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS));
|
assertEquals(AccessStatus.DENIED, dmPermissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS));
|
||||||
assertEquals(AccessStatus.DENIED, dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS));
|
assertEquals(AccessStatus.DENIED, dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS));
|
||||||
|
|
||||||
@@ -149,6 +148,14 @@ public class RecordServiceTestImpl extends BaseRMTestCase
|
|||||||
assertEquals(AccessStatus.ALLOWED, dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS));
|
assertEquals(AccessStatus.ALLOWED, dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS));
|
||||||
|
|
||||||
assertTrue(rmService.isRecord(dmDocument));
|
assertTrue(rmService.isRecord(dmDocument));
|
||||||
|
|
||||||
|
//
|
||||||
|
Capability createCapability = capabilityService.getCapability("Create");
|
||||||
|
assertNotNull(createCapability);
|
||||||
|
createCapability.evaluate(dmDocument);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
dmUserName);
|
dmUserName);
|
||||||
|
@@ -56,7 +56,7 @@ import org.alfresco.util.GUID;
|
|||||||
import org.alfresco.util.PropertyMap;
|
import org.alfresco.util.PropertyMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event service implementation unit test
|
* Security service implementation unit test
|
||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
*/
|
*/
|
||||||
|
@@ -49,6 +49,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
|||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityService;
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.site.SiteInfo;
|
import org.alfresco.service.cmr.site.SiteInfo;
|
||||||
import org.alfresco.service.cmr.site.SiteService;
|
import org.alfresco.service.cmr.site.SiteService;
|
||||||
@@ -104,6 +105,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
protected PersonService personService;
|
protected PersonService personService;
|
||||||
protected TransactionService transactionService;
|
protected TransactionService transactionService;
|
||||||
protected FileFolderService fileFolderService;
|
protected FileFolderService fileFolderService;
|
||||||
|
protected PermissionService permissionService;
|
||||||
|
|
||||||
/** RM Services */
|
/** RM Services */
|
||||||
protected RecordsManagementService rmService;
|
protected RecordsManagementService rmService;
|
||||||
@@ -260,6 +262,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
personService = (PersonService)this.applicationContext.getBean("PersonService");
|
personService = (PersonService)this.applicationContext.getBean("PersonService");
|
||||||
transactionService = (TransactionService)applicationContext.getBean("TransactionService");
|
transactionService = (TransactionService)applicationContext.getBean("TransactionService");
|
||||||
fileFolderService = (FileFolderService)applicationContext.getBean("FileFolderService");
|
fileFolderService = (FileFolderService)applicationContext.getBean("FileFolderService");
|
||||||
|
permissionService = (PermissionService)applicationContext.getBean("PermissionService");
|
||||||
|
|
||||||
// Get RM services
|
// Get RM services
|
||||||
rmService = (RecordsManagementService)applicationContext.getBean("RecordsManagementService");
|
rmService = (RecordsManagementService)applicationContext.getBean("RecordsManagementService");
|
||||||
@@ -329,15 +332,6 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
setupTestDataImpl();
|
setupTestDataImpl();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that the new records container has been created for the file plan
|
|
||||||
public void test(Void arg0) throws Exception
|
|
||||||
{
|
|
||||||
// NodeRef newRecordsContainer = recordService.getNewRecordContainer(filePlan);
|
|
||||||
// assertNotNull(newRecordsContainer);
|
|
||||||
// assertEquals(TYPE_NEW_RECORDS_CONTAINER, nodeService.getType(newRecordsContainer));
|
|
||||||
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
AuthenticationUtil.getSystemUserName());
|
AuthenticationUtil.getSystemUserName());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user