RM-886: Audit Log. Filters are applied only on displayed entries.

RM-870: Audit UI layout is incorrect
RM-889: Audit cannot be filtered by property values after rename file
RM-838: Searching for audit logs by event doesn't work for some event types



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@54809 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2013-09-03 05:10:11 +00:00
parent 74eaebf9f5
commit c8b7aa3a2d
2 changed files with 103 additions and 97 deletions

View File

@@ -37,33 +37,7 @@ public interface RecordsManagementAuditService extends RecordsManagementAuditSer
{ {
public enum ReportFormat { HTML, JSON } public enum ReportFormat { HTML, JSON }
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_APPLICATION_NAME = "RM";
public static final String RM_AUDIT_PATH_ROOT = "/RM";
public static final String RM_AUDIT_SNIPPET_EVENT = "/event";
public static final String RM_AUDIT_SNIPPET_PERSON = "/person";
public static final String RM_AUDIT_SNIPPET_NAME = "/name";
public static final String RM_AUDIT_SNIPPET_NODE = "/node";
public static final String RM_AUDIT_SNIPPET_CHANGES = "/changes";
public static final String RM_AUDIT_SNIPPET_BEFORE = "/before";
public static final String RM_AUDIT_SNIPPET_AFTER = "/after";
public static final String RM_AUDIT_DATA_PERSON_FULLNAME = "/RM/event/person/fullName";
public static final String RM_AUDIT_DATA_PERSON_ROLES = "/RM/event/person/roles";
public static final String RM_AUDIT_DATA_EVENT_NAME = "/RM/event/name/value";
public static final String RM_AUDIT_DATA_NODE_NODEREF = "/RM/event/node/noderef";
public static final String RM_AUDIT_DATA_NODE_NAME = "/RM/event/node/name";
public static final String RM_AUDIT_DATA_NODE_TYPE = "/RM/event/node/type";
public static final String RM_AUDIT_DATA_NODE_IDENTIFIER = "/RM/event/node/identifier";
public static final String RM_AUDIT_DATA_NODE_NAMEPATH = "/RM/event/node/namePath";
public static final String RM_AUDIT_DATA_NODE_CHANGES_BEFORE = "/RM/event/node/changes/before/value";
public static final String RM_AUDIT_DATA_NODE_CHANGES_AFTER = "/RM/event/node/changes/after/value";
public static final String RM_AUDIT_DATA_LOGIN_USERNAME = "/RM/login/args/userName/value";
public static final String RM_AUDIT_DATA_LOGIN_FULLNAME = "/RM/login/no-error/fullName";
public static final String RM_AUDIT_DATA_LOGIN_ERROR = "/RM/login/error/value";
/** /**
* Retrieves a list of audit events. * Retrieves a list of audit events.

View File

@@ -97,6 +97,34 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
private static Log logger = LogFactory.getLog(RecordsManagementAuditServiceImpl.class); private static Log logger = LogFactory.getLog(RecordsManagementAuditServiceImpl.class);
private static final String KEY_RM_AUDIT_NODE_RECORDS = "RMAUditNodeRecords"; private static final String KEY_RM_AUDIT_NODE_RECORDS = "RMAUditNodeRecords";
protected static final String RM_AUDIT_EVENT_LOGIN_SUCCESS = "Login.Success";
protected static final String RM_AUDIT_EVENT_LOGIN_FAILURE = "Login.Failure";
protected static final String RM_AUDIT_APPLICATION_NAME = "RM";
protected static final String RM_AUDIT_PATH_ROOT = "/RM";
protected static final String RM_AUDIT_SNIPPET_EVENT = "/event";
protected static final String RM_AUDIT_SNIPPET_PERSON = "/person";
protected static final String RM_AUDIT_SNIPPET_NAME = "/name";
protected static final String RM_AUDIT_SNIPPET_NODE = "/node";
protected static final String RM_AUDIT_SNIPPET_CHANGES = "/changes";
protected static final String RM_AUDIT_SNIPPET_BEFORE = "/before";
protected static final String RM_AUDIT_SNIPPET_AFTER = "/after";
protected static final String RM_AUDIT_DATA_PERSON_FULLNAME = "/RM/event/person/fullName";
protected static final String RM_AUDIT_DATA_PERSON_ROLES = "/RM/event/person/roles";
protected static final String RM_AUDIT_DATA_EVENT_NAME = "/RM/event/name/value";
protected static final String RM_AUDIT_DATA_NODE_NODEREF = "/RM/event/node/noderef";
protected static final String RM_AUDIT_DATA_NODE_NAME = "/RM/event/node/name";
protected static final String RM_AUDIT_DATA_NODE_TYPE = "/RM/event/node/type";
protected static final String RM_AUDIT_DATA_NODE_IDENTIFIER = "/RM/event/node/identifier";
protected static final String RM_AUDIT_DATA_NODE_NAMEPATH = "/RM/event/node/namePath";
protected static final String RM_AUDIT_DATA_NODE_CHANGES_BEFORE = "/RM/event/node/changes/before/value";
protected static final String RM_AUDIT_DATA_NODE_CHANGES_AFTER = "/RM/event/node/changes/after/value";
protected static final String RM_AUDIT_DATA_LOGIN_USERNAME = "/RM/login/args/userName/value";
protected static final String RM_AUDIT_DATA_LOGIN_FULLNAME = "/RM/login/no-error/fullName";
protected static final String RM_AUDIT_DATA_LOGIN_ERROR = "/RM/login/error/value";
protected static final String AUDIT_TRAIL_FILE_PREFIX = "audit_"; protected static final String AUDIT_TRAIL_FILE_PREFIX = "audit_";
protected static final String AUDIT_TRAIL_JSON_FILE_SUFFIX = ".json"; protected static final String AUDIT_TRAIL_JSON_FILE_SUFFIX = ".json";
@@ -283,8 +311,8 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
// TODO use file plan to scope audit log // TODO use file plan to scope audit log
return auditService.isAuditEnabled( return auditService.isAuditEnabled(
RecordsManagementAuditService.RM_AUDIT_APPLICATION_NAME, RM_AUDIT_APPLICATION_NAME,
RecordsManagementAuditService.RM_AUDIT_PATH_ROOT); RM_AUDIT_PATH_ROOT);
} }
/** /**
@@ -296,8 +324,8 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
// TODO use file plan to scope audit log // TODO use file plan to scope audit log
auditService.enableAudit( auditService.enableAudit(
RecordsManagementAuditService.RM_AUDIT_APPLICATION_NAME, RM_AUDIT_APPLICATION_NAME,
RecordsManagementAuditService.RM_AUDIT_PATH_ROOT); RM_AUDIT_PATH_ROOT);
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
{ {
@@ -318,8 +346,8 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
auditEvent(filePlan, AUDIT_EVENT_STOP, null, null, true); auditEvent(filePlan, AUDIT_EVENT_STOP, null, null, true);
auditService.disableAudit( auditService.disableAudit(
RecordsManagementAuditService.RM_AUDIT_APPLICATION_NAME, RM_AUDIT_APPLICATION_NAME,
RecordsManagementAuditService.RM_AUDIT_PATH_ROOT); RM_AUDIT_PATH_ROOT);
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
{ {
@@ -336,7 +364,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
ParameterCheck.mandatory("filePlan", filePlan); ParameterCheck.mandatory("filePlan", filePlan);
// TODO use file plan to scope audit log // TODO use file plan to scope audit log
auditService.clearAudit(RecordsManagementAuditService.RM_AUDIT_APPLICATION_NAME, null, null); auditService.clearAudit(RM_AUDIT_APPLICATION_NAME, null, null);
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
{ {
logger.debug("Records Management audit log has been cleared"); logger.debug("Records Management audit log has been cleared");
@@ -398,7 +426,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
if (immediate == true) if (immediate == true)
{ {
Map<String, Serializable> auditMap = buildAuditMap(nodeRef, eventName, before, after); Map<String, Serializable> auditMap = buildAuditMap(nodeRef, eventName, before, after);
auditComponent.recordAuditValues(RecordsManagementAuditService.RM_AUDIT_PATH_ROOT, auditMap); auditComponent.recordAuditValues(RM_AUDIT_PATH_ROOT, auditMap);
} }
else else
{ {
@@ -428,16 +456,16 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
Map<String, Serializable> auditMap = new HashMap<String, Serializable>(13); Map<String, Serializable> auditMap = new HashMap<String, Serializable>(13);
auditMap.put( auditMap.put(
AuditApplication.buildPath( AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT, RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NAME), RM_AUDIT_SNIPPET_NAME),
eventName); eventName);
if (nodeRef != null) if (nodeRef != null)
{ {
auditMap.put( auditMap.put(
AuditApplication.buildPath( AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT, RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE), RM_AUDIT_SNIPPET_NODE),
nodeRef); nodeRef);
} }
@@ -445,17 +473,17 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
Pair<Map<QName, Serializable>, Map<QName, Serializable>> deltaPair = PropertyMap.getBeforeAndAfterMapsForChanges(propertiesBefore, propertiesAfter); Pair<Map<QName, Serializable>, Map<QName, Serializable>> deltaPair = PropertyMap.getBeforeAndAfterMapsForChanges(propertiesBefore, propertiesAfter);
auditMap.put( auditMap.put(
AuditApplication.buildPath( AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT, RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE, RM_AUDIT_SNIPPET_NODE,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES, RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_BEFORE), RM_AUDIT_SNIPPET_BEFORE),
(Serializable) deltaPair.getFirst()); (Serializable) deltaPair.getFirst());
auditMap.put( auditMap.put(
AuditApplication.buildPath( AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT, RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE, RM_AUDIT_SNIPPET_NODE,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES, RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_AFTER), RM_AUDIT_SNIPPET_AFTER),
(Serializable) deltaPair.getSecond()); (Serializable) deltaPair.getSecond());
return auditMap; return auditMap;
@@ -529,7 +557,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
{ {
logger.debug("RM Audit: Auditing values: \n" + auditMap); logger.debug("RM Audit: Auditing values: \n" + auditMap);
} }
auditMap = auditComponent.recordAuditValues(RecordsManagementAuditService.RM_AUDIT_PATH_ROOT, auditMap); auditMap = auditComponent.recordAuditValues(RM_AUDIT_PATH_ROOT, auditMap);
if (auditMap.isEmpty()) if (auditMap.isEmpty())
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@@ -676,7 +704,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
Map<QName, Serializable> beforeProperties = null; Map<QName, Serializable> beforeProperties = null;
Map<QName, Serializable> afterProperties = null; Map<QName, Serializable> afterProperties = null;
if (values.containsKey(RecordsManagementAuditService.RM_AUDIT_DATA_EVENT_NAME)) if (values.containsKey(RM_AUDIT_DATA_EVENT_NAME))
{ {
// This data is /RM/event/... // This data is /RM/event/...
eventName = (String) values.get(RM_AUDIT_DATA_EVENT_NAME); eventName = (String) values.get(RM_AUDIT_DATA_EVENT_NAME);
@@ -698,18 +726,18 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
nodeType = (typeDef != null) ? typeDef.getTitle(dictionaryService) : null; nodeType = (typeDef != null) ? typeDef.getTitle(dictionaryService) : null;
} }
} }
else if (values.containsKey(RecordsManagementAuditService.RM_AUDIT_DATA_LOGIN_USERNAME)) else if (values.containsKey(RM_AUDIT_DATA_LOGIN_USERNAME))
{ {
user = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_LOGIN_USERNAME); user = (String) values.get(RM_AUDIT_DATA_LOGIN_USERNAME);
if (values.containsKey(RecordsManagementAuditService.RM_AUDIT_DATA_LOGIN_ERROR)) if (values.containsKey(RM_AUDIT_DATA_LOGIN_ERROR))
{ {
eventName = RecordsManagementAuditService.RM_AUDIT_EVENT_LOGIN_FAILURE; eventName = RM_AUDIT_EVENT_LOGIN_FAILURE;
fullName = user; // The user didn't log in fullName = user; // The user didn't log in
} }
else else
{ {
eventName = RecordsManagementAuditService.RM_AUDIT_EVENT_LOGIN_SUCCESS; eventName = RM_AUDIT_EVENT_LOGIN_SUCCESS;
fullName = (String) values.get(RecordsManagementAuditService.RM_AUDIT_DATA_LOGIN_FULLNAME); fullName = (String) values.get(RM_AUDIT_DATA_LOGIN_FULLNAME);
} }
} }
else else
@@ -723,21 +751,21 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
return true; return true;
} }
// filter out events if set // // filter out events if set
if (params.getEvent() != null && // if (params.getEvent() != null &&
params.getEvent().endsWith(eventName) == false) // params.getEvent().endsWith(eventName) == false)
{ // {
// skip it // // skip it
return true; // return true;
} // }
//
//
if (params.getProperty() != null && // if (params.getProperty() != null &&
getChangedProperties(beforeProperties, afterProperties).contains(params.getProperty()) == false) // getChangedProperties(beforeProperties, afterProperties).contains(params.getProperty()) == false)
{ // {
// skip it // // skip it
return false; // return false;
} // }
// TODO: Refactor this to use the builder pattern // TODO: Refactor this to use the builder pattern
RecordsManagementAuditEntry entry = new RecordsManagementAuditEntry( RecordsManagementAuditEntry entry = new RecordsManagementAuditEntry(
@@ -771,31 +799,31 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
return true; return true;
} }
private List<QName> getChangedProperties(Map<QName, Serializable> beforeProperties, Map<QName, Serializable> afterProperties) // private List<QName> getChangedProperties(Map<QName, Serializable> beforeProperties, Map<QName, Serializable> afterProperties)
{ // {
List<QName> changedProperties = new ArrayList<QName>(21); // List<QName> changedProperties = new ArrayList<QName>(21);
//
if (beforeProperties != null && afterProperties != null) // if (beforeProperties != null && afterProperties != null)
{ // {
// add all the properties present before the audited action // // add all the properties present before the audited action
for (QName valuePropName : beforeProperties.keySet()) // for (QName valuePropName : beforeProperties.keySet())
{ // {
changedProperties.add(valuePropName); // changedProperties.add(valuePropName);
} // }
//
// add all the properties present after the audited action that // // add all the properties present after the audited action that
// have not already been added // // have not already been added
for (QName valuePropName : afterProperties.keySet()) // for (QName valuePropName : afterProperties.keySet())
{ // {
if (!beforeProperties.containsKey(valuePropName)) // if (!beforeProperties.containsKey(valuePropName))
{ // {
changedProperties.add(valuePropName); // changedProperties.add(valuePropName);
} // }
} // }
} // }
//
return changedProperties; // return changedProperties;
} // }
private void writeEntryToFile(RecordsManagementAuditEntry entry) private void writeEntryToFile(RecordsManagementAuditEntry entry)
{ {
@@ -854,13 +882,17 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
// Build audit query parameters // Build audit query parameters
AuditQueryParameters auditQueryParams = new AuditQueryParameters(); AuditQueryParameters auditQueryParams = new AuditQueryParameters();
auditQueryParams.setForward(forward); auditQueryParams.setForward(forward);
auditQueryParams.setApplicationName(RecordsManagementAuditService.RM_AUDIT_APPLICATION_NAME); auditQueryParams.setApplicationName(RM_AUDIT_APPLICATION_NAME);
auditQueryParams.setUser(user); auditQueryParams.setUser(user);
auditQueryParams.setFromTime(fromTime); auditQueryParams.setFromTime(fromTime);
auditQueryParams.setToTime(toTime); auditQueryParams.setToTime(toTime);
if (nodeRef != null) if (nodeRef != null)
{ {
auditQueryParams.addSearchKey(RecordsManagementAuditService.RM_AUDIT_DATA_NODE_NODEREF, nodeRef); auditQueryParams.addSearchKey(RM_AUDIT_DATA_NODE_NODEREF, nodeRef);
}
else if (params.getEvent() != null)
{
auditQueryParams.addSearchKey(RM_AUDIT_DATA_EVENT_NAME, params.getEvent());
} }
// Get audit entries // Get audit entries
auditService.auditQuery(callback, auditQueryParams, maxEntries); auditService.auditQuery(callback, auditQueryParams, maxEntries);