Browse Source

Merge pull request #262 from grap/8.0_ADD_auth_track_and_prevent_brut_force

[ADD] auth track and prevent brut force
pull/356/head
Maxime Chambreuil - http://www.savoirfairelinux.com 9 years ago
parent
commit
b403942cdc
  1. 114
      auth_brute_force/README.rst
  2. 3
      auth_brute_force/__init__.py
  3. 42
      auth_brute_force/__openerp__.py
  4. 2
      auth_brute_force/controllers/__init__.py
  5. 104
      auth_brute_force/controllers/controllers.py
  6. 29
      auth_brute_force/data/ir_config_parameter.xml
  7. 150
      auth_brute_force/i18n/auth_brute_force.pot
  8. 120
      auth_brute_force/i18n/fr.po
  9. 3
      auth_brute_force/models/__init__.py
  10. 58
      auth_brute_force/models/res_authentication_attempt.py
  11. 71
      auth_brute_force/models/res_banned_remote.py
  12. 28
      auth_brute_force/security/ir_model_access.yml
  13. BIN
      auth_brute_force/static/description/icon.png
  14. BIN
      auth_brute_force/static/description/screenshot_attempts_list.png
  15. BIN
      auth_brute_force/static/description/screenshot_custom_ban.png
  16. 39
      auth_brute_force/views/action.xml
  17. 32
      auth_brute_force/views/menu.xml
  18. 98
      auth_brute_force/views/view.xml

114
auth_brute_force/README.rst

