You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
3.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2015 GRAP - Sylvain LE GAL
  3. # Copyright 2017 Tecnativa - David Vidal
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. import logging
  6. from odoo import fields, http, registry, SUPERUSER_ID
  7. from odoo.api import Environment
  8. from odoo.http import request
  9. from odoo.addons.web.controllers.main import Home, ensure_db
  10. _logger = logging.getLogger(__name__)
  11. class LoginController(Home):
  12. @http.route()
  13. def web_login(self, redirect=None, **kw):
  14. if request.httprequest.method == 'POST':
  15. ensure_db()
  16. remote = request.httprequest.remote_addr
  17. # Get registry and cursor
  18. with registry(request.session.db).cursor() as cursor:
  19. env = Environment(cursor, SUPERUSER_ID, {})
  20. config_obj = env['ir.config_parameter']
  21. attempt_obj = env['res.authentication.attempt']
  22. banned_remote_obj = env['res.banned.remote']
  23. # Get Settings
  24. max_attempts_qty = int(config_obj.get_param(
  25. 'auth_brute_force.max_attempt_qty'))
  26. # Test if remote user is banned
  27. banned = banned_remote_obj.search([('remote', '=', remote)])
  28. if banned:
  29. request.params['password'] = ''
  30. _logger.warning(
  31. "Authentication tried from remote '%s'. The request "
  32. "has been ignored because the remote has been banned "
  33. "after %d attempts without success. Login tried : '%s'"
  34. "." % (remote, max_attempts_qty,
  35. request.params['login']))
  36. else:
  37. # Try to authenticate
  38. result = request.session.authenticate(
  39. request.session.db, request.params['login'],
  40. request.params['password'])
  41. # Log attempt
  42. attempt_obj.create({
  43. 'attempt_date': fields.Datetime.now(),
  44. 'login': request.params['login'],
  45. 'remote': remote,
  46. 'result': banned and 'banned' or (
  47. result and 'successfull' or 'failed'),
  48. })
  49. cursor.commit()
  50. if not banned and not result:
  51. # Get last bad attempts quantity
  52. attempts_qty = len(attempt_obj.search_last_failed(remote))
  53. if max_attempts_qty <= attempts_qty:
  54. # We ban the remote
  55. _logger.warning(
  56. "Authentication failed from remote '%s'. "
  57. "The remote has been banned. Login tried : '%s'"
  58. "." % (remote, request.params['login']))
  59. banned_remote_obj.sudo().create({
  60. 'remote': remote,
  61. 'ban_date': fields.Datetime.now(),
  62. })
  63. cursor.commit()
  64. else:
  65. _logger.warning(
  66. "Authentication failed from remote '%s'."
  67. " Login tried : '%s'. Attempt %d / %d." % (
  68. remote, request.params['login'], attempts_qty,
  69. max_attempts_qty))
  70. return super(LoginController, self).web_login(redirect=redirect, **kw)