Module 'auditlog' - Log HTTP user sessions and requests
parent
54a4858fd9
commit
55e8393a9f
|
@ -22,8 +22,6 @@ Known issues / Roadmap
|
||||||
======================
|
======================
|
||||||
|
|
||||||
* log only operations triggered by some users (currently it logs all users)
|
* log only operations triggered by some users (currently it logs all users)
|
||||||
* group logs by HTTP query (thanks to werzeug)?
|
|
||||||
* group HTTP query by user session?
|
|
||||||
|
|
||||||
|
|
||||||
Bug Tracker
|
Bug Tracker
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
'data': [
|
'data': [
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'views/auditlog_view.xml',
|
'views/auditlog_view.xml',
|
||||||
|
'views/http_session_view.xml',
|
||||||
|
'views/http_request_view.xml',
|
||||||
],
|
],
|
||||||
'application': True,
|
'application': True,
|
||||||
'installable': False,
|
'installable': False,
|
||||||
|
|
|
@ -20,4 +20,6 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from . import rule
|
from . import rule
|
||||||
|
from . import http_session
|
||||||
|
from . import http_request
|
||||||
from . import log
|
from . import log
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2015 ABF OSIELL (<http://osiell.com>).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp import models, fields, api
|
||||||
|
from openerp.http import request
|
||||||
|
|
||||||
|
|
||||||
|
class AuditlogHTTPRequest(models.Model):
|
||||||
|
_name = 'auditlog.http.request'
|
||||||
|
_description = u"Auditlog - HTTP request log"
|
||||||
|
_order = "create_date DESC"
|
||||||
|
|
||||||
|
name = fields.Char(u"Path")
|
||||||
|
root_url = fields.Char(u"Root URL")
|
||||||
|
user_id = fields.Many2one(
|
||||||
|
'res.users', string=u"User")
|
||||||
|
http_session_id = fields.Many2one(
|
||||||
|
'auditlog.http.session', string=u"Session")
|
||||||
|
user_context = fields.Char(u"Context")
|
||||||
|
log_ids = fields.One2many(
|
||||||
|
'auditlog.log', 'http_request_id', string=u"Logs")
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def current_http_request(self):
|
||||||
|
"""Create a log corresponding to the current HTTP request, and returns
|
||||||
|
its ID. This method can be called several times during the
|
||||||
|
HTTP query/response cycle, it will only log the request on the
|
||||||
|
first call.
|
||||||
|
If no HTTP request is available, returns `False`.
|
||||||
|
"""
|
||||||
|
http_session_model = self.env['auditlog.http.session']
|
||||||
|
httprequest = request.httprequest
|
||||||
|
if httprequest:
|
||||||
|
if hasattr(httprequest, 'auditlog_http_request_id'):
|
||||||
|
return httprequest.auditlog_http_request_id
|
||||||
|
vals = {
|
||||||
|
'name': httprequest.path,
|
||||||
|
'root_url': httprequest.url_root,
|
||||||
|
'user_id': request.uid,
|
||||||
|
'http_session_id': http_session_model.current_http_session(),
|
||||||
|
'user_context': request.context,
|
||||||
|
}
|
||||||
|
httprequest.auditlog_http_request_id = self.create(vals).id
|
||||||
|
return httprequest.auditlog_http_request_id
|
||||||
|
return False
|
|
@ -0,0 +1,58 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2015 ABF OSIELL (<http://osiell.com>).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp import models, fields, api
|
||||||
|
from openerp.http import request
|
||||||
|
|
||||||
|
|
||||||
|
class AuditlogtHTTPSession(models.Model):
|
||||||
|
_name = 'auditlog.http.session'
|
||||||
|
_description = u"Auditlog - HTTP User session log"
|
||||||
|
_order = "create_date DESC"
|
||||||
|
|
||||||
|
name = fields.Char(u"Session ID")
|
||||||
|
user_id = fields.Many2one(
|
||||||
|
'res.users', string=u"User")
|
||||||
|
http_request_ids = fields.One2many(
|
||||||
|
'auditlog.http.request', 'http_session_id', string=u"HTTP Requests")
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def current_http_session(self):
|
||||||
|
"""Create a log corresponding to the current HTTP user session, and
|
||||||
|
returns its ID. This method can be called several times during the
|
||||||
|
HTTP query/response cycle, it will only log the user session on the
|
||||||
|
first call.
|
||||||
|
If no HTTP user session is available, returns `False`.
|
||||||
|
"""
|
||||||
|
httpsession = request.httpsession
|
||||||
|
if httpsession:
|
||||||
|
existing_session = self.search(
|
||||||
|
[('name', '=', httpsession.sid),
|
||||||
|
('user_id', '=', request.uid)])
|
||||||
|
if existing_session:
|
||||||
|
return existing_session.id
|
||||||
|
vals = {
|
||||||
|
'name': httpsession.sid,
|
||||||
|
'user_id': request.uid,
|
||||||
|
}
|
||||||
|
httpsession.auditlog_http_session_id = self.create(vals).id
|
||||||
|
return httpsession.auditlog_http_session_id
|
||||||
|
return False
|
|
@ -36,6 +36,10 @@ class auditlog_log(models.Model):
|
||||||
method = fields.Char(u"Method", size=64)
|
method = fields.Char(u"Method", size=64)
|
||||||
line_ids = fields.One2many(
|
line_ids = fields.One2many(
|
||||||
'auditlog.log.line', 'log_id', string=u"Fields updated")
|
'auditlog.log.line', 'log_id', string=u"Fields updated")
|
||||||
|
http_session_id = fields.Many2one(
|
||||||
|
'auditlog.http.session', string=u"Session")
|
||||||
|
http_request_id = fields.Many2one(
|
||||||
|
'auditlog.http.request', string=u"HTTP Request")
|
||||||
|
|
||||||
|
|
||||||
class auditlog_log_line(models.Model):
|
class auditlog_log_line(models.Model):
|
||||||
|
|
|
@ -306,6 +306,8 @@ class auditlog_rule(models.Model):
|
||||||
if new_values is None:
|
if new_values is None:
|
||||||
new_values = EMPTY_DICT
|
new_values = EMPTY_DICT
|
||||||
log_model = self.env['auditlog.log']
|
log_model = self.env['auditlog.log']
|
||||||
|
http_request_model = self.env['auditlog.http.request']
|
||||||
|
http_session_model = self.env['auditlog.http.session']
|
||||||
for res_id in res_ids:
|
for res_id in res_ids:
|
||||||
model_model = self.env[res_model]
|
model_model = self.env[res_model]
|
||||||
name = model_model.browse(res_id).name_get()
|
name = model_model.browse(res_id).name_get()
|
||||||
|
@ -316,6 +318,8 @@ class auditlog_rule(models.Model):
|
||||||
'res_id': res_id,
|
'res_id': res_id,
|
||||||
'method': method,
|
'method': method,
|
||||||
'user_id': uid,
|
'user_id': uid,
|
||||||
|
'http_request_id': http_request_model.current_http_request(),
|
||||||
|
'http_session_id': http_session_model.current_http_session(),
|
||||||
}
|
}
|
||||||
vals.update(additional_log_values or {})
|
vals.update(additional_log_values or {})
|
||||||
log = log_model.create(vals)
|
log = log_model.create(vals)
|
||||||
|
|
|
@ -2,7 +2,11 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
access_auditlog_rule_user,auditlog_rule_user,model_auditlog_rule,base.group_user,0,0,0,0
|
access_auditlog_rule_user,auditlog_rule_user,model_auditlog_rule,base.group_user,0,0,0,0
|
||||||
access_auditlog_log_user,auditlog_log_user,model_auditlog_log,base.group_user,0,0,0,0
|
access_auditlog_log_user,auditlog_log_user,model_auditlog_log,base.group_user,0,0,0,0
|
||||||
access_auditlog_log_line_user,auditlog_log_line_user,model_auditlog_log_line,base.group_user,0,0,0,0
|
access_auditlog_log_line_user,auditlog_log_line_user,model_auditlog_log_line,base.group_user,0,0,0,0
|
||||||
|
access_auditlog_http_session_user,auditlog_http_session_user,model_auditlog_http_session,base.group_user,0,0,0,0
|
||||||
|
access_auditlog_http_request_user,auditlog_http_request_user,model_auditlog_http_request,base.group_user,0,0,0,0
|
||||||
|
|
||||||
access_auditlog_rule_manager,auditlog_rule_manager,model_auditlog_rule,base.group_erp_manager,1,1,1,1
|
access_auditlog_rule_manager,auditlog_rule_manager,model_auditlog_rule,base.group_erp_manager,1,1,1,1
|
||||||
access_auditlog_log_manager,auditlog_log_manager,model_auditlog_log,base.group_erp_manager,1,1,1,1
|
access_auditlog_log_manager,auditlog_log_manager,model_auditlog_log,base.group_erp_manager,1,1,1,1
|
||||||
access_auditlog_log_line_manager,auditlog_log_line_manager,model_auditlog_log_line,base.group_erp_manager,1,1,1,1
|
access_auditlog_log_line_manager,auditlog_log_line_manager,model_auditlog_log_line,base.group_erp_manager,1,1,1,1
|
||||||
|
access_auditlog_http_session_manager,auditlog_http_session_manager,model_auditlog_http_session,base.group_erp_manager,1,1,1,1
|
||||||
|
access_auditlog_http_request_manager,auditlog_http_request_manager,model_auditlog_http_request,base.group_erp_manager,1,1,1,1
|
||||||
|
|
|
|
@ -117,6 +117,10 @@
|
||||||
<field name="name" readonly="1"/>
|
<field name="name" readonly="1"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
<group string="HTTP Context">
|
||||||
|
<field name="http_session_id"/>
|
||||||
|
<field name="http_request_id"/>
|
||||||
|
</group>
|
||||||
<group string="Fields updated">
|
<group string="Fields updated">
|
||||||
<field name="line_ids" readonly="1" nolabel="1">
|
<field name="line_ids" readonly="1" nolabel="1">
|
||||||
<form string="Log - Field updated">
|
<form string="Log - Field updated">
|
||||||
|
@ -182,6 +186,12 @@
|
||||||
<filter name="group_by_create_date"
|
<filter name="group_by_create_date"
|
||||||
string="Date"
|
string="Date"
|
||||||
domain="[]" context="{'group_by':'create_date'}"/>
|
domain="[]" context="{'group_by':'create_date'}"/>
|
||||||
|
<filter name="group_by_http_session"
|
||||||
|
string="User session"
|
||||||
|
domain="[]" context="{'group_by':'http_session_id'}"/>
|
||||||
|
<filter name="group_by_http_request"
|
||||||
|
string="HTTP Request"
|
||||||
|
domain="[]" context="{'group_by':'http_request_id'}"/>
|
||||||
</group>
|
</group>
|
||||||
</search>
|
</search>
|
||||||
</field>
|
</field>
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record id="view_auditlog_http_request_form" model="ir.ui.view">
|
||||||
|
<field name="name">auditlog.http.request.form</field>
|
||||||
|
<field name="model">auditlog.http.request</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="HTTP Request">
|
||||||
|
<sheet>
|
||||||
|
<group string="HTTP Request">
|
||||||
|
<field name="root_url"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="create_date"/>
|
||||||
|
</group>
|
||||||
|
<group string="User session">
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="http_session_id"/>
|
||||||
|
<field name="user_context"/>
|
||||||
|
</group>
|
||||||
|
<group string="Logs">
|
||||||
|
<field name="log_ids" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_auditlog_http_request_tree" model="ir.ui.view">
|
||||||
|
<field name="name">auditlog.http.request.tree</field>
|
||||||
|
<field name="model">auditlog.http.request</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="HTTP Requests">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="create_date"/>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="http_session_id"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_auditlog_http_request_search" model="ir.ui.view">
|
||||||
|
<field name="name">auditlog.http.request.search</field>
|
||||||
|
<field name="model">auditlog.http.request</field>
|
||||||
|
<field name="type">search</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="HTTP Requests">
|
||||||
|
<field name="create_date"/>
|
||||||
|
<field name="root_url"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="http_session_id"/>
|
||||||
|
<group expand="0" string="Group By...">
|
||||||
|
<filter name="group_by_root_url"
|
||||||
|
string="Root URL"
|
||||||
|
domain="[]" context="{'group_by':'root_url'}"/>
|
||||||
|
<filter name="group_by_name"
|
||||||
|
string="Path"
|
||||||
|
domain="[]" context="{'group_by':'name'}"/>
|
||||||
|
<filter name="group_by_create_date"
|
||||||
|
string="Created on"
|
||||||
|
domain="[]" context="{'group_by':'create_date'}"/>
|
||||||
|
<filter name="group_by_user_id"
|
||||||
|
string="User"
|
||||||
|
domain="[]" context="{'group_by':'user_id'}"/>
|
||||||
|
<filter name="group_by_http_session_id"
|
||||||
|
string="User session"
|
||||||
|
domain="[]" context="{'group_by':'http_session_id'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="action_auditlog_http_request_tree">
|
||||||
|
<field name="name">HTTP Requests</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">auditlog.http.request</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_id" ref="view_auditlog_http_request_tree"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="menu_action_auditlog_http_request_tree"
|
||||||
|
parent="menu_audit"
|
||||||
|
action="action_auditlog_http_request_tree"/>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record id="view_auditlog_http_session_form" model="ir.ui.view">
|
||||||
|
<field name="name">auditlog.http.session.form</field>
|
||||||
|
<field name="model">auditlog.http.session</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="User session">
|
||||||
|
<sheet>
|
||||||
|
<group string="User session">
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="create_date"/>
|
||||||
|
</group>
|
||||||
|
<group string="HTTP Requests">
|
||||||
|
<field name="http_request_ids" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_auditlog_http_session_tree" model="ir.ui.view">
|
||||||
|
<field name="name">auditlog.http.session.tree</field>
|
||||||
|
<field name="model">auditlog.http.session</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="User sessions">
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="create_date"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_auditlog_http_session_search" model="ir.ui.view">
|
||||||
|
<field name="name">auditlog.http.session.search</field>
|
||||||
|
<field name="model">auditlog.http.session</field>
|
||||||
|
<field name="type">search</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="User sessions">
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="create_date"/>
|
||||||
|
<group expand="0" string="Group By...">
|
||||||
|
<filter name="group_by_user_id"
|
||||||
|
string="User"
|
||||||
|
domain="[]" context="{'group_by':'user_id'}"/>
|
||||||
|
<filter name="group_by_create_date"
|
||||||
|
string="Created on"
|
||||||
|
domain="[]" context="{'group_by':'create_date'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="action_auditlog_http_session_tree">
|
||||||
|
<field name="name">User sessions</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">auditlog.http.session</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_id" ref="view_auditlog_http_session_tree"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="menu_action_auditlog_http_session_tree"
|
||||||
|
parent="menu_audit"
|
||||||
|
action="action_auditlog_http_session_tree"/>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
Loading…
Reference in New Issue