@ -0,0 +1,114 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License
===============================================================
Tracks Authentication Attempts and Prevents Brute-force Attacks
===============================================================
This module registers each request done by users trying to authenticate into
Odoo. If the authentication fails, a counter is increased for the given remote
IP. After after a defined number of attempts, Odoo will ban the remote IP and
ignore new requests.
This module applies security through obscurity
(https://en.wikipedia.org/wiki/Security_through_obscurity),
When a user is banned, the request is now considered as an attack. So, the UI
will **not** indicate to the user that his IP is banned and the regular message
'Wrong login/password' is displayed.
This module realizes a call to a web API (http://ip-api.com) to try to have
extra informations about remote IP.
Known issue / Roadmap
---------------------
The ID used to identify a remote request is the IP provided in the request
(key 'REMOTE_ADDR').
Depending of server and / or user network configuration, the idenfication
of the user can be wrong, and mainly in the following cases:
* if the Odoo server is behind an Apache / NGinx proxy without redirection,
all the request will be have the value '127.0.0.1' for the REMOTE_ADDR key;
* If some users are behind the same Internet Service Provider, if a user is
banned, all the other users will be banned too;
Configuration
-------------
Once installed, you can change the ir.config_parameter value for the key
'auth_brute_force.max_attempt_qty' (10 by default) that define the max number
of attempts allowed before the user was banned.
Usage
-----
Admin user have the possibility to unblock a banned IP.
Logging
-------
This module generates some WARNING logs, in the three following cases:
* Authentication failed from remote '127.0.0.1'. Login tried : 'admin'.
Attempt 1 / 10.
* Authentication failed from remote '127.0.0.1'. The remote has been banned.
Login tried : 'admin'.
* Authentication tried from remote '127.0.0.1'. The request has been ignored
because the remote has been banned after 10 attempts without success. Login
tried : 'admin'.
Screenshot
----------
**List of Attempts**
.. image:: /auth_brute_force/static/description/screenshot_attempts_list.png
**Detail of a banned IP**
.. image:: /auth_brute_force/static/description/screenshot_custom_ban.png
Usage
=====
* go to ...
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/149/8.0
For further information, please visit:
* https://www.odoo.com/forum/help-1
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/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
`here <https://github.com/OCA/web/issues/new?body=module:%20auth_brute_force%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Sylvain LE GAL (https://twitter.com/legalsylvain)
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.

3
auth_brute_force/__init__.py

@ -0,0 +1,3 @@
# -*- encoding: utf-8 -*-
from . import models
from . import controllers

42
auth_brute_force/__openerp__.py

@ -0,0 +1,42 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Tracks Authentication Attempts and Prevents Brute-force Attacks module
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
#
# 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/>.
#
##############################################################################
{
'name': 'Authentification - Brute-force Attack',
'version': '8.0.1.0.0',
'category': 'base',
'summary': "Tracks Authentication Attempts and Prevents Brute-force"
" Attacks module",
'author': "GRAP,Odoo Community Association (OCA)",
'website': 'http://www.grap.coop',
'license': 'AGPL-3',
'depends': [
'web',
],
'data': [
'security/ir_model_access.yml',
'data/ir_config_parameter.xml',
'views/view.xml',
'views/action.xml',
'views/menu.xml',
],
}

2
auth_brute_force/controllers/__init__.py

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import controllers

104
auth_brute_force/controllers/controllers.py

@ -0,0 +1,104 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Tracks Authentication Attempts and Prevents Brute-force Attacks module
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
#
# 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/>.
#
##############################################################################
import logging
from openerp import fields, http, registry, SUPERUSER_ID
from openerp.http import request
from openerp.addons.web.controllers.main import Home, ensure_db
_logger = logging.getLogger(__name__)
class LoginController(Home):
@http.route()
def web_login(self, redirect=None, **kw):
if request.httprequest.method == 'POST':
ensure_db()
remote = request.httprequest.remote_addr
# Get registry and cursor
config_obj = registry(request.session.db)['ir.config_parameter']
attempt_obj = registry(
request.session.db)['res.authentication.attempt']
banned_remote_obj = registry(
request.session.db)['res.banned.remote']
cursor = attempt_obj.pool.cursor()
# Get Settings
max_attempts_qty = int(config_obj.search_read(
cursor, SUPERUSER_ID,
[('key', '=', 'auth_brute_force.max_attempt_qty')],
['value'])[0]['value'])
# Test if remote user is banned
banned = banned_remote_obj.search(cursor, SUPERUSER_ID, [
('remote', '=', remote)])
if banned:
_logger.warning(
"Authentication tried from remote '%s'. The request has"
" been ignored because the remote has been banned after"
" %d attempts without success. Login tried : '%s'." % (
remote, max_attempts_qty, request.params['login']))
request.params['password'] = ''
else:
# Try to authenticate
result = request.session.authenticate(
request.session.db, request.params['login'],
request.params['password'])
# Log attempt
cursor.commit()
attempt_obj.create(cursor, SUPERUSER_ID, {
'attempt_date': fields.Datetime.now(),
'login': request.params['login'],
'remote': remote,
'result': banned and 'banned' or (
result and 'successfull' or 'failed'),
})
cursor.commit()
if not banned and not result:
# Get last bad attempts quantity
attempts_qty = len(attempt_obj.search_last_failed(
cursor, SUPERUSER_ID, remote))
if max_attempts_qty <= attempts_qty:
# We ban the remote
_logger.warning(
"Authentication failed from remote '%s'. "
"The remote has been banned. Login tried : '%s'." % (
remote, request.params['login']))
banned_remote_obj.create(cursor, SUPERUSER_ID, {
'remote': remote,
'ban_date': fields.Datetime.now(),
})
cursor.commit()
else:
_logger.warning(
"Authentication failed from remote '%s'."
" Login tried : '%s'. Attempt %d / %d." % (
remote, request.params['login'], attempts_qty,
max_attempts_qty))
cursor.close()
return super(LoginController, self).web_login(redirect=redirect, **kw)

29
auth_brute_force/data/ir_config_parameter.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ********************************************************************** -->
<!--Tracks Authentication Attempts and Prevents Brute-force Attacks module -->
<!--Copyright (C) 2015-Today GRAP (http://www.grap.coop) -->
<!--@author Sylvain LE GAL (https://twitter.com/legalsylvain) -->
<!--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/>. -->
<!-- ********************************************************************** -->
<openerp>
<data noupdate="1">
<record id="max_attempt_qty" model="ir.config_parameter">
<field name="key">auth_brute_force.max_attempt_qty</field>
<field name="value">10</field>
</record>
</data>
</openerp>

150
auth_brute_force/i18n/auth_brute_force.pot

@ -0,0 +1,150 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auth_brute_force
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-26 00:39+0000\n"
"PO-Revision-Date: 2015-09-26 00:39+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_banned_remote.py:75
#, python-format
msgid "%s %s - %s %s (ISP: %s)"
msgstr ""
#. module: auth_brute_force
#: field:res.banned.remote,active:0
msgid "Active"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,attempt_date:0
msgid "Attempt Date"
msgstr ""
#. module: auth_brute_force
#: model:ir.actions.act_window,name:auth_brute_force.action_res_authentication_attempt
#: model:ir.ui.menu,name:auth_brute_force.menu_res_authentication_attempt
msgid "Authentication Attempts"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,result:0
msgid "Authentication Result"
msgstr ""
#. module: auth_brute_force
#: field:res.banned.remote,ban_date:0
msgid "Ban Date"
msgstr ""
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_authentication_attempt.py:34
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
#: selection:res.authentication.attempt,result:0
#, python-format
msgid "Banned"
msgstr ""
#. module: auth_brute_force
#: model:ir.actions.act_window,name:auth_brute_force.action_res_banned_remote
#: model:ir.ui.menu,name:auth_brute_force.menu_res_banned_remote
msgid "Banned Remotes"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,create_uid:0
#: field:res.banned.remote,create_uid:0
msgid "Created by"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,create_date:0
#: field:res.banned.remote,create_date:0
msgid "Created on"
msgstr ""
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_authentication_attempt.py:33
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
#: selection:res.authentication.attempt,result:0
#, python-format
msgid "Failed"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,id:0
#: field:res.banned.remote,id:0
msgid "ID"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,write_uid:0
#: field:res.banned.remote,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,write_date:0
#: field:res.banned.remote,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: auth_brute_force
#: field:res.banned.remote,name:0
msgid "Name"
msgstr ""
#. module: auth_brute_force
#: field:res.banned.remote,description:0
msgid "Remote Description"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,remote:0
#: field:res.banned.remote,remote:0
msgid "Remote ID"
msgstr ""
#. module: auth_brute_force
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
msgid "Successful"
msgstr ""
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_authentication_attempt.py:32
#: selection:res.authentication.attempt,result:0
#, python-format
msgid "Successfull"
msgstr ""
#. module: auth_brute_force
#: field:res.authentication.attempt,login:0
msgid "Tried Login"
msgstr ""
#. module: auth_brute_force
#: help:res.banned.remote,active:0
msgid "Uncheck this box to unban the remote"
msgstr ""
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_banned_remote.py:77
#, python-format
msgid "Unidentified Call from %s"
msgstr ""
#. module: auth_brute_force
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
msgid "Without Success"
msgstr ""

120
auth_brute_force/i18n/fr.po

@ -0,0 +1,120 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auth_brute_force
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-26 00:34+0000\n"
"PO-Revision-Date: 2015-09-26 00:34+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_banned_remote.py:75
#, python-format
msgid "%s %s - %s %s (ISP: %s)"
msgstr "%s %s - %s %s (FAI : %s)"
#. module: auth_brute_force
#: field:res.banned.remote,active:0
msgid "Active"
msgstr "Active"
#. module: auth_brute_force
#: field:res.authentication.attempt,attempt_date:0
msgid "Attempt Date"
msgstr "Date de la tentative"
#. module: auth_brute_force
#: model:ir.actions.act_window,name:auth_brute_force.action_res_authentication_attempt
#: model:ir.ui.menu,name:auth_brute_force.menu_res_authentication_attempt
msgid "Authentication Attempts"
msgstr "Tentative d'authentification"
#. module: auth_brute_force
#: field:res.authentication.attempt,result:0
msgid "Authentication Result"
msgstr "Résultat de l'authentification"
#. module: auth_brute_force
#: field:res.banned.remote,ban_date:0
msgid "Ban Date"
msgstr "Ban Date"
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_authentication_attempt.py:34
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
#: selection:res.authentication.attempt,result:0
#, python-format
msgid "Banned"
msgstr "Banni"
#. module: auth_brute_force
#: model:ir.actions.act_window,name:auth_brute_force.action_res_banned_remote
#: model:ir.ui.menu,name:auth_brute_force.menu_res_banned_remote
msgid "Banned Remotes"
msgstr "Clients distants bannis"
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_authentication_attempt.py:33
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
#: selection:res.authentication.attempt,result:0
#, python-format
msgid "Failed"
msgstr "Echoué"
#. module: auth_brute_force
#: field:res.banned.remote,name:0
msgid "Name"
msgstr "Nom"
#. module: auth_brute_force
#: field:res.banned.remote,description:0
msgid "Description"
msgstr "Description"
#. module: auth_brute_force
#: field:res.authentication.attempt,remote:0
#: field:res.banned.remote,remote:0
msgid "Remote ID"
msgstr "ID du client Distant"
#. module: auth_brute_force
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
msgid "Successful"
msgstr "Réussie"
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_authentication_attempt.py:32
#: selection:res.authentication.attempt,result:0
#, python-format
msgid "Successfull"
msgstr "Réussie"
#. module: auth_brute_force
#: field:res.authentication.attempt,login:0
msgid "Tried Login"
msgstr "Idenfiant essayé"
#. module: auth_brute_force
#: help:res.banned.remote,active:0
msgid "Uncheck this box to unban the remote"
msgstr "Décochez cette case afin d'annuler l'exclusion du client distant"
#. module: auth_brute_force
#: code:addons/auth_brute_force/models/res_banned_remote.py:77
#, python-format
msgid "Unidentified Call from %s"
msgstr "Appel non identifié depuis %s"
#. module: auth_brute_force
#: view:res.authentication.attempt:auth_brute_force.view_res_authentication_attempt_search
msgid "Without Success"
msgstr "Sans succès"

3
auth_brute_force/models/__init__.py

@ -0,0 +1,3 @@
# -*- encoding: utf-8 -*-
from . import res_banned_remote
from . import res_authentication_attempt

58
auth_brute_force/models/res_authentication_attempt.py

@ -0,0 +1,58 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Tracks Authentication Attempts and Prevents Brute-force Attacks module
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
#
# 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.tools.translate import _
class ResAuthenticationAttempt(models.Model):
_name = 'res.authentication.attempt'
_order = 'attempt_date desc'
_ATTEMPT_RESULT = [
('successfull', _('Successfull')),
('failed', _('Failed')),
('banned', _('Banned')),
]
# Column Section
attempt_date = fields.Datetime(string='Attempt Date')
login = fields.Char(string='Tried Login')
remote = fields.Char(string='Remote ID')
result = fields.Selection(
selection=_ATTEMPT_RESULT, string='Authentication Result')
# Custom Section
@api.model
def search_last_failed(self, remote):
last_ok = self.search(
[('result', '=', 'successfull'), ('remote', '=', remote)],
order='attempt_date desc', limit=1)
if last_ok:
return self.search([
('remote', '=', remote),
('attempt_date', '>', last_ok.attempt_date)])
else:
return self.search([('remote', '=', remote)])

71
auth_brute_force/models/res_banned_remote.py

@ -0,0 +1,71 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Tracks Authentication Attempts and Prevents Brute-force Attacks module
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
#
# 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/>.
#
##############################################################################
import urllib
import json
from openerp import models, fields, api
class ResBannedRemote(models.Model):
_name = 'res.banned.remote'
_rec_name = 'remote'
_GEOLOCALISATION_URL = "http://ip-api.com/json/{}"
# Default Section
def _default_ban_date(self):
return fields.Datetime.now()
# Column Section
description = fields.Text(
string='Description', compute='_compute_description', store=True)
ban_date = fields.Datetime(
string='Ban Date', required=True, default=_default_ban_date)
remote = fields.Char(string='Remote ID', required=True)
active = fields.Boolean(
string='Active', help="Uncheck this box to unban the remote",
default=True)
attempt_ids = fields.Many2many(
comodel_name='res.authentication.attempt', string='Attempts',
compute='_compute_attempt_ids')
# Compute Section
@api.multi
@api.depends('remote')
def _compute_description(self):
for item in self:
url = self._GEOLOCALISATION_URL.format(item.remote)
res = json.loads(urllib.urlopen(url).read())
item.description = ''
for k, v in res.iteritems():
item.description += '%s : %s\n' % (k, v)
@api.multi
def _compute_attempt_ids(self):
for item in self:
attempt_obj = self.env['res.authentication.attempt']
item.attempt_ids = attempt_obj.search_last_failed(item.remote).ids

28
auth_brute_force/security/ir_model_access.yml

@ -0,0 +1,28 @@
# -*- encoding: utf-8 -*-
- !record {model: ir.model.access, id: access_res_authentication_attempt_all}:
model_id: model_res_authentication_attempt
name: Authentication Attempt All Users
perm_read: true
- !record {model: ir.model.access, id: access_res_banned_remote_all}:
model_id: model_res_banned_remote
name: Banned Remote All Users
perm_read: true
- !record {model: ir.model.access, id: access_res_authentication_attempt_manager}:
group_id: base.group_system
model_id: model_res_authentication_attempt
name: Authentication Attempt Manager
perm_create: true
perm_read: true
perm_write: true
perm_unlink: true
- !record {model: ir.model.access, id: access_res_banned_remote_manager}:
group_id: base.group_system
model_id: model_res_banned_remote
name: Banned Remote Manager
perm_create: true
perm_read: true
perm_write: true
perm_unlink: true

BIN
auth_brute_force/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

BIN
auth_brute_force/static/description/screenshot_attempts_list.png

After

Width: 915  |  Height: 262  |  Size: 29 KiB

BIN
auth_brute_force/static/description/screenshot_custom_ban.png

After

Width: 601  |  Height: 331  |  Size: 31 KiB

39
auth_brute_force/views/action.xml

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ********************************************************************** -->
<!--Tracks Authentication Attempts and Prevents Brute-force Attacks module -->
<!--Copyright (C) 2015-Today GRAP (http://www.grap.coop) -->
<!--@author Sylvain LE GAL (https://twitter.com/legalsylvain) -->
<!--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/>. -->
<!-- ********************************************************************** -->
<openerp>
<data>
<record id="action_res_authentication_attempt" model="ir.actions.act_window">
<field name="name">Authentication Attempts</field>
<field name="res_model">res.authentication.attempt</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="context">{"search_default_filter_no_success":1}</field>
</record>
<record id="action_res_banned_remote" model="ir.actions.act_window">
<field name="name">Banned Remotes</field>
<field name="res_model">res.banned.remote</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
</data>
</openerp>

32
auth_brute_force/views/menu.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ********************************************************************** -->
<!--Tracks Authentication Attempts and Prevents Brute-force Attacks module -->
<!--Copyright (C) 2015-Today GRAP (http://www.grap.coop) -->
<!--@author Sylvain LE GAL (https://twitter.com/legalsylvain) -->
<!--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/>. -->
<!-- ********************************************************************** -->
<openerp>
<data>
<menuitem id="menu_res_authentication_attempt"
parent="base.menu_users"
action="action_res_authentication_attempt"/>
<menuitem id="menu_res_banned_remote"
parent="base.menu_users"
action="action_res_banned_remote"/>
</data>
</openerp>

98
auth_brute_force/views/view.xml

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ********************************************************************** -->
<!--Tracks Authentication Attempts and Prevents Brute-force Attacks module -->
<!--Copyright (C) 2015-Today GRAP (http://www.grap.coop) -->
<!--@author Sylvain LE GAL (https://twitter.com/legalsylvain) -->
<!--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/>. -->
<!-- ********************************************************************** -->
<openerp>
<data>
<!-- Model: res.authentication.attempt -->
<record id="view_res_authentication_attempt_tree" model="ir.ui.view">
<field name="model">res.authentication.attempt</field>
<field name="arch" type="xml">
<tree colors="orange: result == 'failed';red: result == 'banned'">
<field name="attempt_date" />
<field name="remote" />
<field name="login" />
<field name="result" />
</tree>
</field>
</record>
<record id="view_res_authentication_attempt_graph" model="ir.ui.view">
<field name="model">res.authentication.attempt</field>
<field name="arch" type="xml">
<graph>
<field name="attempt_date" />
<field name="result" />
</graph>
</field>
</record>
<record id="view_res_authentication_attempt_search" model="ir.ui.view">
<field name="model">res.authentication.attempt</field>
<field name="arch" type="xml">
<search>
<field name="login"/>
<filter name="filter_no_success" string="Without Success" domain="[('result','!=', 'successfull')]"/>
<filter name="filter_banned" string="Banned" domain="[('result','=', 'banned')]"/>
<filter name="filter_failed" string="Failed" domain="[('result','=', 'failed')]"/>
<filter name="filter_successful" string="Successful" domain="[('result','=', 'successfull')]"/>
</search>
</field>
</record>
<!-- Model: res.banned.remote -->
<record id="view_res_banned_remote_tree" model="ir.ui.view">
<field name="model">res.banned.remote</field>
<field name="arch" type="xml">
<tree colors="gray: active==False">
<field name="remote" />
<field name="ban_date" />
<field name="active" invisible="1" />
</tree>
</field>
</record>
<record id="view_res_banned_remote_form" model="ir.ui.view">
<field name="model">res.banned.remote</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="remote" />
<field name="ban_date" />
<field name="active" />
<field name="description" />
<field name="attempt_ids" />
</group>
</sheet>
</form>
</field>
</record>
<record id="view_res_banned_remote_search" model="ir.ui.view">
<field name="model">res.banned.remote</field>
<field name="arch" type="xml">
<search>
<field name="remote"/>
</search>
</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save