RM-853: File Record audit event is absent

* refactored audit events to be spring configurable, registerable beans
  * adjusted how actions are audited
  * added missing action I18N labels
  * adjusted how audit events are stored against the transaction so that more than one is recorded per transaction (previously it was the last event to happen that was recorded)
  * unit test running and share tested



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@54678 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2013-08-30 00:54:23 +00:00
parent 811fe439eb
commit eaadaa0faa
31 changed files with 861 additions and 429 deletions

View File

@@ -13,5 +13,9 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info
# RM Permission Debug Information # RM Permission Debug Information
# #
#log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter=debug
#log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMAfterInvocationProvider=debug
#log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.declarative=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.declarative=debug
#log4j.logger.org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl=debug
#log4j.logger.org.springframework.extensions.webscripts.ScriptDebugger=on
log4j.logger.org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService=debug

View File

@@ -133,6 +133,31 @@ createDispositionSchedule.description=Create disposition schedule
# File Destruction Report # File Destruction Report
fileDestructionReport.title=File destruction report fileDestructionReport.title=File destruction report
fileDestructionReport.description=File destruction report fileDestructionReport.description=File destruction report
# Cut off
cutoff.title=Cut off
cutoff.description=Cut off
# Destroy
destroy.title=Destroy
destroy.description=Destroy
# Reviewed
reviewed.title=Reviewed
reviewed.description=Reviewed
# Hide Record
hide-record.title=Hide record
hide-record.description=Hide record
# Transfer
transfer.title=Transfer
transfer.description=Transfer
# Uncut off
unCutoff.title=Uncut off
unCutoff.description=Uncut off
# Accession
accession.title=Accession
accession.description=Accession
# Retain
retain.title=Retain
retain.description=Retain
# 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

@@ -3,35 +3,4 @@ rm.audit.created-object=Created Object
rm.audit.delte-object=Delete Object rm.audit.delte-object=Delete Object
rm.audit.login-succeeded=Login Succeeded rm.audit.login-succeeded=Login Succeeded
rm.audit.login-failed=Login Failed rm.audit.login-failed=Login Failed
rm.audit.filed-record=Filed Record rm.audit.create-person=Create Person
rm.audit.reviewed=Reviewed
rm.audit.cut-off=Cut Off
rm.audit.reversed-cut-off=Reversed Cut Off
rm.audit.destroyed-item=Destroyed Item
rm.audit.opened-record-folder=Opened Record Folder
rm.audit.closed-record-folder=Closed Record Folder
rm.audit.setup-recorder-folder=Setup Recorder Folder
rm.audit.declared-record=Complete Record
rm.audit.undeclared-record=Reopen Record
rm.audit.froze-item=Froze Item
rm.audit.relinquised-hold=Relinquished Hold
rm.audit.updated-hold-reason=Updated Hold Reason
rm.audit.updated-review-as-of-date=Updated Review As Of Date
rm.audit.updated-disposition-as-of-date=Updated Disposition As Of Date
rm.audit.updated-vital-record-definition=Updated Vital Record Definition
rm.audit.updated-disposition-action-definition=Updated Disposition Action Definition
rm.audit.completed-event=Completed Event
rm.audit.revered-complete-event=Reversed Completed Event
rm.audit.transferred-item=Transferred Item
rm.audit.completed-transfer=Completed Transfer
rm.audit.accession=Accession
rm.audit.copmleted-accession=Completed Accession
rm.audit.scanned-record=Set Record as a Scanned Record
rm.audit.pdf-record=Set Record as a PDF Record
rm.audit.photo-record=Set Record as a Digital Photographic Record
rm.audit.web-record=Set Record as a Web Record
rm.audit.trail-file-fail=Failed to generate audit trail file.
rm.audit.audit-report=Audit Report
rm.audit.create-disposition-schedule=Create Disposition Schedule
rm.audit.unfreeze=Unfreeze
rm.audit.reject-record=Reject Record

View File

@@ -43,35 +43,12 @@
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-model-context.xml"/> <import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-model-context.xml"/>
<!-- Import RM Audit -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-audit-context.xml"/>
<!-- Import RM query context --> <!-- Import RM query context -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/query/rm-query-context.xml" /> <import resource="classpath:alfresco/module/org_alfresco_module_rm/query/rm-query-context.xml" />
<!-- Load audit config -->
<bean id="org_alfresco_module_rm_userRolesExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.AuthenticatedUserRolesDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
<property name="filePlanRoleService" ref="filePlanRoleService" />
</bean>
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.FilePlanNamePathDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
</bean>
<bean id="org_alfresco_module_rm_nodeRefPathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.FilePlanNodeRefPathDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
</bean>
<bean id="org_alfresco_module_rm_identifierExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.FilePlanIdentifierDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
</bean>
<!-- Bootstrap the permission model --> <!-- Bootstrap the permission model -->
<bean id="org_alfresco_module_rm_permissionBootstrap" parent="permissionModelBootstrap"> <bean id="org_alfresco_module_rm_permissionBootstrap" parent="permissionModelBootstrap">

View File

@@ -582,6 +582,7 @@
parent="rmAction"> parent="rmAction">
<property name="filePlanService" ref="FilePlanService"/> <property name="filePlanService" ref="FilePlanService"/>
<property name="filePlanAuthenticationService" ref="FilePlanAuthenticationService"/> <property name="filePlanAuthenticationService" ref="FilePlanAuthenticationService"/>
<property name="auditable" value="false"/>
</bean> </bean>
<!-- broadcast disposition action definition update --> <!-- broadcast disposition action definition update -->
@@ -612,6 +613,7 @@
class="org.alfresco.module.org_alfresco_module_rm.action.impl.BroadcastDispositionActionDefinitionUpdateAction" class="org.alfresco.module.org_alfresco_module_rm.action.impl.BroadcastDispositionActionDefinitionUpdateAction"
parent="rmAction" > parent="rmAction" >
<property name="behaviourFilter" ref="policyBehaviourFilter"/> <property name="behaviourFilter" ref="policyBehaviourFilter"/>
<property name="auditable" value="false"/>
</bean> </bean>

View File

@@ -0,0 +1,69 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- audit extractors -->
<bean id="org_alfresco_module_rm_userRolesExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.AuthenticatedUserRolesDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
<property name="filePlanRoleService" ref="filePlanRoleService" />
</bean>
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanNamePathDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
</bean>
<bean id="org_alfresco_module_rm_nodeRefPathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanNodeRefPathDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
</bean>
<bean id="org_alfresco_module_rm_identifierExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanIdentifierDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
</bean>
<!-- audit events -->
<bean id="audit-event" abstract="true" init-method="init">
<property name="recordsManagementAuditService" ref="recordsManagementAuditService"/>
<property name="policyComponent" ref="policyComponent" />
</bean>
<bean id="audit-event.create-object" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.CreateObjectAuditEvent">
<property name="name" value="Create RM Object"/>
<property name="label" value="rm.audit.created-object"/>
</bean>
<bean id="audit-event.update-object" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.UpdateObjectAuditEvent">
<property name="name" value="Update RM Object"/>
<property name="label" value="rm.audit.updated-metadata"/>
</bean>
<bean id="audit-event.delete-object" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.DeleteObjectAuditEvent">
<property name="name" value="Delete RM Object"/>
<property name="label" value="rm.audit.delte-object"/>
</bean>
<bean id="audit-event.create-person" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.CreatePersonAuditEvent">
<property name="name" value="Create Person"/>
<property name="label" value="rm.audit.create-person"/>
</bean>
<bean id="audit-event.login-success" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent">
<property name="name" value="Login.Success"/>
<property name="label" value="rm.audit.login-succeeded"/>
</bean>
<bean id="audit-event.login-fail" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent">
<property name="name" value="Login.Failure"/>
<property name="label" value="rm.audit.login-failed"/>
</bean>
</beans>

