mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-1460: Hold Reson is not displayed in Audit Log
RM-1505: Search Results: Hold Reason field is empty * specific filtering for ViewHoldReason capability removed .. no longer required as we specify user permissions at the hold level * deprecated hold related actions are no longer auditable (and so don't appear in the audit view) * hold service Audits add/remove to/from holds * hold reason is no longer rolled up onto disposable item .. it no longer makes sense for multiple holds and was a security hole * hold reason removed from search options git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@74611 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -178,6 +178,9 @@ addRecordTypes.description=Adds the selected type(s) to the record
|
|||||||
# File report
|
# File report
|
||||||
fileReport.title=File report
|
fileReport.title=File report
|
||||||
fileReport.description=File report
|
fileReport.description=File report
|
||||||
|
# Delete Hold
|
||||||
|
deleteHold.title=Delete Hold
|
||||||
|
deleteHold.description=Delete hold
|
||||||
|
|
||||||
# Action parameter constraints
|
# Action parameter constraints
|
||||||
rm-ac-is-kind-kinds.record_category=Record Category
|
rm-ac-is-kind-kinds.record_category=Record Category
|
||||||
|
@@ -1024,6 +1024,7 @@
|
|||||||
<type>d:text</type>
|
<type>d:text</type>
|
||||||
<protected>true</protected>
|
<protected>true</protected>
|
||||||
</property>
|
</property>
|
||||||
|
<!-- @deprecated as of 2.2, because disposable items now in multiple holds -->
|
||||||
<property name="rma:recordSearchHoldReason">
|
<property name="rma:recordSearchHoldReason">
|
||||||
<type>d:text</type>
|
<type>d:text</type>
|
||||||
<protected>true</protected>
|
<protected>true</protected>
|
||||||
|
@@ -413,102 +413,7 @@
|
|||||||
<property name="publicAction" value="true"/>
|
<property name="publicAction" value="true"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Freeze record -->
|
|
||||||
|
|
||||||
<bean id="freeze_proxy" parent="rmProxyAction" >
|
|
||||||
<property name="target">
|
|
||||||
<ref bean="freeze"/>
|
|
||||||
</property>
|
|
||||||
<property name="interceptorNames">
|
|
||||||
<list>
|
|
||||||
<idref bean="freeze_security"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="freeze_security" parent="actionSecurity">
|
|
||||||
<property name="objectDefinitionSource">
|
|
||||||
<value>
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.ExtendRetentionPeriodOrFreeze
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
|
|
||||||
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
|
|
||||||
</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="freeze" class="org.alfresco.module.org_alfresco_module_rm.action.impl.FreezeAction" parent="rmAction" depends-on="rmExtendRetentionPeriodOrFreezeCapability">
|
|
||||||
<property name="publicAction" value="false"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Unfreeze record -->
|
|
||||||
|
|
||||||
<bean id="unfreeze_proxy" parent="rmProxyAction" >
|
|
||||||
<property name="target">
|
|
||||||
<ref bean="unfreeze"/>
|
|
||||||
</property>
|
|
||||||
<property name="interceptorNames">
|
|
||||||
<list>
|
|
||||||
<idref bean="unfreeze_security"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="unfreeze_security" parent="actionSecurity">
|
|
||||||
<property name="objectDefinitionSource">
|
|
||||||
<value>
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.Unfreeze
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
|
|
||||||
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
|
|
||||||
</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="unfreeze" class="org.alfresco.module.org_alfresco_module_rm.action.impl.UnfreezeAction" parent="rmAction">
|
|
||||||
<property name="publicAction" value="false"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Relinquish Hold Action-->
|
|
||||||
|
|
||||||
<bean id="relinquishHold_proxy" parent="rmProxyAction" >
|
|
||||||
<property name="target">
|
|
||||||
<ref bean="relinquishHold"/>
|
|
||||||
</property>
|
|
||||||
<property name="interceptorNames">
|
|
||||||
<list>
|
|
||||||
<idref bean="unfreeze_security"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="relinquishHold" class="org.alfresco.module.org_alfresco_module_rm.action.impl.RelinquishHoldAction" parent="rmAction">
|
|
||||||
<property name="publicAction" value="false"/>
|
|
||||||
<property name="auditedImmediately" value="true"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Edit hold reason -->
|
|
||||||
|
|
||||||
<bean id="editHoldReason_proxy" parent="rmProxyAction" >
|
|
||||||
<property name="target">
|
|
||||||
<ref bean="editHoldReason"/>
|
|
||||||
</property>
|
|
||||||
<property name="interceptorNames">
|
|
||||||
<list>
|
|
||||||
<idref bean="editHoldReason_security"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="editHoldReason_security" parent="actionSecurity">
|
|
||||||
<property name="objectDefinitionSource">
|
|
||||||
<value>
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.ViewUpdateReasonsForFreeze
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
|
|
||||||
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
|
|
||||||
</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="editHoldReason" class="org.alfresco.module.org_alfresco_module_rm.action.impl.EditHoldReasonAction" parent="rmAction" />
|
|
||||||
|
|
||||||
<!-- Edit review as of date -->
|
<!-- Edit review as of date -->
|
||||||
|
|
||||||
@@ -1112,4 +1017,110 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- @deprecated actions as of 2.2 -->
|
||||||
|
<!-- actions can be reinstated by reconfiguring their publicity -->
|
||||||
|
|
||||||
|
<!-- Freeze record -->
|
||||||
|
|
||||||
|
<bean id="freeze_proxy" parent="rmProxyAction" >
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="freeze"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref bean="freeze_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="freeze_security" parent="actionSecurity">
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.ExtendRetentionPeriodOrFreeze
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
|
||||||
|
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="freeze" class="org.alfresco.module.org_alfresco_module_rm.action.impl.FreezeAction" parent="rmAction" depends-on="rmExtendRetentionPeriodOrFreezeCapability">
|
||||||
|
<property name="publicAction" value="false"/>
|
||||||
|
<property name="auditable" value="false"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- Unfreeze record -->
|
||||||
|
|
||||||
|
<bean id="unfreeze_proxy" parent="rmProxyAction" >
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="unfreeze"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref bean="unfreeze_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="unfreeze_security" parent="actionSecurity">
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.Unfreeze
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
|
||||||
|
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="unfreeze" class="org.alfresco.module.org_alfresco_module_rm.action.impl.UnfreezeAction" parent="rmAction">
|
||||||
|
<property name="publicAction" value="false"/>
|
||||||
|
<property name="auditable" value="false"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- Relinquish Hold Action-->
|
||||||
|
|
||||||
|
<bean id="relinquishHold_proxy" parent="rmProxyAction" >
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="relinquishHold"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref bean="unfreeze_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="relinquishHold" class="org.alfresco.module.org_alfresco_module_rm.action.impl.RelinquishHoldAction" parent="rmAction">
|
||||||
|
<property name="publicAction" value="false"/>
|
||||||
|
<property name="auditable" value="false"/>
|
||||||
|
<property name="auditedImmediately" value="true"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- Edit hold reason -->
|
||||||
|
|
||||||
|
<bean id="editHoldReason_proxy" parent="rmProxyAction" >
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="editHoldReason"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref bean="editHoldReason_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="editHoldReason_security" parent="actionSecurity">
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.ViewUpdateReasonsForFreeze
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
|
||||||
|
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="editHoldReason" class="org.alfresco.module.org_alfresco_module_rm.action.impl.EditHoldReasonAction" parent="rmAction">
|
||||||
|
<property name="publicAction" value="false"/>
|
||||||
|
<property name="auditable" value="false"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
@@ -1418,11 +1418,13 @@
|
|||||||
|
|
||||||
<bean id="holdService"
|
<bean id="holdService"
|
||||||
parent="baseService"
|
parent="baseService"
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImpl">
|
class="org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImpl"
|
||||||
|
init-method="init">
|
||||||
<property name="filePlanService" ref="FilePlanService" />
|
<property name="filePlanService" ref="FilePlanService" />
|
||||||
<property name="recordService" ref="RecordService" />
|
<property name="recordService" ref="RecordService" />
|
||||||
<property name="recordFolderService" ref="RecordFolderService" />
|
<property name="recordFolderService" ref="RecordFolderService" />
|
||||||
<property name="permissionService" ref="PermissionService"/>
|
<property name="permissionService" ref="PermissionService"/>
|
||||||
|
<property name="recordsManagementAuditService" ref="RecordsManagementAuditService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="HoldService"
|
<bean id="HoldService"
|
||||||
|
@@ -25,8 +25,8 @@ rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.deleteNode=RM.
|
|||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addChild=RM.Create.0.1.2
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addChild=RM.Create.0.1.2
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeChild=RM.Delete.0.1
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeChild=RM.Delete.0.1
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeChildAssociation=RM.Delete.0
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeChildAssociation=RM.Delete.0
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getProperties=RM.Read.0,AFTER_RM.FilterProperty
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getProperties=RM.Read.0
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getProperty=RM.Read.0,RM.ReadProperty.0.1
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getProperty=RM.Read.0
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setProperties=RM.UpdateProperties.0.1
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setProperties=RM.UpdateProperties.0.1
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addProperties=RM.UpdateProperties.0.1
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addProperties=RM.UpdateProperties.0.1
|
||||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setProperty=RM.UpdateProperties.0.1.2
|
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setProperty=RM.UpdateProperties.0.1.2
|
||||||
|
@@ -21,7 +21,6 @@ Filters.QUERY_TEMPLATES =
|
|||||||
{ field: "hasDispositionSchedule", template: "%(rma:recordSearchHasDispositionSchedule)" },
|
{ field: "hasDispositionSchedule", template: "%(rma:recordSearchHasDispositionSchedule)" },
|
||||||
{ field: "dispositionInstructions", template: "%(rma:recordSearchDispositionInstructions)" },
|
{ field: "dispositionInstructions", template: "%(rma:recordSearchDispositionInstructions)" },
|
||||||
{ field: "dispositionAuthority", template: "%(rma:recordSearchDispositionAuthority)" },
|
{ field: "dispositionAuthority", template: "%(rma:recordSearchDispositionAuthority)" },
|
||||||
{ field: "holdReason", template: "%(rma:recordSearchHoldReason)" },
|
|
||||||
{ field: "vitalRecordReviewPeriod", template: "%(rma:recordSearchVitalRecordReviewPeriod)" }
|
{ field: "vitalRecordReviewPeriod", template: "%(rma:recordSearchVitalRecordReviewPeriod)" }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -205,10 +205,6 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
|
|||||||
{
|
{
|
||||||
return decide(authentication, object, config, (Object[]) returnedObject);
|
return decide(authentication, object, config, (Object[]) returnedObject);
|
||||||
}
|
}
|
||||||
else if (Map.class.isAssignableFrom(returnedObject.getClass()))
|
|
||||||
{
|
|
||||||
return decide(authentication, object, config, (Map) returnedObject);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
@@ -922,39 +918,6 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
|
|||||||
return testNodeRef;
|
return testNodeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes" })
|
|
||||||
private Map decide(Authentication authentication, Object object, ConfigAttributeDefinition config, Map returnedObject)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (returnedObject.containsKey(RecordsManagementModel.PROP_HOLD_REASON))
|
|
||||||
{
|
|
||||||
HashMap filtered = new HashMap();
|
|
||||||
filtered.putAll(returnedObject);
|
|
||||||
// get the node ref from the properties or delete
|
|
||||||
String protocol = DefaultTypeConverter.INSTANCE.convert(String.class, filtered.get(ContentModel.PROP_STORE_PROTOCOL));
|
|
||||||
String identifier = DefaultTypeConverter.INSTANCE.convert(String.class, filtered.get(ContentModel.PROP_STORE_IDENTIFIER));
|
|
||||||
String uuid = DefaultTypeConverter.INSTANCE.convert(String.class, filtered.get(ContentModel.PROP_NODE_UUID));
|
|
||||||
StoreRef storeRef = new StoreRef(protocol, identifier);
|
|
||||||
NodeRef nodeRef = new NodeRef(storeRef, uuid);
|
|
||||||
if ((nodeRef == null) ||
|
|
||||||
(permissionService.hasPermission(getFilePlanService().getFilePlan(nodeRef), RMPermissionModel.VIEW_UPDATE_REASONS_FOR_FREEZE) != AccessStatus.ALLOWED))
|
|
||||||
{
|
|
||||||
filtered.remove(RecordsManagementModel.PROP_HOLD_REASON);
|
|
||||||
}
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return returnedObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(ClassCastException ex)
|
|
||||||
{
|
|
||||||
// This will happen if returnedObject is an instance of TreeMap containing anything other than instances of QName
|
|
||||||
return returnedObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ConfigAttributeDefintion
|
private class ConfigAttributeDefintion
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.capability.policy;
|
|
||||||
|
|
||||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
|
||||||
|
|
||||||
public class ReadPropertyPolicy extends AbstractBasePolicy
|
|
||||||
{
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
public int evaluate(
|
|
||||||
MethodInvocation invocation,
|
|
||||||
Class[] params,
|
|
||||||
ConfigAttributeDefinition cad)
|
|
||||||
{
|
|
||||||
NodeRef nodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent());
|
|
||||||
QName propertyQName = getQName(invocation, params, cad.getParameters().get(1));
|
|
||||||
if(propertyQName.equals(RecordsManagementModel.PROP_HOLD_REASON))
|
|
||||||
{
|
|
||||||
return getCapabilityService().getCapability(RMPermissionModel.VIEW_UPDATE_REASONS_FOR_FREEZE).evaluate(nodeRef);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -30,6 +30,8 @@ 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.audit.RecordsManagementAuditService;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
@@ -72,6 +74,10 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
|||||||
/** Logger */
|
/** Logger */
|
||||||
private static Log logger = LogFactory.getLog(HoldServiceImpl.class);
|
private static Log logger = LogFactory.getLog(HoldServiceImpl.class);
|
||||||
|
|
||||||
|
/** Audit event keys */
|
||||||
|
private static final String AUDIT_ADD_TO_HOLD = "addToHold";
|
||||||
|
private static final String AUDIT_REMOVE_FROM_HOLD = "removeFromHold";
|
||||||
|
|
||||||
/** File Plan Service */
|
/** File Plan Service */
|
||||||
private FilePlanService filePlanService;
|
private FilePlanService filePlanService;
|
||||||
|
|
||||||
@@ -84,6 +90,9 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
|||||||
/** Permission service */
|
/** Permission service */
|
||||||
private PermissionService permissionService;
|
private PermissionService permissionService;
|
||||||
|
|
||||||
|
/** records management audit service */
|
||||||
|
private RecordsManagementAuditService recordsManagementAuditService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the file plan service
|
* Set the file plan service
|
||||||
*
|
*
|
||||||
@@ -134,6 +143,31 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
|||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param recordsManagementAuditService records management audit service
|
||||||
|
*/
|
||||||
|
public void setRecordsManagementAuditService(RecordsManagementAuditService recordsManagementAuditService)
|
||||||
|
{
|
||||||
|
this.recordsManagementAuditService = recordsManagementAuditService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise hold service
|
||||||
|
*/
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
recordsManagementAuditService.registerAuditEvent(new AuditEvent(AUDIT_ADD_TO_HOLD, "capability.AddToHold.title"));
|
||||||
|
recordsManagementAuditService.registerAuditEvent(new AuditEvent(AUDIT_REMOVE_FROM_HOLD, "capability.RemoveFromHold.title"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behaviour unfreezes node's that will no longer he held after delete.
|
* Behaviour unfreezes node's that will no longer he held after delete.
|
||||||
*
|
*
|
||||||
@@ -556,6 +590,9 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
|||||||
// Link the record to the hold
|
// Link the record to the hold
|
||||||
nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
||||||
|
|
||||||
|
// audit item being added to the hold
|
||||||
|
recordsManagementAuditService.auditEvent(nodeRef, AUDIT_ADD_TO_HOLD);
|
||||||
|
|
||||||
// Mark all the folders contents as frozen
|
// Mark all the folders contents as frozen
|
||||||
if (isRecordFolder(nodeRef))
|
if (isRecordFolder(nodeRef))
|
||||||
{
|
{
|
||||||
@@ -657,6 +694,11 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
|||||||
{
|
{
|
||||||
// remove from hold
|
// remove from hold
|
||||||
nodeService.removeChild(hold, nodeRef);
|
nodeService.removeChild(hold, nodeRef);
|
||||||
|
|
||||||
|
// audit that the node has been remove from the hold
|
||||||
|
// TODO add details of the hold that the node was removed from
|
||||||
|
recordsManagementAuditService.auditEvent(nodeRef, AUDIT_REMOVE_FROM_HOLD);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -672,7 +714,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
|||||||
removeFreezeAspect(nodeRef, 0);
|
removeFreezeAspect(nodeRef, 0);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -233,6 +233,8 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
|||||||
QName PROP_RS_HAS_DISPOITION_SCHEDULE = QName.createQName(RM_URI, "recordSearchHasDispositionSchedule");
|
QName PROP_RS_HAS_DISPOITION_SCHEDULE = QName.createQName(RM_URI, "recordSearchHasDispositionSchedule");
|
||||||
QName PROP_RS_DISPOITION_INSTRUCTIONS = QName.createQName(RM_URI, "recordSearchDispositionInstructions");
|
QName PROP_RS_DISPOITION_INSTRUCTIONS = QName.createQName(RM_URI, "recordSearchDispositionInstructions");
|
||||||
QName PROP_RS_DISPOITION_AUTHORITY = QName.createQName(RM_URI, "recordSearchDispositionAuthority");
|
QName PROP_RS_DISPOITION_AUTHORITY = QName.createQName(RM_URI, "recordSearchDispositionAuthority");
|
||||||
|
/** @depreacted as of 2.2, because disposable items can now be in multiple holds */
|
||||||
|
@Deprecated
|
||||||
QName PROP_RS_HOLD_REASON = QName.createQName(RM_URI, "recordSearchHoldReason");
|
QName PROP_RS_HOLD_REASON = QName.createQName(RM_URI, "recordSearchHoldReason");
|
||||||
|
|
||||||
// Loaded Data Set Ids
|
// Loaded Data Set Ids
|
||||||
|
@@ -218,17 +218,6 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
|||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||||
ASPECT_VITAL_RECORD_DEFINITION,
|
ASPECT_VITAL_RECORD_DEFINITION,
|
||||||
new JavaBehaviour(this, "vitalRecordDefintionUpdateProperties", NotificationFrequency.TRANSACTION_COMMIT));
|
new JavaBehaviour(this, "vitalRecordDefintionUpdateProperties", NotificationFrequency.TRANSACTION_COMMIT));
|
||||||
|
|
||||||
// Hold reason rollup
|
|
||||||
this.policyComponent.bindClassBehaviour(
|
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
|
||||||
ASPECT_FROZEN,
|
|
||||||
new JavaBehaviour(this, "onRemoveFrozenAspect", NotificationFrequency.TRANSACTION_COMMIT));
|
|
||||||
|
|
||||||
this.policyComponent.bindClassBehaviour(
|
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
|
||||||
TYPE_HOLD,
|
|
||||||
new JavaBehaviour(this, "frozenAspectUpdateProperties", NotificationFrequency.TRANSACTION_COMMIT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -716,59 +705,6 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* On remove frozen aspect aspect behaviour implementation
|
|
||||||
*
|
|
||||||
* @param nodeRef node reference
|
|
||||||
* @param aspectTypeQName aspect type qname
|
|
||||||
*/
|
|
||||||
public void onRemoveFrozenAspect(NodeRef nodeRef, QName aspectTypeQName)
|
|
||||||
{
|
|
||||||
if (nodeService.exists(nodeRef) &&
|
|
||||||
nodeService.hasAspect(nodeRef, ASPECT_RM_SEARCH))
|
|
||||||
{
|
|
||||||
nodeService.setProperty(nodeRef, PROP_RS_HOLD_REASON, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frozen aspect properties update behavour implementation.
|
|
||||||
*
|
|
||||||
* @param nodeRef node reference
|
|
||||||
* @param before before properties
|
|
||||||
* @param after after proeprties
|
|
||||||
*/
|
|
||||||
public void frozenAspectUpdateProperties(final NodeRef nodeRef, final Map<QName, Serializable> before, final Map<QName, Serializable> after)
|
|
||||||
{
|
|
||||||
AuthenticationUtil.RunAsWork<Void> work = new AuthenticationUtil.RunAsWork<Void>()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public Void doWork()
|
|
||||||
{
|
|
||||||
if (nodeService.exists(nodeRef))
|
|
||||||
{
|
|
||||||
// get the changed hold reason
|
|
||||||
String holdReason = (String)nodeService.getProperty(nodeRef, PROP_HOLD_REASON);
|
|
||||||
|
|
||||||
// get all the frozen items the hold node has and change the hold reason
|
|
||||||
List<ChildAssociationRef> holdAssocs = nodeService.getChildAssocs(nodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
for (ChildAssociationRef assoc : holdAssocs)
|
|
||||||
{
|
|
||||||
NodeRef frozenItem = assoc.getChildRef();
|
|
||||||
|
|
||||||
// ensure the search aspect is applied and set the hold reason
|
|
||||||
applySearchAspect(frozenItem);
|
|
||||||
nodeService.setProperty(frozenItem, PROP_RS_HOLD_REASON, holdReason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AuthenticationUtil.runAs(work, AuthenticationUtil.getSystemUserName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the disposition schedule properties
|
* Updates the disposition schedule properties
|
||||||
*
|
*
|
||||||
|
@@ -68,7 +68,6 @@ public class RecordsManagementSearchParameters
|
|||||||
put("hasDispositionSchedule", "%(rma:recordSearchHasDispositionSchedule)");
|
put("hasDispositionSchedule", "%(rma:recordSearchHasDispositionSchedule)");
|
||||||
put("dispositionInstructions", "%(rma:recordSearchDispositionInstructions)");
|
put("dispositionInstructions", "%(rma:recordSearchDispositionInstructions)");
|
||||||
put("dispositionAuthority", "%(rma:recordSearchDispositionAuthority)");
|
put("dispositionAuthority", "%(rma:recordSearchDispositionAuthority)");
|
||||||
put("holdReason", "%(rma:recordSearchHoldReason)");
|
|
||||||
put("vitalRecordReviewPeriod", "%(rma:recordSearchVitalRecordReviewPeriod)");
|
put("vitalRecordReviewPeriod", "%(rma:recordSearchVitalRecordReviewPeriod)");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -288,11 +288,13 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService).addChild(hold, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
verify(mockedNodeService).addChild(hold, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
||||||
verify(mockedNodeService).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
verify(mockedNodeService).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
|
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(recordFolder), anyString());
|
||||||
|
|
||||||
holdService.addToHold(hold, record);
|
holdService.addToHold(hold, record);
|
||||||
verify(mockedNodeService).addChild(hold, record, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
verify(mockedNodeService).addChild(hold, record, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
||||||
verify(mockedNodeService).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
verify(mockedNodeService, times(2)).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, times(2)).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
|
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(record), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -306,6 +308,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService, never()).addChild(hold, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
verify(mockedNodeService, never()).addChild(hold, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
||||||
verify(mockedNodeService, never()).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, never()).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
verify(mockedNodeService, never()).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, never()).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
|
verify(mockedRecordsManagementAuditService, never()).auditEvent(eq(recordFolder), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -320,6 +323,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService, times(1)).addChild(hold, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
verify(mockedNodeService, times(1)).addChild(hold, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
||||||
verify(mockedNodeService, never()).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, never()).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
verify(mockedNodeService, never()).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, never()).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
|
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(recordFolder), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -351,6 +355,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService, times(1)).addChild(hold2, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
verify(mockedNodeService, times(1)).addChild(hold2, recordFolder, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
|
||||||
verify(mockedNodeService, times(1)).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, times(1)).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
verify(mockedNodeService, times(1)).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
verify(mockedNodeService, times(1)).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class));
|
||||||
|
verify(mockedRecordsManagementAuditService, times(2)).auditEvent(eq(recordFolder), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test (expected=AlfrescoRuntimeException.class)
|
@Test (expected=AlfrescoRuntimeException.class)
|
||||||
@@ -367,6 +372,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService, never()).removeChild(hold, recordFolder);
|
verify(mockedNodeService, never()).removeChild(hold, recordFolder);
|
||||||
verify(mockedNodeService, never()).removeAspect(recordFolder, ASPECT_FROZEN);
|
verify(mockedNodeService, never()).removeAspect(recordFolder, ASPECT_FROZEN);
|
||||||
verify(mockedNodeService, never()).removeAspect(record, ASPECT_FROZEN);
|
verify(mockedNodeService, never()).removeAspect(record, ASPECT_FROZEN);
|
||||||
|
verify(mockedRecordsManagementAuditService, never()).auditEvent(eq(recordFolder), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -381,6 +387,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService, times(1)).removeChild(hold, recordFolder);
|
verify(mockedNodeService, times(1)).removeChild(hold, recordFolder);
|
||||||
verify(mockedNodeService, times(1)).removeAspect(recordFolder, ASPECT_FROZEN);
|
verify(mockedNodeService, times(1)).removeAspect(recordFolder, ASPECT_FROZEN);
|
||||||
verify(mockedNodeService, times(1)).removeAspect(record, ASPECT_FROZEN);
|
verify(mockedNodeService, times(1)).removeAspect(record, ASPECT_FROZEN);
|
||||||
|
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(recordFolder), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -402,6 +409,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
verify(mockedNodeService, times(1)).removeChild(hold2, recordFolder);
|
verify(mockedNodeService, times(1)).removeChild(hold2, recordFolder);
|
||||||
verify(mockedNodeService, times(1)).removeAspect(recordFolder, ASPECT_FROZEN);
|
verify(mockedNodeService, times(1)).removeAspect(recordFolder, ASPECT_FROZEN);
|
||||||
verify(mockedNodeService, times(1)).removeAspect(record, ASPECT_FROZEN);
|
verify(mockedNodeService, times(1)).removeAspect(record, ASPECT_FROZEN);
|
||||||
|
verify(mockedRecordsManagementAuditService, times(2)).auditEvent(any(NodeRef.class), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -31,6 +31,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
|
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
|
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
|
import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
|
||||||
@@ -103,6 +104,7 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
@Mock(name="recordsManagementActionService") protected RecordsManagementActionService mockedRecordsManagementActionService;
|
@Mock(name="recordsManagementActionService") protected RecordsManagementActionService mockedRecordsManagementActionService;
|
||||||
@Mock(name="reportService") protected ReportService mockedReportService;
|
@Mock(name="reportService") protected ReportService mockedReportService;
|
||||||
@Mock(name="filePlanRoleService") protected FilePlanRoleService mockedFilePlanRoleService;
|
@Mock(name="filePlanRoleService") protected FilePlanRoleService mockedFilePlanRoleService;
|
||||||
|
@Mock(name="recordsManagementAuditService") protected RecordsManagementAuditService mockedRecordsManagementAuditService;
|
||||||
|
|
||||||
/** application context mock */
|
/** application context mock */
|
||||||
@Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
|
@Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
|
||||||
|
Reference in New Issue
Block a user