Add module base_user_auth_log
This commit is contained in:
37
base_user_auth_log/README.rst
Normal file
37
base_user_auth_log/README.rst
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||||
|
:alt: License: AGPL-3
|
||||||
|
|
||||||
|
========================
|
||||||
|
User Authentication Logs
|
||||||
|
========================
|
||||||
|
|
||||||
|
This module adds user authentication logs in Odoo. It logs both authentication success and failures.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
The authentication logs can be seen:
|
||||||
|
|
||||||
|
* on the users's form view in the *Auth Logs* tab,
|
||||||
|
* in the menu *Settings > Technical > Security > Authentication Logs*.
|
||||||
|
|
||||||
|
Authentication failure logs are displayed in red. Authentication success logs are displayed in black.
|
||||||
|
|
||||||
|
To have read access to the logs, you need to be part of the *Access Rights* group.
|
||||||
|
|
||||||
|
Bug Tracker
|
||||||
|
===========
|
||||||
|
|
||||||
|
Bugs are tracked on `GitHub Issues
|
||||||
|
<https://github.com/akretion/odoo-usability/issues>`_. In case of trouble, please
|
||||||
|
check there if your issue has already been reported. If you spotted it first,
|
||||||
|
help us smashing it by providing a detailed and welcomed feedback.
|
||||||
|
|
||||||
|
Credits
|
||||||
|
=======
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
3
base_user_auth_log/__init__.py
Normal file
3
base_user_auth_log/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import models
|
||||||
21
base_user_auth_log/__openerp__.py
Normal file
21
base_user_auth_log/__openerp__.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
{
|
||||||
|
'name': 'Users authentification logs',
|
||||||
|
'version': '8.0.1.0.0',
|
||||||
|
'category': 'Tools',
|
||||||
|
'license': 'AGPL-3',
|
||||||
|
'summary': 'Adds users authentication logs',
|
||||||
|
'author': 'Akretion',
|
||||||
|
'website': 'http://www.akretion.com',
|
||||||
|
'depends': ['base'],
|
||||||
|
'data': [
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'views/res_users_auth_log.xml',
|
||||||
|
'views/res_users.xml',
|
||||||
|
'data/ir_cron.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
}
|
||||||
24
base_user_auth_log/data/ir_cron.xml
Normal file
24
base_user_auth_log/data/ir_cron.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<openerp>
|
||||||
|
<data noupdate="1"> <!-- noupdate = 1 for the 'active' field -->
|
||||||
|
|
||||||
|
<record id="purge_auth_log_cron" model="ir.cron">
|
||||||
|
<field name="name">Purge old authentication logs</field>
|
||||||
|
<field name="active" eval="True"/>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">months</field>
|
||||||
|
<field name="numbercall">-1</field> <!-- don't limit the number of calls -->
|
||||||
|
<field name="doall" eval="False"/>
|
||||||
|
<field name="model" eval="'res.users.auth.log'"/>
|
||||||
|
<field name="function" eval="'_purge_old_auth_logs'" />
|
||||||
|
<field name="args" eval="'()'"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
4
base_user_auth_log/models/__init__.py
Normal file
4
base_user_auth_log/models/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import res_users_auth_log
|
||||||
|
from . import res_users
|
||||||
42
base_user_auth_log/models/res_users.py
Normal file
42
base_user_auth_log/models/res_users.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from openerp import models, fields, registry, SUPERUSER_ID
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ResUsers(models.Model):
|
||||||
|
_inherit = 'res.users'
|
||||||
|
|
||||||
|
auth_log_ids = fields.One2many(
|
||||||
|
'res.users.auth.log', 'user_id', string='Authentication Logs')
|
||||||
|
|
||||||
|
def _login(self, db, login, password):
|
||||||
|
user_id = super(ResUsers, self)._login(db, login, password)
|
||||||
|
with registry(db).cursor() as cr:
|
||||||
|
if user_id:
|
||||||
|
result = 'success'
|
||||||
|
else:
|
||||||
|
user_id = None # To write a null value, psycopg2 wants None
|
||||||
|
result = 'failure'
|
||||||
|
cr.execute(
|
||||||
|
"SELECT id FROM res_users WHERE login=%s", (login, ))
|
||||||
|
user_select = cr.fetchall()
|
||||||
|
if user_select:
|
||||||
|
user_id = user_select[0][0]
|
||||||
|
|
||||||
|
cr.execute("""
|
||||||
|
INSERT INTO res_users_auth_log (
|
||||||
|
create_uid,
|
||||||
|
create_date,
|
||||||
|
date,
|
||||||
|
login,
|
||||||
|
result,
|
||||||
|
user_id
|
||||||
|
) VALUES (
|
||||||
|
%s, NOW() AT TIME ZONE 'UTC', NOW() AT TIME ZONE 'UTC',
|
||||||
|
%s, %s, %s)""", (SUPERUSER_ID, login, result, user_id))
|
||||||
|
logger.info('Auth log created for login %s type %s', login, result)
|
||||||
|
return user_id
|
||||||
44
base_user_auth_log/models/res_users_auth_log.py
Normal file
44
base_user_auth_log/models/res_users_auth_log.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from openerp import models, fields, api, _
|
||||||
|
from openerp.exceptions import Warning as UserError
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ResUsersAuthLog(models.Model):
|
||||||
|
_name = 'res.users.auth.log'
|
||||||
|
_description = 'Users Authentication Logs'
|
||||||
|
_order = 'date desc'
|
||||||
|
_rec_name = 'date'
|
||||||
|
|
||||||
|
user_id = fields.Many2one(
|
||||||
|
'res.users', string='User', ondelete='cascade', readonly=True)
|
||||||
|
login = fields.Char(string='Login', readonly=True)
|
||||||
|
date = fields.Datetime(
|
||||||
|
string='Authentication Date', required=True, readonly=True)
|
||||||
|
result = fields.Selection([
|
||||||
|
('success', 'Success'),
|
||||||
|
('failure', 'Failure'),
|
||||||
|
], string='Result', required=True, readonly=True)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
if not self._context.get('authenticate_create'):
|
||||||
|
raise UserError(_(
|
||||||
|
"You cannot manually create an authentication log."))
|
||||||
|
return super(ResUsersAuthLog, self).create(vals)
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def write(self, vals):
|
||||||
|
raise UserError(_("You cannot modify an authentication log."))
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _purge_old_auth_logs(self):
|
||||||
|
expiry_date = datetime.today() - timedelta(days=365)
|
||||||
|
self._cr.execute(
|
||||||
|
"DELETE FROM res_users_auth_log WHERE date <= %s", (expiry_date, ))
|
||||||
|
logger.info('Auth logs older than %s have been purged', expiry_date)
|
||||||
2
base_user_auth_log/security/ir.model.access.csv
Normal file
2
base_user_auth_log/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_res_users_auth_log,Read access to Access rights group,model_res_users_auth_log,base.group_erp_manager,1,0,0,0
|
||||||
|
26
base_user_auth_log/views/res_users.xml
Normal file
26
base_user_auth_log/views/res_users.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="view_users_form" model="ir.ui.view">
|
||||||
|
<field name="name">auth_logs.res.users.form</field>
|
||||||
|
<field name="model">res.users</field>
|
||||||
|
<field name="inherit_id" ref="base.view_users_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<notebook position="inside">
|
||||||
|
<page string="Auth Logs" name="auth_logs">
|
||||||
|
<field name="auth_log_ids" nolabel="1"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
81
base_user_auth_log/views/res_users_auth_log.xml
Normal file
81
base_user_auth_log/views/res_users_auth_log.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="res_users_auth_log_form" model="ir.ui.view">
|
||||||
|
<field name="name">res.users.auth.logs.form</field>
|
||||||
|
<field name="model">res.users.auth.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Authentication Log">
|
||||||
|
<group name="main">
|
||||||
|
<field name="date"/>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="login"/>
|
||||||
|
<field name="result"/>
|
||||||
|
</group>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="res_users_auth_log_tree" model="ir.ui.view">
|
||||||
|
<field name="name">res.users.auth.logs.tree</field>
|
||||||
|
<field name="model">res.users.auth.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Authentication Logs" colors="red:result=='failure'">
|
||||||
|
<field name="date"/>
|
||||||
|
<field name="user_id" invisible="not context.get('auth_logs_main_view')"/>
|
||||||
|
<field name="login" invisible="not context.get('auth_logs_main_view')"/>
|
||||||
|
<field name="result"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="res_users_auth_log_search" model="ir.ui.view">
|
||||||
|
<field name="name">res.users.auth.logs.search</field>
|
||||||
|
<field name="model">res.users.auth.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Search Authentication Logs">
|
||||||
|
<field name="user_id"/>
|
||||||
|
<filter name="success" string="Success" domain="[('result', '=', 'success')]"/>
|
||||||
|
<filter name="failure" string="Failure" domain="[('result', '=', 'failure')]"/>
|
||||||
|
<group string="Group By" name="groupby">
|
||||||
|
<filter name="day_groupby" string="Day" context="{'group_by': 'date:day'}"/>
|
||||||
|
<filter name="week_groupby" string="Week" context="{'group_by': 'date:week'}"/>
|
||||||
|
<filter name="month_groupby" string="Month" context="{'group_by': 'date:month'}"/>
|
||||||
|
<filter name="user_groupby" string="User" context="{'group_by': 'user_id'}"/>
|
||||||
|
<filter name="result_groupby" string="Result" context="{'group_by': 'result'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="res_users_auth_log_graph" model="ir.ui.view">
|
||||||
|
<field name="name">res.users.auth.logs.graph</field>
|
||||||
|
<field name="model">res.users.auth.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<graph string="Analyze Authentication Logs" type="pivot">
|
||||||
|
<field name="date" type="row" interval="week"/>
|
||||||
|
<field name="user_id" type="col"/>
|
||||||
|
</graph>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="res_users_auth_log_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Authentication Logs</field>
|
||||||
|
<field name="res_model">res.users.auth.log</field>
|
||||||
|
<field name="view_mode">tree,form,graph</field>
|
||||||
|
<field name="context">{'auth_logs_main_view': True}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="res_users_auth_log_menu" action="res_users_auth_log_action"
|
||||||
|
parent="base.menu_security" sequence="100"/>
|
||||||
|
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
Reference in New Issue
Block a user