View File

@@ -966,6 +966,8 @@
<property name="dictionaryService" ref="dictionaryService" /> <property name="dictionaryService" ref="dictionaryService" />
<property name="recordService" ref="RecordService" /> <property name="recordService" ref="RecordService" />
<property name="filePlanService" ref="FilePlanService" /> <property name="filePlanService" ref="FilePlanService" />
<property name="permissionService" ref="PermissionService" />
<property name="filePlanRoleService" ref="FilePlanRoleService" />
</bean> </bean>
<bean id="FreezeService" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="FreezeService" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -1081,19 +1083,15 @@
<property name="objectDefinitionSource"> <property name="objectDefinitionSource">
<value> <value>
<![CDATA[ <![CDATA[
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.clear=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.registerAuditEvent=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.auditEvent=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.clearAuditLog=RM_CAP.0.rma:filePlanComponent.DeleteAudit org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.clearAuditLog=RM_CAP.0.rma:filePlanComponent.DeleteAudit
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getAuditTrail=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getAuditTrail=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getAuditTrailFile=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getAuditTrailFile=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getDateLastStarted=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getDateAuditLogLastStarted=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getDateAuditLogLastStarted=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getDateLastStopped=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getDateAuditLogLastStopped=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getDateAuditLogLastStopped=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.isEnabled=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.isAuditLogEnabled=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.isAuditLogEnabled=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.start=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.startAuditLog=RM_CAP.0.rma:filePlanComponent.EnableDisableAuditByTypes org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.startAuditLog=RM_CAP.0.rma:filePlanComponent.EnableDisableAuditByTypes
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.stop=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.stopAuditLog=RM_CAP.0.rma:filePlanComponent.EnableDisableAuditByTypes org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.stopAuditLog=RM_CAP.0.rma:filePlanComponent.EnableDisableAuditByTypes
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.fileAuditTrailAsRecord=RM_CAP.1.rma:filePlanComponent.DeclareAuditAsRecord org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.fileAuditTrailAsRecord=RM_CAP.1.rma:filePlanComponent.DeclareAuditAsRecord
org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getAuditEvents=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.getAuditEvents=RM_ALLOW

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2005-2011 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.audit;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Deprecated records management audit interface methods.
*
* @author Roy Wetherall
* @since 2.1
*/
public interface RecordsManagementAuditServiceDeprecated
{
/**
* @deprecated as of 2.1, see {@link #stop(NodeRef)}
*/
@Deprecated
void stop();
/**
* @deprecated as of 2.1, see {@link #clear(NodeRef)}
*/
@Deprecated
void clear();
/**
* @deprecated as of 2.1, see {@link #isEnabled(NodeRef)}
*/
@Deprecated
boolean isEnabled();
/**
* @deprecated as of 2.1, see {@link #getDateLastStarted(NodeRef)}
*/
@Deprecated
Date getDateLastStarted();
/**
* @deprecated as of 2.1, see {@link #getDateLastStopped(NodeRef)}
*/
Date getDateLastStopped();
/**
* @deprecated as of 2.1
*/
@Deprecated
void auditRMAction(RecordsManagementAction action, NodeRef nodeRef, Map<String, Serializable> parameters);
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2005-2013 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.action;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* Auditable action executer abstract base
*
* @author Roy Wetherall
* @since 2.1
*/
public abstract class AuditableActionExecuterAbstractBase extends ActionExecuterAbstractBase implements ApplicationContextAware
{
/** Indicates whether the action is auditable or not */
protected boolean auditable = true;
protected ApplicationContext applicationContext;
private RecordsManagementAuditService auditService;
public void setAuditable(boolean auditable)
{
this.auditable = auditable;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
private RecordsManagementAuditService getAuditService()
{
if (auditService == null)
{
auditService = (RecordsManagementAuditService)applicationContext.getBean("recordsManagementAuditService");
}
return auditService;
}
@Override
public void init()
{
super.init();
if (auditable == true)
{
getAuditService().registerAuditEvent(this.getActionDefinition().getName(), this.getActionDefinition().getTitle());
}
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#execute(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public void execute(Action action, NodeRef actionedUponNodeRef)
{
// execute the action
super.execute(action, actionedUponNodeRef);
// audit the execution of the action
if (auditable == true)
{
getAuditService().auditEvent(actionedUponNodeRef, this.getActionDefinition().getName());
}
}
}

View File

@@ -18,7 +18,6 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.action; package org.alfresco.module.org_alfresco_module_rm.action;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.action.parameter.ParameterProcessorComponent; import org.alfresco.repo.action.parameter.ParameterProcessorComponent;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -26,28 +25,42 @@ import org.alfresco.service.cmr.repository.NodeRef;
/** /**
* Extension to action implementation hierarchy to insert parameter substitution processing. * Extension to action implementation hierarchy to insert parameter substitution processing.
* *
* NOTE: this should eventually be pushed into the core.
*
* @author Roy Wetherall * @author Roy Wetherall
* @since 2.1 * @since 2.1
*/ */
public abstract class PropertySubActionExecuterAbstractBase extends ActionExecuterAbstractBase public abstract class PropertySubActionExecuterAbstractBase extends AuditableActionExecuterAbstractBase
{ {
/** Parameter processor component */
private ParameterProcessorComponent parameterProcessorComponent; private ParameterProcessorComponent parameterProcessorComponent;
/** Indicates whether parameter substitutions are allowed */
protected boolean allowParameterSubstitutions = false; protected boolean allowParameterSubstitutions = false;
/**
* @param parameterProcessorComponent parameter processor component
*/
public void setParameterProcessorComponent(ParameterProcessorComponent parameterProcessorComponent) public void setParameterProcessorComponent(ParameterProcessorComponent parameterProcessorComponent)
{ {
this.parameterProcessorComponent = parameterProcessorComponent; this.parameterProcessorComponent = parameterProcessorComponent;
} }
/**
* @param allowParameterSubstitutions true if property subs allowed, false otherwise
*/
public void setAllowParameterSubstitutions(boolean allowParameterSubstitutions) public void setAllowParameterSubstitutions(boolean allowParameterSubstitutions)
{ {
this.allowParameterSubstitutions = allowParameterSubstitutions; this.allowParameterSubstitutions = allowParameterSubstitutions;
} }
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#execute(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override @Override
public void execute(Action action, NodeRef actionedUponNodeRef) public void execute(Action action, NodeRef actionedUponNodeRef)
{ {
// do the property subs (if any exist)
if (allowParameterSubstitutions == true) if (allowParameterSubstitutions == true)
{ {
parameterProcessorComponent.process(action, getActionDefinition(), actionedUponNodeRef); parameterProcessorComponent.process(action, getActionDefinition(), actionedUponNodeRef);

View File

@@ -324,6 +324,8 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe
PropertyCheck.mandatory(this, "recordsManagementService", recordsManagementService); PropertyCheck.mandatory(this, "recordsManagementService", recordsManagementService);
PropertyCheck.mandatory(this, "recordsManagementAdminService", recordsManagementAdminService); PropertyCheck.mandatory(this, "recordsManagementAdminService", recordsManagementAdminService);
PropertyCheck.mandatory(this, "recordsManagementEventService", recordsManagementEventService); PropertyCheck.mandatory(this, "recordsManagementEventService", recordsManagementEventService);
super.init();
} }
/** /**
@@ -405,8 +407,6 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe
Action action = this.actionService.createAction(name); Action action = this.actionService.createAction(name);
action.setParameterValues(parameters); action.setParameterValues(parameters);
recordsManagementAuditService.auditRMAction(this, filePlanComponent, parameters);
// Execute the action // Execute the action
this.actionService.executeAction(action, filePlanComponent); this.actionService.executeAction(action, filePlanComponent);

View File

@@ -22,12 +22,12 @@ import java.util.List;
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.action.AuditableActionExecuterAbstractBase;
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;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationService; import org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationService;
import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
@@ -45,7 +45,7 @@ import org.apache.commons.logging.LogFactory;
* *
* @author Roy Wetherall * @author Roy Wetherall
*/ */
public class CreateRecordAction extends ActionExecuterAbstractBase public class CreateRecordAction extends AuditableActionExecuterAbstractBase
implements RecordsManagementModel implements RecordsManagementModel
{ {
/** Logger */ /** Logger */

View File

@@ -20,9 +20,9 @@ package org.alfresco.module.org_alfresco_module_rm.action.dm;
import java.util.List; import java.util.List;
import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase;
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.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -38,7 +38,8 @@ import org.apache.commons.logging.LogFactory;
* @author Tuna Aksoy * @author Tuna Aksoy
* @since 2.1 * @since 2.1
*/ */
public class HideRecordAction extends ActionExecuterAbstractBase implements RecordsManagementModel public class HideRecordAction extends AuditableActionExecuterAbstractBase
implements RecordsManagementModel
{ {
/** Logger */ /** Logger */

View File

@@ -1,68 +0,0 @@
/*
* Copyright (C) 2005-2011 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.audit;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Class to represent an audit event
*
* @author Gavin Cornwell
*/
public class AuditEvent
{
private final String name;
private final String label;
/**
* Constructor
*
* @param name The audit event name
* @param label The audit event label (or I18N lookup id)
*/
public AuditEvent(String name, String label)
{
this.name = name;
String lookup = I18NUtil.getMessage(label);
if (lookup != null)
{
label = lookup;
}
this.label = label;
}
/**
*
* @return The audit event name
*/
public String getName()
{
return this.name;
}
/**
*
* @return The audit event label
*/
public String getLabel()
{
return this.label;
}
}

View File

@@ -24,21 +24,19 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction; import org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/** /**
* Records management audit service. * Records management audit service.
* *
* @author Gavin Cornwell * @author Gavin Cornwell
*/ */
public interface RecordsManagementAuditService public interface RecordsManagementAuditService extends RecordsManagementAuditServiceDeprecated
{ {
public enum ReportFormat { HTML, JSON } public enum ReportFormat { HTML, JSON }
public static final String RM_AUDIT_EVENT_UPDATE_RM_OBJECT = "Update RM Object";
public static final String RM_AUDIT_EVENT_CREATE_RM_OBJECT = "Create RM Object";
public static final String RM_AUDIT_EVENT_DELETE_RM_OBJECT = "Delete RM Object";
public static final String RM_AUDIT_EVENT_LOGIN_SUCCESS = "Login.Success"; public static final String RM_AUDIT_EVENT_LOGIN_SUCCESS = "Login.Success";
public static final String RM_AUDIT_EVENT_LOGIN_FAILURE = "Login.Failure"; public static final String RM_AUDIT_EVENT_LOGIN_FAILURE = "Login.Failure";
@@ -68,49 +66,59 @@ public interface RecordsManagementAuditService
public static final String RM_AUDIT_DATA_LOGIN_ERROR = "/RM/login/error/value"; public static final String RM_AUDIT_DATA_LOGIN_ERROR = "/RM/login/error/value";
/** /**
* @deprecated as of 2.1, see {@link #start(NodeRef)} * Retrieves a list of audit events.
*/
@Deprecated
void start();
/**
* Start RM auditing.
* *
* @param filePlan file plan * @return List of audit events
*/ */
void startAuditLog(NodeRef filePlan); List<AuditEvent> getAuditEvents();
/** /**
* @deprecated as of 2.1, see {@link #stop(NodeRef)} * Register audit event
*/
@Deprecated
void stop();
/**
* Stop RM auditing.
* *
* @param filePlan file plan * @param name name of audit event
* @param label display label of audit event
*/ */
void stopAuditLog(NodeRef filePlan); void registerAuditEvent(String name, String label);
/** /**
* @deprecated as of 2.1, see {@link #clear(NodeRef)}
*/
@Deprecated
void clear();
/**
* Clears the RM audit.
* *
* @param filePlan file plan * @param auditEvent
*/ */
void clearAuditLog(NodeRef filePlan); void registerAuditEvent(AuditEvent auditEvent);
/** /**
* @deprecated as of 2.1, see {@link #isEnabled(NodeRef)} *
* @param nodeRef
* @param eventName
*/ */
@Deprecated void auditEvent(NodeRef nodeRef,
boolean isEnabled(); String eventName);
/**
*
* @param nodeRef
* @param eventName
* @param before
* @param after
*/
void auditEvent(NodeRef nodeRef,
String eventName,
Map<QName, Serializable> before,
Map<QName, Serializable> after);
/**
*
* @param nodeRef
* @param eventName
* @param before
* @param after
* @param immediate
*/
void auditEvent(NodeRef nodeRef,
String eventName,
Map<QName, Serializable> before,
Map<QName, Serializable> after,
boolean immediate);
/** /**
* Determines whether the RM audit log is currently enabled. * Determines whether the RM audit log is currently enabled.
@@ -121,10 +129,26 @@ public interface RecordsManagementAuditService
boolean isAuditLogEnabled(NodeRef filePlan); boolean isAuditLogEnabled(NodeRef filePlan);
/** /**
* @deprecated as of 2.1, see {@link #getDateLastStarted(NodeRef)} * Start RM auditing.
*
* @param filePlan file plan
*/ */
@Deprecated void startAuditLog(NodeRef filePlan);
Date getDateLastStarted();
/**
* Stop RM auditing.
*
* @param filePlan file plan
*/
void stopAuditLog(NodeRef filePlan);
/**
* Clears the RM audit.
*
* @param filePlan file plan
*/
void clearAuditLog(NodeRef filePlan);
/** /**
* Returns the date the RM audit was last started. * Returns the date the RM audit was last started.
@@ -134,11 +158,6 @@ public interface RecordsManagementAuditService
*/ */
Date getDateAuditLogLastStarted(NodeRef filePlan); Date getDateAuditLogLastStarted(NodeRef filePlan);
/**
* @deprecated as of 2.1, see {@link #getDateLastStopped(NodeRef)}
*/
Date getDateLastStopped();
/** /**
* Returns the date the RM audit was last stopped. * Returns the date the RM audit was last stopped.
* *
@@ -146,15 +165,6 @@ public interface RecordsManagementAuditService
*/ */
Date getDateAuditLogLastStopped(NodeRef filePlan); Date getDateAuditLogLastStopped(NodeRef filePlan);
/**
* An explicit call that RM actions can make to have the events logged.
*
* @param action the action that will be performed
* @param nodeRef the component being acted on
* @param parameters the action's parameters
*/
void auditRMAction(RecordsManagementAction action, NodeRef nodeRef, Map<String, Serializable> parameters);
/** /**
* Retrieves a list of audit log entries using the provided parameters * Retrieves a list of audit log entries using the provided parameters
* represented by the RecordsManagementAuditQueryParameters instance. * represented by the RecordsManagementAuditQueryParameters instance.
@@ -201,18 +211,4 @@ public interface RecordsManagementAuditService
* @return NodeRef of the undeclared record filed * @return NodeRef of the undeclared record filed
*/ */
NodeRef fileAuditTrailAsRecord(RecordsManagementAuditQueryParameters params, NodeRef destination, ReportFormat format); NodeRef fileAuditTrailAsRecord(RecordsManagementAuditQueryParameters params, NodeRef destination, ReportFormat format);
/**
* Retrieves a list of audit events.
*
* @return List of audit events
*/
List<AuditEvent> getAuditEvents();
/**
* Register records management action
*
* @param rmAction records management action
*/
void register(RecordsManagementAction rmAction);
} }

View File

@@ -29,24 +29,21 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
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.action.RecordsManagementAction; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
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.event.AuditEvent;
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.repo.audit.AuditComponent; import org.alfresco.repo.audit.AuditComponent;
import org.alfresco.repo.audit.model.AuditApplication; import org.alfresco.repo.audit.model.AuditApplication;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
@@ -59,7 +56,6 @@ import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -90,19 +86,10 @@ import org.springframework.extensions.surf.util.ParameterCheck;
* @author Gavin Cornwell * @author Gavin Cornwell
* @since 3.2 * @since 3.2
*/ */
public class RecordsManagementAuditServiceImpl public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
extends AbstractLifecycleBean implements RecordsManagementAuditService
implements RecordsManagementAuditService,
NodeServicePolicies.OnCreateNodePolicy,
NodeServicePolicies.BeforeDeleteNodePolicy,
NodeServicePolicies.OnUpdatePropertiesPolicy
{ {
/** I18N */ /** I18N */
private static final String MSG_UPDATED_METADATA = "rm.audit.updated-metadata";
private static final String MSG_CREATED_OBJECT = "rm.audit.created-object";
private static final String MSG_DELETE_OBJECT = "rm.audit.delte-object";
private static final String MSG_LOGIN_SUCCEEDED = "rm.audit.login-succeeded";
private static final String MSG_LOGIN_FAILED = "rm.audit.login-failed";
private static final String MSG_TRAIL_FILE_FAIL = "rm.audit.trail-file-fail"; private static final String MSG_TRAIL_FILE_FAIL = "rm.audit.trail-file-fail";
private static final String MSG_AUDIT_REPORT = "rm.audit.audit-report"; private static final String MSG_AUDIT_REPORT = "rm.audit.audit-report";
@@ -128,7 +115,7 @@ public class RecordsManagementAuditServiceImpl
private boolean shutdown = false; private boolean shutdown = false;
private RMAuditTxnListener txnListener; private RMAuditTxnListener txnListener = new RMAuditTxnListener();
/** Registered and initialised records management auditEvents */ /** Registered and initialised records management auditEvents */
private Map<String, AuditEvent> auditEvents = new HashMap<String, AuditEvent>(); private Map<String, AuditEvent> auditEvents = new HashMap<String, AuditEvent>();
@@ -213,15 +200,21 @@ public class RecordsManagementAuditServiceImpl
this.filePlanService = filePlanService; this.filePlanService = filePlanService;
} }
/** @Override
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementAuditService#register(org.alfresco.module.org_alfresco_module_rm.RecordsManagementAction) public void registerAuditEvent(String name, String label)
*/
public void register(RecordsManagementAction rmAction)
{ {
if (this.auditEvents.containsKey(rmAction.getName()) == false) registerAuditEvent(new AuditEvent(name, label));
}
@Override
public void registerAuditEvent(AuditEvent auditEvent)
{
if (logger.isDebugEnabled() == true)
{ {
this.auditEvents.put(rmAction.getName(), new AuditEvent(rmAction.getName(), rmAction.getLabel())); logger.debug("Registering audit event " + auditEvent.getName());
} }
this.auditEvents.put(auditEvent.getName(), auditEvent);
} }
/** /**
@@ -239,52 +232,12 @@ public class RecordsManagementAuditServiceImpl
PropertyCheck.mandatory(this, "rmActionService", rmActionService); PropertyCheck.mandatory(this, "rmActionService", rmActionService);
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService); PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
PropertyCheck.mandatory(this, "filePlanService", filePlanService); PropertyCheck.mandatory(this, "filePlanService", filePlanService);
// setup the audit events map
initAuditEvents();
}
protected void initAuditEvents()
{
this.auditEvents.put(RM_AUDIT_EVENT_UPDATE_RM_OBJECT,
new AuditEvent(RM_AUDIT_EVENT_UPDATE_RM_OBJECT, MSG_UPDATED_METADATA));
this.auditEvents.put(RM_AUDIT_EVENT_CREATE_RM_OBJECT,
new AuditEvent(RM_AUDIT_EVENT_CREATE_RM_OBJECT, MSG_CREATED_OBJECT));
this.auditEvents.put(RM_AUDIT_EVENT_DELETE_RM_OBJECT,
new AuditEvent(RM_AUDIT_EVENT_DELETE_RM_OBJECT, MSG_DELETE_OBJECT));
this.auditEvents.put(RM_AUDIT_EVENT_LOGIN_SUCCESS,
new AuditEvent(RM_AUDIT_EVENT_LOGIN_SUCCESS, MSG_LOGIN_SUCCEEDED));
this.auditEvents.put(RM_AUDIT_EVENT_LOGIN_FAILURE,
new AuditEvent(RM_AUDIT_EVENT_LOGIN_FAILURE, MSG_LOGIN_FAILED));
// Added for DOD compliance
this.auditEvents.put("createPerson",
new AuditEvent("createPerson", "User Created"));
} }
@Override @Override
protected void onBootstrap(ApplicationEvent event) protected void onBootstrap(ApplicationEvent event)
{ {
shutdown = false; shutdown = false;
txnListener = new RMAuditTxnListener();
// Register to listen for property changes to rma:record types
policyComponent.bindClassBehaviour(
OnUpdatePropertiesPolicy.QNAME,
RecordsManagementModel.ASPECT_RECORD_COMPONENT_ID,
new JavaBehaviour(this, "onUpdateProperties"));
policyComponent.bindClassBehaviour(
OnCreateNodePolicy.QNAME,
RecordsManagementModel.ASPECT_RECORD_COMPONENT_ID,
new JavaBehaviour(this, "onCreateNode"));
policyComponent.bindClassBehaviour(
BeforeDeleteNodePolicy.QNAME,
RecordsManagementModel.ASPECT_RECORD_COMPONENT_ID,
new JavaBehaviour(this, "beforeDeleteNode"));
policyComponent.bindClassBehaviour(
OnCreateNodePolicy.QNAME,
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, "onCreatePersonNode"));
} }
@Override @Override
@@ -293,25 +246,21 @@ public class RecordsManagementAuditServiceImpl
shutdown = true; shutdown = true;
} }
/*** TODO remove this when we support multiple file plans ****/ /**
* Helper method to get the default file plan
private NodeRef defaultFilePlan; *
* @return NodRef default file plan
*/
private NodeRef getDefaultFilePlan() private NodeRef getDefaultFilePlan()
{ {
NodeRef defaultFilePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (defaultFilePlan == null) if (defaultFilePlan == null)
{ {
defaultFilePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); throw new AlfrescoRuntimeException("Default file plan could not be found.");
if (defaultFilePlan == null) }
{
throw new AlfrescoRuntimeException("Default file plan could not be found.");
}
}
return defaultFilePlan; return defaultFilePlan;
} }
/*** TODO end ***/
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@@ -493,54 +442,37 @@ public class RecordsManagementAuditServiceImpl
} }
} }
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
{
auditRMEvent(nodeRef, RM_AUDIT_EVENT_UPDATE_RM_OBJECT, before, after);
}
public void beforeDeleteNode(NodeRef nodeRef)
{
auditRMEvent(nodeRef, RM_AUDIT_EVENT_DELETE_RM_OBJECT, null, null);
}
public void onCreateNode(ChildAssociationRef childAssocRef)
{
auditRMEvent(childAssocRef.getChildRef(), RM_AUDIT_EVENT_CREATE_RM_OBJECT, null, null);
}
public void onCreatePersonNode(ChildAssociationRef childAssocRef)
{
auditRMEvent(childAssocRef.getChildRef(), "createPerson", null, null);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
* @since 3.2 * @since 3.2
* @deprecated since 2.1
*/ */
@Deprecated
public void auditRMAction( public void auditRMAction(
RecordsManagementAction action, RecordsManagementAction action,
NodeRef nodeRef, NodeRef nodeRef,
Map<String, Serializable> parameters) Map<String, Serializable> parameters)
{ {
auditRMEvent(nodeRef, action.getName(), null, null); auditEvent(nodeRef, action.getName());
} }
/** @Override
* Audit an event for a node public void auditEvent(NodeRef nodeRef, String eventName)
*
* @param nodeRef the node to which the event applies
* @param eventName the name of the event
* @param nodePropertiesBefore properties before the event (optional)
* @param nodePropertiesAfter properties after the event (optional)
*/
private void auditRMEvent(
NodeRef nodeRef,
String eventName,
Map<QName, Serializable> nodePropertiesBefore,
Map<QName, Serializable> nodePropertiesAfter)
{ {
// If we are deleting nodes, then we need to audit NOW auditEvent(nodeRef, eventName, null, null, false);
if (eventName.equals(RecordsManagementAuditService.RM_AUDIT_EVENT_DELETE_RM_OBJECT)) }
@Override
public void auditEvent(NodeRef nodeRef, String eventName, Map<QName, Serializable> before, Map<QName, Serializable> after)
{
auditEvent(nodeRef, eventName, before, after, false);
}
@Override
public void auditEvent(NodeRef nodeRef, String eventName, Map<QName, Serializable> before, Map<QName, Serializable> after, boolean immediate)
{
// deal with immediate auditing if required
if (immediate == true)
{ {
// Deleted nodes will not be available at the end of the transaction. The data needs to // Deleted nodes will not be available at the end of the transaction. The data needs to
// be extracted now and the audit entry needs to be created now. // be extracted now and the audit entry needs to be created now.
@@ -555,16 +487,20 @@ public class RecordsManagementAuditServiceImpl
else else
{ {
// Create an event for auditing post-commit // Create an event for auditing post-commit
Map<NodeRef, RMAuditNode> auditedNodes = TransactionalResourceHelper.getMap(KEY_RM_AUDIT_NODE_RECORDS); Map<NodeRef, Set<RMAuditNode>> auditedNodes = TransactionalResourceHelper.getMap(KEY_RM_AUDIT_NODE_RECORDS);
RMAuditNode auditedNode = auditedNodes.get(nodeRef); Set<RMAuditNode> auditDetails = auditedNodes.get(nodeRef);
if (auditedNode == null) if (auditDetails == null)
{ {
auditedNode = new RMAuditNode(); auditDetails = new HashSet<RMAuditNode>(3);
auditedNodes.put(nodeRef, auditedNode); auditedNodes.put(nodeRef, auditDetails);
// Bind the listener to the txn. We could do it anywhere in the method, this position ensures // Bind the listener to the txn. We could do it anywhere in the method, this position ensures
// that we avoid some rebinding of the listener // that we avoid some rebinding of the listener
AlfrescoTransactionSupport.bindListener(txnListener); AlfrescoTransactionSupport.bindListener(txnListener);
} }
RMAuditNode auditedNode = new RMAuditNode();
// Only update the eventName if it has not already been done // Only update the eventName if it has not already been done
if (auditedNode.getEventName() == null) if (auditedNode.getEventName() == null)
{ {
@@ -573,15 +509,17 @@ public class RecordsManagementAuditServiceImpl
// Set the properties before the start if they are not already available // Set the properties before the start if they are not already available
if (auditedNode.getNodePropertiesBefore() == null) if (auditedNode.getNodePropertiesBefore() == null)
{ {
auditedNode.setNodePropertiesBefore(nodePropertiesBefore); auditedNode.setNodePropertiesBefore(before);
} }
// Set the after values if they are provided. // Set the after values if they are provided.
// Overwrite as we assume that these represent the latest state of the node. // Overwrite as we assume that these represent the latest state of the node.
if (nodePropertiesAfter != null) if (after != null)
{ {
auditedNode.setNodePropertiesAfter(nodePropertiesAfter); auditedNode.setNodePropertiesAfter(after);
} }
// That is it. The values are queued for the end of the transaction. // That is it. The values are queued for the end of the transaction.
auditDetails.add(auditedNode);
} }
} }
@@ -634,7 +572,7 @@ public class RecordsManagementAuditServiceImpl
@Override @Override
public void afterCommit() public void afterCommit()
{ {
final Map<NodeRef, RMAuditNode> auditedNodes = TransactionalResourceHelper.getMap(KEY_RM_AUDIT_NODE_RECORDS); final Map<NodeRef, Set<RMAuditNode>> auditedNodes = TransactionalResourceHelper.getMap(KEY_RM_AUDIT_NODE_RECORDS);
// Start a *new* read-write transaction to audit in // Start a *new* read-write transaction to audit in
RetryingTransactionCallback<Void> auditCallback = new RetryingTransactionCallback<Void>() RetryingTransactionCallback<Void> auditCallback = new RetryingTransactionCallback<Void>()
@@ -653,11 +591,11 @@ public class RecordsManagementAuditServiceImpl
* *
* @param auditedNodes details of the nodes that were modified * @param auditedNodes details of the nodes that were modified
*/ */
private void auditInTxn(Map<NodeRef, RMAuditNode> auditedNodes) throws Throwable private void auditInTxn(Map<NodeRef, Set<RMAuditNode>> auditedNodes) throws Throwable
{ {
// Go through all the audit information and audit it // Go through all the audit information and audit it
boolean auditedSomething = false; // We rollback if nothing is audited boolean auditedSomething = false; // We rollback if nothing is audited
for (Map.Entry<NodeRef, RMAuditNode> entry : auditedNodes.entrySet()) for (Map.Entry<NodeRef, Set<RMAuditNode>> entry : auditedNodes.entrySet())
{ {
NodeRef nodeRef = entry.getKey(); NodeRef nodeRef = entry.getKey();
@@ -667,63 +605,66 @@ public class RecordsManagementAuditServiceImpl
continue; continue;
} }
RMAuditNode auditedNode = entry.getValue(); Set<RMAuditNode> auditedNodeDetails = entry.getValue();
// Action description for (RMAuditNode auditedNode : auditedNodeDetails)
String eventName = auditedNode.getEventName();
Map<String, Serializable> auditMap = buildAuditMap(nodeRef, eventName);
// TODO do we care if the before and after are null??
// Property changes
Map<QName, Serializable> propertiesBefore = auditedNode.getNodePropertiesBefore();
Map<QName, Serializable> propertiesAfter = auditedNode.getNodePropertiesAfter();
Pair<Map<QName, Serializable>, Map<QName, Serializable>> deltaPair =
PropertyMap.getBeforeAndAfterMapsForChanges(propertiesBefore, propertiesAfter);
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_BEFORE),
(Serializable) deltaPair.getFirst());
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_AFTER),
(Serializable) deltaPair.getSecond());
// Audit it
if (logger.isDebugEnabled())
{
logger.debug("RM Audit: Auditing values: \n" + auditMap);
}
auditMap = auditComponent.recordAuditValues(RecordsManagementAuditService.RM_AUDIT_PATH_ROOT, auditMap);
if (auditMap.isEmpty())
{ {
// Action description
String eventName = auditedNode.getEventName();
Map<String, Serializable> auditMap = buildAuditMap(nodeRef, eventName);
// TODO do we care if the before and after are null??
// Property changes
Map<QName, Serializable> propertiesBefore = auditedNode.getNodePropertiesBefore();
Map<QName, Serializable> propertiesAfter = auditedNode.getNodePropertiesAfter();
Pair<Map<QName, Serializable>, Map<QName, Serializable>> deltaPair =
PropertyMap.getBeforeAndAfterMapsForChanges(propertiesBefore, propertiesAfter);
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_BEFORE),
(Serializable) deltaPair.getFirst());
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_AFTER),
(Serializable) deltaPair.getSecond());
// Audit it
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("RM Audit: Nothing was audited."); logger.debug("RM Audit: Auditing values: \n" + auditMap);
} }
} auditMap = auditComponent.recordAuditValues(RecordsManagementAuditService.RM_AUDIT_PATH_ROOT, auditMap);
else if (auditMap.isEmpty())
{
if (logger.isDebugEnabled())
{ {
logger.debug("RM Audit: Audited values: \n" + auditMap); if (logger.isDebugEnabled())
{
logger.debug("RM Audit: Nothing was audited.");
}
}
else
{
if (logger.isDebugEnabled())
{
logger.debug("RM Audit: Audited values: \n" + auditMap);
}
// We must commit the transaction to get the values in
auditedSomething = true;
} }
// We must commit the transaction to get the values in
auditedSomething = true;
} }
} // Check if anything was audited
// Check if anything was audited if (!auditedSomething)
if (!auditedSomething) {
{ // Nothing was audited, so do nothing
// Nothing was audited, so do nothing RetryingTransactionHelper.getActiveUserTransaction().setRollbackOnly();
RetryingTransactionHelper.getActiveUserTransaction().setRollbackOnly(); }
} }
} }
} }
@@ -849,18 +790,16 @@ public class RecordsManagementAuditServiceImpl
if (values.containsKey(RecordsManagementAuditService.RM_AUDIT_DATA_EVENT_NAME)) if (values.containsKey(RecordsManagementAuditService.RM_AUDIT_DATA_EVENT_NAME))
{ {
// This data is /RM/event/... // This data is /RM/event/...
eventName = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_EVENT_NAME); eventName = (String) values.get(RM_AUDIT_DATA_EVENT_NAME);
fullName = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_PERSON_FULLNAME); fullName = (String) values.get(RM_AUDIT_DATA_PERSON_FULLNAME);
userRoles = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_PERSON_ROLES); userRoles = (String) values.get(RM_AUDIT_DATA_PERSON_ROLES);
nodeRef = (NodeRef) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_NODE_NODEREF); nodeRef = (NodeRef) values.get(RM_AUDIT_DATA_NODE_NODEREF);
nodeName = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_NODE_NAME); nodeName = (String) values.get(RM_AUDIT_DATA_NODE_NAME);
QName nodeTypeQname = (QName) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_NODE_TYPE); QName nodeTypeQname = (QName) values.get(RM_AUDIT_DATA_NODE_TYPE);
nodeIdentifier = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_NODE_IDENTIFIER); nodeIdentifier = (String) values.get(RM_AUDIT_DATA_NODE_IDENTIFIER);
namePath = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_NODE_NAMEPATH); namePath = (String) values.get(RM_AUDIT_DATA_NODE_NAMEPATH);
beforeProperties = (Map<QName, Serializable>) values.get( beforeProperties = (Map<QName, Serializable>) values.get(RM_AUDIT_DATA_NODE_CHANGES_BEFORE);
RecordsManagementAuditService.RM_AUDIT_DATA_NODE_CHANGES_BEFORE); afterProperties = (Map<QName, Serializable>) values.get(RM_AUDIT_DATA_NODE_CHANGES_AFTER);
afterProperties = (Map<QName, Serializable>) values.get(
RecordsManagementAuditService.RM_AUDIT_DATA_NODE_CHANGES_AFTER);
// Convert some of the values to recognizable forms // Convert some of the values to recognizable forms
nodeType = null; nodeType = null;

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2005-2011 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.audit.event;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService;
import org.alfresco.repo.policy.PolicyComponent;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Class to represent an audit event
*
* @author Gavin Cornwell
* @author Roy Wetherall
*/
public class AuditEvent
{
/** Name */
protected String name;
/** Label */
protected String label;
protected RecordsManagementAuditService recordsManagementAuditService;
protected PolicyComponent policyComponent;
public void setRecordsManagementAuditService(RecordsManagementAuditService recordsManagementAuditService)
{
this.recordsManagementAuditService = recordsManagementAuditService;
}
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
public void init()
{
recordsManagementAuditService.registerAuditEvent(this);
}
public AuditEvent()
{
}
public AuditEvent(String name, String label)
{
this.name = name;
this.label = label;
}
/**
* @return audit event name
*/
public String getName()
{
return this.name;
}
/**
* @param name audit event name
*/
public void setName(String name)
{
this.name = name;
}
/**
* @return audit event label
*/
public String getLabel()
{
String lookup = I18NUtil.getMessage(label);
if (lookup == null)
{
lookup = label;
}
return lookup;
}
/**
* @param label audit event label
*/
public void setLabel(String label)
{
this.label = label;
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2005-2011 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.audit.event;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
public class CreateObjectAuditEvent extends AuditEvent implements OnCreateNodePolicy
{
/**
* @see org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent#init()
*/
@Override
public void init()
{
super.init();
policyComponent.bindClassBehaviour(
OnCreateNodePolicy.QNAME,
RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT,
new JavaBehaviour(this, "onCreateNode"));
}
/**
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef)
*/
public void onCreateNode(ChildAssociationRef childAssocRef)
{
recordsManagementAuditService.auditEvent(childAssocRef.getChildRef(), name);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005-2011 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.audit.event;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
public class CreatePersonAuditEvent extends AuditEvent implements OnCreateNodePolicy
{
@Override
public void init()
{
super.init();
policyComponent.bindClassBehaviour(
OnCreateNodePolicy.QNAME,
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, "onCreateNode"));
}
public void onCreateNode(ChildAssociationRef childAssocRef)
{
recordsManagementAuditService.auditEvent(childAssocRef.getChildRef(), name);
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2005-2011 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.audit.event;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.service.cmr.repository.NodeRef;
public class DeleteObjectAuditEvent extends AuditEvent implements BeforeDeleteNodePolicy
{
@Override
public void init()
{
super.init();
policyComponent.bindClassBehaviour(
BeforeDeleteNodePolicy.QNAME,
RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT,
new JavaBehaviour(this, "beforeDeleteNode"));
}
public void beforeDeleteNode(NodeRef nodeRef)
{
recordsManagementAuditService.auditEvent(nodeRef, name, null, null, true);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2005-2011 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.audit.event;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
public class UpdateObjectAuditEvent extends AuditEvent implements OnUpdatePropertiesPolicy
{
@Override
public void init()
{
super.init();
policyComponent.bindClassBehaviour(
OnUpdatePropertiesPolicy.QNAME,
RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT,
new JavaBehaviour(this, "onUpdateProperties"));
}
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
{
recordsManagementAuditService.auditEvent(nodeRef, name, before, after);
}
}

View File

@@ -16,7 +16,7 @@
* 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.audit; package org.alfresco.module.org_alfresco_module_rm.audit.extractor;
import java.io.Serializable; import java.io.Serializable;
import java.util.Set; import java.util.Set;

View File

@@ -16,7 +16,7 @@
* 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.audit; package org.alfresco.module.org_alfresco_module_rm.audit.extractor;
import java.io.Serializable; import java.io.Serializable;

View File

@@ -16,7 +16,7 @@
* 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.audit; package org.alfresco.module.org_alfresco_module_rm.audit.extractor;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;

View File

@@ -16,7 +16,7 @@
* 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.audit; package org.alfresco.module.org_alfresco_module_rm.audit.extractor;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;

View File

@@ -25,15 +25,23 @@ import org.alfresco.repo.action.RuntimeActionService;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.springframework.aop.framework.ProxyFactoryBean; import org.springframework.aop.framework.ProxyFactoryBean;
/**
* RM action proxy factory bean.
*
* @author Roy Wetherall
*/
public class RMActionProxyFactoryBean extends ProxyFactoryBean public class RMActionProxyFactoryBean extends ProxyFactoryBean
{ {
private static final long serialVersionUID = 539749542853266449L; private static final long serialVersionUID = 539749542853266449L;
/** Runtime action service */
protected RuntimeActionService runtimeActionService; protected RuntimeActionService runtimeActionService;
private RecordsManagementActionService recordsManagementActionService; /** Records management action service */
protected RecordsManagementActionService recordsManagementActionService;
private RecordsManagementAuditService recordsManagementAuditService; /** Records management audit service */
protected RecordsManagementAuditService recordsManagementAuditService;
/** /**
* Set action service * Set action service
@@ -65,18 +73,20 @@ public class RMActionProxyFactoryBean extends ProxyFactoryBean
this.recordsManagementAuditService = recordsManagementAuditService; this.recordsManagementAuditService = recordsManagementAuditService;
} }
/**
* Register the action
*/
public void registerAction() public void registerAction()
{ {
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>() AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>()
{ {
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
// if (((RMActionExecuterAbstractBase)getTargetSource().getTarget()).isPublicAction() == true) RecordsManagementAction action = (RecordsManagementAction)getObject();
// {
// runtimeActionService.registerActionExecuter((ActionExecuter) getObject()); recordsManagementActionService.register(action);
// } // recordsManagementAuditService.registerActionAuditEvent(action);
recordsManagementActionService.register((RecordsManagementAction) getObject());
recordsManagementAuditService.register((RecordsManagementAction) getObject());
return null; return null;
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());

View File

@@ -29,13 +29,15 @@ 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.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;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.JavaBehaviour; 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.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;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
@@ -44,6 +46,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
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.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.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
@@ -91,6 +94,12 @@ public class FreezeServiceImpl implements FreezeService,
/** File Plan Service */ /** File Plan Service */
private FilePlanService filePlanService; private FilePlanService filePlanService;
/** Permission service */
private PermissionService permissionService;
/** file plan role service */
private FilePlanRoleService filePlanRoleService;
/** /**
* @param policyComponent policy component * @param policyComponent policy component
*/ */
@@ -139,13 +148,31 @@ public class FreezeServiceImpl implements FreezeService,
this.filePlanService = filePlanService; this.filePlanService = filePlanService;
} }
/**
* @param permissionService permission service
*/
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
/**
* @param filePlanRoleService file plan role service
*/
public void setFilePlanRoleService(FilePlanRoleService filePlanRoleService)
{
this.filePlanRoleService = filePlanRoleService;
}
/** /**
* Init service * Init service
*/ */
public void init() public void init()
{ {
policyComponent.bindClassBehaviour(NodeServicePolicies.BeforeDeleteNodePolicy.QNAME, this, new JavaBehaviour( policyComponent.bindClassBehaviour(
this, "beforeDeleteNode", NotificationFrequency.FIRST_EVENT)); NodeServicePolicies.BeforeDeleteNodePolicy.QNAME,
this,
new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.FIRST_EVENT));
} }
/** /**
@@ -270,8 +297,10 @@ public class FreezeServiceImpl implements FreezeService,
boolean isRecord = recordService.isRecord(nodeRef); boolean isRecord = recordService.isRecord(nodeRef);
boolean isFolder = recordsManagementService.isRecordFolder(nodeRef); boolean isFolder = recordsManagementService.isRecordFolder(nodeRef);
if (!(isRecord || isFolder)) { throw new AlfrescoRuntimeException(I18NUtil if (!(isRecord || isFolder))
.getMessage(MSG_FREEZE_ONLY_RECORDS_FOLDERS)); } {
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_ONLY_RECORDS_FOLDERS));
}
// Log a message about freezing the node with the reason // Log a message about freezing the node with the reason
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@@ -612,6 +641,11 @@ public class FreezeServiceImpl implements FreezeService,
logger.debug(msg.toString()); logger.debug(msg.toString());
} }
// set inherit to false
permissionService.setInheritParentPermissions(holdNodeRef, false);
String allGroup = filePlanRoleService.getAllRolesContainerGroup(root);
permissionService.setPermission(holdNodeRef, allGroup, RMPermissionModel.FILING, true);
// Bind the hold node reference to the transaction // Bind the hold node reference to the transaction
AlfrescoTransactionSupport.bindResource(KEY_HOLD_NODEREF, holdNodeRef); AlfrescoTransactionSupport.bindResource(KEY_HOLD_NODEREF, holdNodeRef);

View File

@@ -187,7 +187,11 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
public NodeRef 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", new HashSet<String>(Arrays.asList(RMAuthority.ZONE_APP_RM))); String allRoles = authorityService.createAuthority(
AuthorityType.GROUP,
getAllRolesGroupShortName(rmRootNode),
"All Roles",
new HashSet<String>(Arrays.asList(RMAuthority.ZONE_APP_RM)));
// Set the permissions // Set the permissions
permissionService.setInheritParentPermissions(rmRootNode, false); permissionService.setInheritParentPermissions(rmRootNode, false);
@@ -195,10 +199,6 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
permissionService.setPermission(rmRootNode, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); permissionService.setPermission(rmRootNode, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
permissionService.setPermission(rmRootNode, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); permissionService.setPermission(rmRootNode, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
// set the capabilities
// permissionService.setPermission(rmRootNode, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.VIEW_RECORDS, true);
// permissionService.setPermission(rmRootNode, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.EDIT_NON_RECORD_METADATA, true);
// Create the unfiled record container // Create the unfiled record container
return filePlanService.createUnfiledContainer(rmRootNode); return filePlanService.createUnfiledContainer(rmRootNode);
} }

View File

@@ -28,8 +28,8 @@ import java.util.Set;
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.action.RecordsManagementAction; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
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.AuditEvent;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; 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.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty; import org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent; import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;

View File

@@ -26,10 +26,10 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.audit.AuditEvent;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditEntry; import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditEntry;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditQueryParameters; import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditQueryParameters;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; 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.test.util.BaseRMTestCase; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
import org.alfresco.repo.security.authentication.AuthenticationException; import org.alfresco.repo.security.authentication.AuthenticationException;

View File

@@ -28,7 +28,9 @@
<ref bean="testAction"/> <ref bean="testAction"/>
</property> </property>
</bean> </bean>
<bean id="testAction" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction" parent="rmAction"/> <bean id="testAction" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction" parent="rmAction">
<property name="auditable" value="false" />
</bean>
<bean id="testAction2_proxy" class="org.alfresco.module.org_alfresco_module_rm.capability.RMActionProxyFactoryBean" parent="rmProxyAction" init-method="registerAction"> <bean id="testAction2_proxy" class="org.alfresco.module.org_alfresco_module_rm.capability.RMActionProxyFactoryBean" parent="rmProxyAction" init-method="registerAction">
<property name="target"> <property name="target">
@@ -37,6 +39,7 @@
</bean> </bean>
<bean id="testAction2" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction2" parent="rmAction"> <bean id="testAction2" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction2" parent="rmAction">
<property name="publicAction" value="true"/> <property name="publicAction" value="true"/>
<property name="auditable" value="false" />
</bean> </bean>
<bean id="testActionParams_proxy" class="org.alfresco.module.org_alfresco_module_rm.capability.RMActionProxyFactoryBean" parent="rmProxyAction" init-method="registerAction"> <bean id="testActionParams_proxy" class="org.alfresco.module.org_alfresco_module_rm.capability.RMActionProxyFactoryBean" parent="rmProxyAction" init-method="registerAction">
@@ -44,7 +47,9 @@
<ref bean="testActionParams"/> <ref bean="testActionParams"/>
</property> </property>
</bean> </bean>
<bean id="testActionParams" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestActionParams" parent="rmAction"/> <bean id="testActionParams" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestActionParams" parent="rmAction">
<property name="auditable" value="false" />
</bean>
<bean id="testActionPropertySubs_proxy" class="org.alfresco.module.org_alfresco_module_rm.capability.RMActionProxyFactoryBean" parent="rmProxyAction" init-method="registerAction"> <bean id="testActionPropertySubs_proxy" class="org.alfresco.module.org_alfresco_module_rm.capability.RMActionProxyFactoryBean" parent="rmProxyAction" init-method="registerAction">
<property name="target"> <property name="target">
@@ -53,6 +58,7 @@
</bean> </bean>
<bean id="testActionPropertySubs" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestActionPropertySubs" parent="rmAction"> <bean id="testActionPropertySubs" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestActionPropertySubs" parent="rmAction">
<property name="allowParameterSubstitutions" value="true"/> <property name="allowParameterSubstitutions" value="true"/>
<property name="auditable" value="false" />
</bean> </bean>
@@ -65,6 +71,7 @@
</bean> </bean>
<bean id="recordOnlyAction" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction2" parent="rmAction"> <bean id="recordOnlyAction" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction2" parent="rmAction">
<property name="publicAction" value="true"/> <property name="publicAction" value="true"/>
<property name="auditable" value="false" />
<property name="applicableKinds"> <property name="applicableKinds">
<list> <list>
<value>RECORD</value> <value>RECORD</value>
@@ -78,6 +85,7 @@
</bean> </bean>
<bean id="recordandFolderOnlyAction" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction2" parent="rmAction"> <bean id="recordandFolderOnlyAction" class="org.alfresco.module.org_alfresco_module_rm.test.util.TestAction2" parent="rmAction">
<property name="publicAction" value="true"/> <property name="publicAction" value="true"/>
<property name="auditable" value="false" />
<property name="applicableKinds"> <property name="applicableKinds">
<list> <list>
<value>RECORD</value> <value>RECORD</value>
@@ -98,6 +106,7 @@
<bean id="rmDelegateAction" class="org.alfresco.module.org_alfresco_module_rm.action.impl.DelegateAction" parent="rmAction"> <bean id="rmDelegateAction" class="org.alfresco.module.org_alfresco_module_rm.action.impl.DelegateAction" parent="rmAction">
<property name="publicAction" value="true"/> <property name="publicAction" value="true"/>
<property name="delegateAction" ref="testDMAction" /> <property name="delegateAction" ref="testDMAction" />
<property name="auditable" value="false" />
<property name="applicableKinds"> <property name="applicableKinds">
<list> <list>
<value>RECORD</value> <value>RECORD</value>