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:
@@ -205,10 +205,6 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
|
||||
{
|
||||
return decide(authentication, object, config, (Object[]) returnedObject);
|
||||
}
|
||||
else if (Map.class.isAssignableFrom(returnedObject.getClass()))
|
||||
{
|
||||
return decide(authentication, object, config, (Map) returnedObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
@@ -922,39 +918,6 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
|
||||
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
|
||||
{
|
||||
|
||||
|
@@ -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.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.fileplan.FilePlanService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
@@ -71,6 +73,10 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
/** Logger */
|
||||
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 */
|
||||
private FilePlanService filePlanService;
|
||||
@@ -83,6 +89,9 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
|
||||
/** Permission service */
|
||||
private PermissionService permissionService;
|
||||
|
||||
/** records management audit service */
|
||||
private RecordsManagementAuditService recordsManagementAuditService;
|
||||
|
||||
/**
|
||||
* Set the file plan service
|
||||
@@ -133,6 +142,31 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
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.
|
||||
@@ -555,6 +589,9 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
|
||||
// Link the record to the hold
|
||||
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
|
||||
if (isRecordFolder(nodeRef))
|
||||
@@ -657,6 +694,11 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
// remove from hold
|
||||
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;
|
||||
}
|
||||
});
|
||||
@@ -672,7 +714,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
removeFreezeAspect(nodeRef, 0);
|
||||
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_DISPOITION_INSTRUCTIONS = QName.createQName(RM_URI, "recordSearchDispositionInstructions");
|
||||
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");
|
||||
|
||||
// Loaded Data Set Ids
|
||||
|
@@ -218,17 +218,6 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ASPECT_VITAL_RECORD_DEFINITION,
|
||||
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
|
||||
*
|
||||
|
@@ -68,7 +68,6 @@ public class RecordsManagementSearchParameters
|
||||
put("hasDispositionSchedule", "%(rma:recordSearchHasDispositionSchedule)");
|
||||
put("dispositionInstructions", "%(rma:recordSearchDispositionInstructions)");
|
||||
put("dispositionAuthority", "%(rma:recordSearchDispositionAuthority)");
|
||||
put("holdReason", "%(rma:recordSearchHoldReason)");
|
||||
put("vitalRecordReviewPeriod", "%(rma:recordSearchVitalRecordReviewPeriod)");
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user