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:
Roy Wetherall
2014-06-25 04:14:18 +00:00
parent 8cfd2a8ee6
commit fefbb15eeb
14 changed files with 171 additions and 253 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -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

View File

@@ -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)" }
]; ];

View File

@@ -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
{ {

View File

@@ -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;
}
}
}

View File

@@ -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;
} }
}); });
} }
} }

View File

@@ -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

View File

@@ -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
* *

View File

@@ -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)");
} }
}; };

View File

@@ -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

View File

@@ -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;