core: mfa cleanup session after successful login
This commit is contained in:
parent
c140c6f524
commit
0c53a95b06
|
@ -3,7 +3,7 @@ from logging import getLogger
|
|||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import login
|
||||
from django.http import Http404
|
||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||
from django.shortcuts import get_object_or_404, redirect, reverse
|
||||
from django.views.generic import View
|
||||
|
||||
|
@ -13,7 +13,8 @@ from passbook.lib.utils.reflection import class_to_path, path_to_class
|
|||
|
||||
LOGGER = getLogger(__name__)
|
||||
|
||||
class MultiFactorAuthenticator(View):
|
||||
|
||||
class MultiFactorAuthenticator(UserPassesTestMixin, View):
|
||||
"""Wizard-like Multi-factor authenticator"""
|
||||
|
||||
SESSION_FACTOR = 'passbook_factor'
|
||||
|
@ -28,13 +29,23 @@ class MultiFactorAuthenticator(View):
|
|||
|
||||
_current_factor = None
|
||||
|
||||
# Allow only not authenticated users to login
|
||||
def test_func(self):
|
||||
return self.request.user.is_authenticated is False
|
||||
|
||||
def handle_no_permission(self):
|
||||
if 'next' in self.request.GET:
|
||||
return redirect(self.request.GET.get('next'))
|
||||
return redirect(reverse('passbook_core:overview'))
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# Extract pending user from session (only remember uid)
|
||||
if MultiFactorAuthenticator.SESSION_PENDING_USER in request.session:
|
||||
self.pending_user = get_object_or_404(
|
||||
User, id=self.request.session[MultiFactorAuthenticator.SESSION_PENDING_USER])
|
||||
else:
|
||||
raise Http404
|
||||
# No Pending user, redirect to login screen
|
||||
return redirect(reverse('passbook_core:auth-login'))
|
||||
# Write pending factors to session
|
||||
if MultiFactorAuthenticator.SESSION_PENDING_FACTORS in request.session:
|
||||
self.pending_factors = request.session[MultiFactorAuthenticator.SESSION_PENDING_FACTORS]
|
||||
|
@ -80,7 +91,8 @@ class MultiFactorAuthenticator(View):
|
|||
return self._user_passed()
|
||||
|
||||
def user_invalid(self):
|
||||
"""Show error message, user could not be authenticated"""
|
||||
"""Show error message, user cannot login.
|
||||
This should only be shown if user authenticated successfully, but is disabled/locked/etc"""
|
||||
LOGGER.debug("User invalid")
|
||||
return redirect(reverse('passbook_core:mfa-denied'))
|
||||
|
||||
|
@ -90,7 +102,18 @@ class MultiFactorAuthenticator(View):
|
|||
backend = self.request.session[MultiFactorAuthenticator.SESSION_USER_BACKEND]
|
||||
login(self.request, self.pending_user, backend=backend)
|
||||
LOGGER.debug("Logged in user %s", self.pending_user)
|
||||
# Cleanup
|
||||
self._cleanup()
|
||||
return redirect(reverse('passbook_core:overview'))
|
||||
|
||||
def _cleanup(self):
|
||||
"""Remove temporary data from session"""
|
||||
session_keys = ['SESSION_FACTOR', 'SESSION_PENDING_FACTORS',
|
||||
'SESSION_PENDING_USER', 'SESSION_USER_BACKEND', ]
|
||||
for key in session_keys:
|
||||
if key in self.request.session:
|
||||
del self.request.session[key]
|
||||
LOGGER.debug("Cleaned up sessions")
|
||||
|
||||
class MFAPermissionDeniedView(PermissionDeniedView):
|
||||
"""User could not be authenticated"""
|
||||
|
|
Reference in New Issue