From 0edcd1ac41e8e8d34853cfc202b1c96413ba76f3 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 13 May 2022 13:55:20 +0000 Subject: [PATCH] [IMP] base, auth_totp: log user in case of failed login When a login attempt is ignored, we add the user info for a better understanding on the attack (brute force, credentials stuffing...). closes odoo/odoo#91588 X-original-commit: 0f69448202244e808e1122a618be701806d606cf Signed-off-by: Nicolas Martinelli (nim) --- addons/auth_totp/controllers/home.py | 2 +- odoo/addons/base/models/res_users.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/addons/auth_totp/controllers/home.py b/addons/auth_totp/controllers/home.py index cb97c404f25..40e41eefc0e 100644 --- a/addons/auth_totp/controllers/home.py +++ b/addons/auth_totp/controllers/home.py @@ -37,7 +37,7 @@ class Home(web_home.Home): elif user and request.httprequest.method == 'POST' and kwargs.get('totp_token'): try: - with user._assert_can_auth(): + with user._assert_can_auth(user=user.id): user._totp_check(int(re.sub(r'\s', '', kwargs['totp_token']))) except AccessDenied as e: error = str(e) diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 5baea2ab9e7..733c7b29a97 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -702,7 +702,7 @@ class Users(models.Model): try: with cls.pool.cursor() as cr: self = api.Environment(cr, SUPERUSER_ID, {})[cls._name] - with self._assert_can_auth(): + with self._assert_can_auth(user=login): user = self.search(self._get_login_domain(login), order=self._get_login_order(), limit=1) if not user: raise AccessDenied() @@ -759,7 +759,7 @@ class Users(models.Model): with contextlib.closing(cls.pool.cursor()) as cr: self = api.Environment(cr, uid, {})[cls._name] - with self._assert_can_auth(): + with self._assert_can_auth(user=uid): if not self.env.user.active: raise AccessDenied() self._check_credentials(passwd, {'interactive': False}) @@ -954,7 +954,7 @@ class Users(models.Model): ) @contextlib.contextmanager - def _assert_can_auth(self): + def _assert_can_auth(self, user=None): """ Checks that the current environment even allows the current auth request to happen. @@ -963,6 +963,8 @@ class Users(models.Model): cooldown. During the cooldown period, login *attempts* are ignored and logged. + :param user: user id or login, for logging purpose + .. warning:: The login counter is not shared between workers and not @@ -993,13 +995,13 @@ class Users(models.Model): (failures, previous) = failures_map[source] if self._on_login_cooldown(failures, previous): _logger.warning( - "Login attempt ignored for %s on %s: " + "Login attempt ignored for %s (user %r) on %s: " "%d failures since last success, last failure at %s. " "You can configure the number of login failures before a " "user is put on cooldown as well as the duration in the " "System Parameters. Disable this feature by setting " "\"base.login_cooldown_after\" to 0.", - source, self.env.cr.dbname, failures, previous) + source, user or "?", self.env.cr.dbname, failures, previous) if ipaddress.ip_address(source).is_private: _logger.warning( "The rate-limited IP address %s is classified as private "