Permalink
Browse files

beginning to do a serious refactor, define more atomic API and define…

… extension points for end users to implement their own take on Audit Logging.
  • Loading branch information...
1 parent f39c12d commit ec561da4836a9287616d62c1b13b96cf7507ca21 @hartsock hartsock committed Jan 24, 2012
@@ -1,6 +1,9 @@
import org.codehaus.groovy.grails.plugins.orm.auditable.AuditLogListener
import org.codehaus.groovy.grails.plugins.orm.auditable.AuditLogListenerUtil
import org.codehaus.groovy.grails.orm.hibernate.HibernateEventListeners
+import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
+import javax.servlet.http.HttpSession
+import org.codehaus.groovy.grails.plugins.orm.auditable.AuditLogConfig
/**
* @author Shawn Hartsock
@@ -88,32 +91,67 @@ Stable Releases:
def doWithSpring = {
if (manager?.hasGrailsPlugin("hibernate")) {
- auditLogListener(AuditLogListener) {
+ setupDefaultActorGetterClosure()
+ auditEventListenerConfig(AuditLogConfig) {
sessionFactory = sessionFactory
verbose = application.config?.auditLog?.verbose ?: false
transactional = application.config?.auditLog?.transactional ?: false
- sessionAttribute = application.config?.auditLog?.sessionAttribute ?: ""
- actorKey = application.config?.auditLog?.actorKey ?: ""
+ // users may specify their own closure for this job
+ actorClosure = application.config?.auditLog?.actorClosure ?: actorDefaultGetter
}
+
+ Class listenerClass = application.config?.auditLogListenerClass ?: AuditLogListener
+ auditLogListener(listenerClass) {
+ configuration = auditEventListenerConfig
+ }
+
//PreDeleteEventListener, PostInsertEventListener, PostUpdateEventListener
hibernateEventListeners(HibernateEventListeners) {
listenerMap = [
'post-insert': auditLogListener,
'post-update': auditLogListener,
- 'pre-delete': auditLogListener,
- 'pre-collection-update': auditLogListener,
- 'pre-collection-remove': auditLogListener,
- 'post-collection-recreate': auditLogListener]
+ 'pre-delete': auditLogListener
+ ]
+ }
+ }
+ else {
+ log.error("Audit Logging Plugin only implements Hibernate!")
+ }
+ }
+
+ private setupDefaultActorGetterClosure() {
+ if (application.config?.auditLog?.sessionAttribute) {
+ actorDefaultGetter = { GrailsWebRequest request, HttpSession session ->
+ log.debug "configured with session attribute ${delegate.sessionAttribute} attempting to resolve"
+ session.getAttribute(application.config?.auditLog?.sessionAttribute)
+ }
+ }
+ else if (application.config?.auditLog?.actorKey) {
+ actorDefaultGetter = { GrailsWebRequest request, HttpSession session ->
+ log.debug "configured with actorKey ${actorKey} resolve using request attributes "
+ AuditLogListenerUtil.resolve(request.getAttributes(),application.config?.auditLog?.actorKey,delegate.log)
+ }
+ }
+ else {
+ actorDefaultGetter = { GrailsWebRequest request, HttpSession session ->
+ def actor = null
+ if(request.remoteUser) {
+ actor = request.remoteUser
+ }
+
+ if(!actor && request.userPrincipal) {
+ actor = request.userPrincipal.getName()
+ }
+ return actor
}
}
}
def doWithApplicationContext = { applicationContext ->
// pulls in the bean to inject and init
AuditLogListener listener = applicationContext.getBean("auditLogListener")
- // allows user to over-ride the maximum length the value stored by the audit logger.
- listener.setActorClosure(application.config?.auditLog?.actorClosure ?: AuditLogListenerUtil.actorDefaultGetter)
listener.init()
+ // allows user to over-ride the maximum length the value stored by the audit logger.
if (application.config?.auditLog?.TRUNCATE_LENGTH) {
listener.truncateLength = new Long(application.config?.auditLog?.TRUNCATE_LENGTH)
}
@@ -136,4 +174,6 @@ Stable Releases:
// TODO Implement code that is executed when any class in a GrailsApplication changes
// the event contain: event.source, event.application and event.applicationContext objects
}
+
+ def actorDefaultGetter
}
View
@@ -1,7 +1,7 @@
#Grails Metadata file
-#Thu Jun 24 15:24:39 EDT 2010
-app.grails.version=1.2.1
+#Fri Jan 20 23:09:59 EST 2012
+app.grails.version=2.0.0
app.name=audit-logging
app.version=0.5.3
-plugins.hibernate=1.2.1
-plugins.tomcat=1.2.1
+plugins.hibernate=2.0.0
+plugins.tomcat=2.0.0
@@ -1,47 +0,0 @@
-package org.codehaus.groovy.grails.plugins.orm.auditable
-
-import org.codehaus.groovy.grails.plugins.orm.auditable.AuditLogEvent
-import org.codehaus.groovy.grails.plugins.orm.auditable.AuditLogEvent
-
-class AuditLogEventController {
-
- def index = { redirect(action: list, params: params) }
-
- // the delete, save and update actions only accept POST requests
- static allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
-
- def list = {
- if (!params.max) params.max = 10
- [auditLogEventInstanceList: AuditLogEvent.list(params), auditLogEventInstanceTotal: AuditLogEvent.count()]
- }
-
- def show = {
- def auditLogEvent = AuditLogEvent.get(params.id)
-
- if (!auditLogEvent) {
- flash.message = "AuditLogEvent not found with id ${params.id}"
- redirect(action: list)
- }
- else { return [auditLogEventInstance: auditLogEvent] }
- }
-
- def delete = {
- redirect(action: list)
- }
-
- def edit = {
- redirect(action: list)
- }
-
- def update = {
- redirect(action: list)
- }
-
- def create = {
- redirect(action: list)
- }
-
- def save = {
- redirect(action: list)
- }
-}
@@ -1,63 +0,0 @@
-
-
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <meta name="layout" content="main" />
- <title>AuditLogEvent List</title>
- </head>
- <body>
- <div class="nav">
- <span class="menuButton"><a class="home" href="${resource(dir:'')}">Home</a></span>
- </div>
- <div class="body">
- <h1>AuditLogEvent List</h1>
- <g:if test="${flash.message}">
- <div class="message">${flash.message}</div>
- </g:if>
- <div class="list">
- <table>
- <thead>
- <tr>
-
- <g:sortableColumn property="id" title="Id" />
-
- <g:sortableColumn property="actor" title="Actor" />
-
- <g:sortableColumn property="uri" title="Uri" />
-
- <g:sortableColumn property="className" title="Class Name" />
-
- <g:sortableColumn property="persistedObjectId" title="Persisted Object Id" />
-
- <g:sortableColumn property="persistedObjectVersion" title="Persisted Object Version" />
-
- </tr>
- </thead>
- <tbody>
- <g:each in="${auditLogEventInstanceList}" status="i" var="auditLogEventInstance">
- <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
-
- <td><g:link action="show" id="${auditLogEventInstance.id}">${fieldValue(bean:auditLogEventInstance, field:'id')}</g:link></td>
-
- <td>${fieldValue(bean:auditLogEventInstance, field:'actor')}</td>
-
- <td>${fieldValue(bean:auditLogEventInstance, field:'uri')}</td>
-
- <td>${fieldValue(bean:auditLogEventInstance, field:'className')}</td>
-
- <td>${fieldValue(bean:auditLogEventInstance, field:'persistedObjectId')}</td>
-
- <td>${fieldValue(bean:auditLogEventInstance, field:'persistedObjectVersion')}</td>
-
- </tr>
- </g:each>
- </tbody>
- </table>
- </div>
- <div class="paginateButtons">
- <g:paginate total="${auditLogEventInstanceTotal}" />
- </div>
- </div>
- </body>
-</html>
@@ -1,113 +0,0 @@
-
-
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <meta name="layout" content="main" />
- <title>Show AuditLogEvent</title>
- </head>
- <body>
- <div class="nav">
- <span class="menuButton"><a class="home" href="${resource(dir:'')}">Home</a></span>
- <span class="menuButton"><g:link class="list" action="list">AuditLogEvent List</g:link></span>
- </div>
- <div class="body">
- <h1>Show AuditLogEvent</h1>
- <g:if test="${flash.message}">
- <div class="message">${flash.message}</div>
- </g:if>
- <div class="dialog">
- <table>
- <tbody>
-
-
- <tr class="prop">
- <td valign="top" class="name">Id:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'id')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Actor:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'actor')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Uri:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'uri')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Class Name:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'className')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Persisted Object Id:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'persistedObjectId')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Persisted Object Version:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'persistedObjectVersion')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Event Name:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'eventName')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Property Name:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'propertyName')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Old Value:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'oldValue')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">New Value:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'newValue')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Date Created:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'dateCreated')}</td>
-
- </tr>
-
- <tr class="prop">
- <td valign="top" class="name">Last Updated:</td>
-
- <td valign="top" class="value">${fieldValue(bean:auditLogEventInstance, field:'lastUpdated')}</td>
-
- </tr>
-
- </tbody>
- </table>
- </div>
- </div>
- </body>
-</html>
@@ -0,0 +1,8 @@
+includeTargets << grailsScript("_GrailsInit")
+
+target(main: "The description of the script goes here!") {
+ // TODO: Implement script here
+ throw new Exception("unimplemented!")
+}
+
+setDefaultTarget(main)
@@ -0,0 +1,14 @@
+package org.codehaus.groovy.grails.plugins.orm.auditable
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: hartsock
+ * Date: 1/23/12
+ * Time: 8:33 PM
+ * To change this template use File | Settings | File Templates.
+ */
+class AuditLogConfig implements AuditEventListenerConfig {
+ boolean verbose
+ boolean transactional
+ Closure actorClosure
+}
Oops, something went wrong.

0 comments on commit ec561da

Please sign in to comment.