Nociones sobre el servicio de auditado de Alfresco 3.4

Recientemente hemos comenzado en el contexto de un proyecto basado en Alfresco, a utilizar y consumir su renovado servicio de auditado con la finalidad de realizar determinados informes para LOPD (Ley Orgánica de Protección de Datos), de manera similar al modulo de registros DOD5015. Es un servicio muy interesante que nos permite auditar acciones sobre nuestros documentos en determinados entornos con información sensible como ayuntamientos, hospitales o banca. Os dejamos aquí unos primeros apuntes técnicos como consecuencia de nuestras primeras inmersiones en la documentación de este servicio mejorado en la ultima versión de Alfresco ECM.

El servicio de auditado en la versión 3.4 se ha cambiado completamente y está orientado en principio a ser consumido a través de las API's web y no directamente a través de las tablas de auditado en base de datos. La configuración inicial es sencilla y requiere de unos archivos básicos de ejemplo.

En primer lugar en el alfresco-global.properties es necesario habilitarlo (audit.enable=true) y poner en marcha los archivos de ejemplo en el directorio de extensiones (tomcat/shared/classes/alfresco/extension/audit) donde renombramos los archivos .sample a sus correspondientes a .xml (alfresco-audit-example-extractors.xml y alfresco-audit-example-login.xml)

También es recomendable habilitar el modo DEBUG de la información de auditado en el log4j.properties de modo que:

log4j.logger.org.alfresco.repo.audit.inbound=DEBUG log4j.logger.org.alfresco.repo.audit.AuditComponentImpl=DEBUG

tras reiniciar el servidor vamos a consumir algunos datos con el ejemplo de auditado de login y comprobar el tipo de información en el log del contenedor de servlets.

Por defecto también existen algunos webscript de alfresco, que nos permiten realizar querys sobre la información auditada. Estos pueden inspeccionarse a través de las consolas de alfresco. De este modo es posible invocar los siguientes webscripts:

http://localhost:8080/alfresco/service/index/family/Audit

Por ejemplo:

http://localhost:8080/alfresco/service/api/audit/query/AuditExampleLogin1

y de este modo obtener una respuesta en json, que se puede parsear en un postproceso y representar la información de auditado. He creado un pequeño script en python que realiza una conexión autenticada al servidor y consume esta información parseando el archivo de json. Os dejo aquí el script:

import urllib
import urllib2
import simplejson
import getopt, sys
import re

def urlopen_auth_method(theurl, username, password, postdata=''):
    # Auth
    passman  = urllib2.HTTPPasswordMgrWithDefaultRealm()
    passman.add_password(None, theurl, username, password)
    authhandler = urllib2.HTTPBasicAuthHandler(passman)
    opener = urllib2.build_opener(authhandler)
    urllib2.install_opener(opener)
    # Post
    if (postdata):
      f = urllib2.urlopen(theurl, postdata)
    else:
      f = urllib2.urlopen(theurl)
    return f

if __name__ == "__main__":

  # Connection data
  username = 'admin'
  password = 'secret'
 
  try:
    opts, args = getopt.getopt(sys.argv[1:], "lum", ["limit=", "user=", "month="])
  except getopt.GetoptError, err:
    print str(err) # will print something like "option -a not recognized"
    sys.exit(2)

  mes = ""
  url1  = ' http://localhost:8080/alfresco/service/api/audit/query/AuditExampleLogin1?verbose=true'
  for o, a in opts:
    if o in ("-l", "--limit"):
      limit = a
      url1 = url1 + '&limit='+limit
    elif o in ("-u", "--user"):
      user = a
      url1 = url1 + '&user='+user
    elif o in ("-m", "--month"):
      month = a
      mes = "%02d" % eval(a)
      mes = str(mes)
    elif o in ("-h", "--help"):
      sys.exit()
    else:
      assert False, "unhandled option"

  # Auth connection and
  f   = urlopen_auth_method(url1, username, password)
  res = simplejson.loads(f.read())

  comp = re.compile(r"-"+mes+"-")
  if mes:
    aux = 0
    for i in res['entries']:
      if comp.search(i['time']):
        aux = aux + 1
        print i['user'],":", i['time']
    print
    print "Entradas: ", aux
  else: 
    for i in res['entries']:
      print i['user'],":", i['time']
    print
    print "Entradas: ", res['count']


De este modo, una sencilla invocación del script me permite obtener datos de los accesos a mi servidor Alfresco.

Una cosilla que nos hemos encontrado es que el formato json resultante del servicio de auditado (por lo menos en la versión 3.4d de Alfresco Community) no es json valido. No ha sido una tragedia y ha sido necesario un sencillo cambio en el webscript de auditado, poniendo comillas en los campos tipos string una vez comprobado el problema. Esto es en $TOMCAT/webapps/alfresco/WEB-INF/classes/alfresco/templates/webscripts/org/alfresco/repository/audit/query.get.json.ftl quedando de la siguiente manera:

<#escape x as jsonUtils.encodeJSONString(x)>
{
   "count":${count?c},
   "entries":
   [
      <#list entries as entry>
      {
         "id":${entry.id?c},
         "application":"${entry.application}",
         "user":<#if entry.user??>"${entry.user}"<#else>"null"</#if>,
         "time":"${xmldate(entry.time)}",
         "values":
         <#if entry.values??>
         {
             <#assign first=true>
             <#list entry.values?keys as k>
                 <#if entry.values[k]??>
                     <#if !first>,<#else><#assign first=false></#if>"${k}":<#assign value = entry.values[k]>"${value}"
                 </#if>
             </#list>
         }
         <#else>"null"</#if>
      }<#if entry_has_next>,</#if>
      </#list>
   ]
}
</#escape>


De este modo, el json resultante por el servicio de auditado es correcto y por tanto sencillamente parseable desde un lenguaje de programación como python (con el modulo simple json).

00

More Blog Entries

0 Comments