From c140c6f52484a4d5efbea9b66a2b4da6e567eda9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Tue, 18 Dec 2018 15:34:15 +0100 Subject: [PATCH] core: better handle MFA BackendFactor failures --- passbook/core/auth/backend_factor.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/passbook/core/auth/backend_factor.py b/passbook/core/auth/backend_factor.py index 56a383db1..9aaef62fd 100644 --- a/passbook/core/auth/backend_factor.py +++ b/passbook/core/auth/backend_factor.py @@ -2,6 +2,9 @@ from logging import getLogger from django.contrib.auth import authenticate +from django.core.exceptions import PermissionDenied +from django.forms.utils import ErrorList +from django.utils.translation import gettext as _ from django.views.generic import FormView from passbook.core.auth.factor import AuthenticationFactor @@ -26,10 +29,21 @@ class AuthenticationBackendFactor(FormView, AuthenticationFactor): } for uid_field in uid_fields: kwargs[uid_field] = getattr(self.authenticator.pending_user, uid_field) - user = authenticate(self.request, **kwargs) - if user: - # User instance returned from authenticate() has .backend property set - self.authenticator.pending_user = user - self.request.session[MultiFactorAuthenticator.SESSION_USER_BACKEND] = user.backend - return self.authenticator.user_ok() - return self.authenticator.user_invalid() + try: + user = authenticate(self.request, **kwargs) + if user: + # User instance returned from authenticate() has .backend property set + self.authenticator.pending_user = user + self.request.session[MultiFactorAuthenticator.SESSION_USER_BACKEND] = user.backend + return self.authenticator.user_ok() + # No user was found -> invalid credentials + LOGGER.debug("Invalid credentials") + # Manually inject error into form + # pylint: disable=protected-access + errors = form._errors.setdefault("password", ErrorList()) + errors.append(_("Invalid password")) + return self.form_invalid(form) + except PermissionDenied: + # User was found, but permission was denied (i.e. user is not active) + LOGGER.debug("Denied access to %s", kwargs) + return self.authenticator.user_invalid()