cleanup, fix Permission Denied when Cancelling login, fix display of messages on login template
This commit is contained in:
parent
07f5dce97a
commit
da5568b571
|
@ -9,6 +9,7 @@ from django.views.generic import View
|
||||||
from passbook.core.models import Factor, User
|
from passbook.core.models import Factor, User
|
||||||
from passbook.core.views.utils import PermissionDeniedView
|
from passbook.core.views.utils import PermissionDeniedView
|
||||||
from passbook.lib.utils.reflection import class_to_path, path_to_class
|
from passbook.lib.utils.reflection import class_to_path, path_to_class
|
||||||
|
from passbook.lib.utils.urls import is_url_absolute
|
||||||
|
|
||||||
LOGGER = getLogger(__name__)
|
LOGGER = getLogger(__name__)
|
||||||
|
|
||||||
|
@ -39,7 +40,6 @@ class AuthenticationView(UserPassesTestMixin, View):
|
||||||
return redirect(reverse('passbook_core:overview'))
|
return redirect(reverse('passbook_core:overview'))
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
print(request.session.keys())
|
|
||||||
# Extract pending user from session (only remember uid)
|
# Extract pending user from session (only remember uid)
|
||||||
if AuthenticationView.SESSION_PENDING_USER in request.session:
|
if AuthenticationView.SESSION_PENDING_USER in request.session:
|
||||||
self.pending_user = get_object_or_404(
|
self.pending_user = get_object_or_404(
|
||||||
|
@ -122,7 +122,9 @@ class AuthenticationView(UserPassesTestMixin, View):
|
||||||
LOGGER.debug("Logged in user %s", self.pending_user)
|
LOGGER.debug("Logged in user %s", self.pending_user)
|
||||||
# Cleanup
|
# Cleanup
|
||||||
self._cleanup()
|
self._cleanup()
|
||||||
# TODO: ?next=...
|
next_param = self.request.GET.get('next', None)
|
||||||
|
if next_param and is_url_absolute(next_param):
|
||||||
|
return redirect(next_param)
|
||||||
return redirect(reverse('passbook_core:overview'))
|
return redirect(reverse('passbook_core:overview'))
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
|
@ -132,7 +134,6 @@ class AuthenticationView(UserPassesTestMixin, View):
|
||||||
for key in session_keys:
|
for key in session_keys:
|
||||||
if key in self.request.session:
|
if key in self.request.session:
|
||||||
del self.request.session[key]
|
del self.request.session[key]
|
||||||
print(self.request.session.keys())
|
|
||||||
LOGGER.debug("Cleaned up sessions")
|
LOGGER.debug("Cleaned up sessions")
|
||||||
|
|
||||||
class FactorPermissionDeniedView(PermissionDeniedView):
|
class FactorPermissionDeniedView(PermissionDeniedView):
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
<link rel="shortcut icon" type="image/png" href="{% static 'img/logo.png' %}">
|
<link rel="shortcut icon" type="image/png" href="{% static 'img/logo.png' %}">
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly.min.css' %}">
|
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly.min.css' %}">
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly-additions.min.css' %}">
|
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly-additions.min.css' %}">
|
||||||
|
<style>
|
||||||
|
.login-pf {
|
||||||
|
background-attachment: fixed;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -5,53 +5,57 @@
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<style>
|
<style>
|
||||||
.login-pf-page .login-pf-page-footer-links {
|
.login-pf-page .login-pf-page-footer-links {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-top: 2px solid transparent;
|
border-top: 2px solid transparent;
|
||||||
box-shadow: 0 1px 1px rgba(3,3,3,.175);
|
box-shadow: 0 1px 1px rgba(3, 3, 3, .175);
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-pf-page .login-pf-page-footer-link {
|
.login-pf-page .login-pf-page-footer-link {
|
||||||
color: #72767b;
|
color: #72767b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-pf-page .login-pf-page-footer-links li:not(:last-of-type):after {
|
.login-pf-page .login-pf-page-footer-links li:not(:last-of-type):after {
|
||||||
color: #72767b;
|
color: #72767b;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="login-pf-page">
|
<div class="login-pf-page">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
|
|
||||||
<header class="login-pf-page-header">
|
|
||||||
<img class="login-pf-brand" style="max-height: 10rem;" src="{% static 'img/logo.svg' %}" alt="PatternFly logo" />
|
|
||||||
{% if config.login.subtext %}
|
|
||||||
<p>{{ config.login.subtext }}</p>
|
|
||||||
{% endif %}
|
|
||||||
</header>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% block row %}
|
<div class="col-md-6 col-md-offset-3">
|
||||||
<div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2">
|
{% include 'partials/messages.html' %}
|
||||||
<div class="card-pf">
|
</div>
|
||||||
{% block card %}
|
<div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
|
||||||
{% endblock %}
|
<header class="login-pf-page-header">
|
||||||
</div><!-- card -->
|
<img class="login-pf-brand" style="max-height: 10rem;" src="{% static 'img/logo.svg' %}"
|
||||||
<footer class="login-pf-page-footer">
|
alt="PatternFly logo" />
|
||||||
<ul class="login-pf-page-footer-links list-unstyled">
|
{% if config.login.subtext %}
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Terms of Use</a></li>
|
<p>{{ config.login.subtext }}</p>
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Help</a></li>
|
{% endif %}
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Privacy Policy</a></li>
|
</header>
|
||||||
</ul>
|
<div class="row">
|
||||||
</footer>
|
{% block row %}
|
||||||
</div><!-- col -->
|
<div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2">
|
||||||
{% endblock %}
|
<div class="card-pf">
|
||||||
|
{% block card %}
|
||||||
|
{% endblock %}
|
||||||
|
</div><!-- card -->
|
||||||
|
<footer class="login-pf-page-footer">
|
||||||
|
<ul class="login-pf-page-footer-links list-unstyled">
|
||||||
|
<li><a class="login-pf-page-footer-link" href="#">Terms of Use</a></li>
|
||||||
|
<li><a class="login-pf-page-footer-link" href="#">Help</a></li>
|
||||||
|
<li><a class="login-pf-page-footer-link" href="#">Privacy Policy</a></li>
|
||||||
|
</ul>
|
||||||
|
</footer>
|
||||||
|
</div><!-- col -->
|
||||||
|
{% endblock %}
|
||||||
|
</div><!-- row -->
|
||||||
|
</div><!-- col -->
|
||||||
</div><!-- row -->
|
</div><!-- row -->
|
||||||
</div><!-- col -->
|
</div><!-- container -->
|
||||||
</div><!-- row -->
|
|
||||||
</div><!-- container -->
|
|
||||||
</div><!-- login-pf-page -->
|
</div><!-- login-pf-page -->
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
<header class="login-pf-header">
|
<header class="login-pf-header">
|
||||||
<h1>{% trans title %}</h1>
|
<h1>{% trans title %}</h1>
|
||||||
</header>
|
</header>
|
||||||
{% include 'partials/messages.html' %}
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% block above_form %}
|
{% block above_form %}
|
||||||
|
|
|
@ -62,8 +62,7 @@ class LoginView(UserPassesTestMixin, FormView):
|
||||||
if not pre_user:
|
if not pre_user:
|
||||||
# No user found
|
# No user found
|
||||||
return self.invalid_login(self.request)
|
return self.invalid_login(self.request)
|
||||||
if AuthenticationView.SESSION_FACTOR in self.request.session:
|
self.request.session.flush()
|
||||||
del self.request.session[AuthenticationView.SESSION_FACTOR]
|
|
||||||
self.request.session[AuthenticationView.SESSION_PENDING_USER] = pre_user.pk
|
self.request.session[AuthenticationView.SESSION_PENDING_USER] = pre_user.pk
|
||||||
return redirect(reverse('passbook_core:auth-process'))
|
return redirect(reverse('passbook_core:auth-process'))
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,14 @@ LOGGER = getLogger(__name__)
|
||||||
class OTPFactor(FormView, AuthenticationFactor):
|
class OTPFactor(FormView, AuthenticationFactor):
|
||||||
"""OTP Factor View"""
|
"""OTP Factor View"""
|
||||||
|
|
||||||
template_name = 'login/form_with_user.html'
|
template_name = 'otp/factor.html'
|
||||||
form_class = OTPVerifyForm
|
form_class = OTPVerifyForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
kwargs = super().get_context_data(**kwargs)
|
||||||
|
kwargs['title'] = _('Enter Verification Code')
|
||||||
|
return kwargs
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
"""Check if User has OTP enabled and if OTP is enforced"""
|
"""Check if User has OTP enabled and if OTP is enforced"""
|
||||||
if not user_has_device(self.pending_user):
|
if not user_has_device(self.pending_user):
|
||||||
|
@ -27,7 +32,8 @@ class OTPFactor(FormView, AuthenticationFactor):
|
||||||
LOGGER.debug("OTP is enforced, redirecting to setup")
|
LOGGER.debug("OTP is enforced, redirecting to setup")
|
||||||
request.user = self.pending_user
|
request.user = self.pending_user
|
||||||
LOGGER.debug("Passing GET to EnableView")
|
LOGGER.debug("Passing GET to EnableView")
|
||||||
return EnableView().dispatch(request)
|
messages.info(request, _('OTP is enforced. Please setup OTP.'))
|
||||||
|
return EnableView.as_view()(request)
|
||||||
LOGGER.debug("OTP is not enforced, skipping form")
|
LOGGER.debug("OTP is not enforced, skipping form")
|
||||||
return self.authenticator.user_ok()
|
return self.authenticator.user_ok()
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
@ -37,7 +43,7 @@ class OTPFactor(FormView, AuthenticationFactor):
|
||||||
if OTP_SETTING_UP_KEY in request.session:
|
if OTP_SETTING_UP_KEY in request.session:
|
||||||
LOGGER.debug("Passing POST to EnableView")
|
LOGGER.debug("Passing POST to EnableView")
|
||||||
request.user = self.pending_user
|
request.user = self.pending_user
|
||||||
return EnableView().dispatch(request)
|
return EnableView.as_view()(request)
|
||||||
return super().post(self, request, *args, **kwargs)
|
return super().post(self, request, *args, **kwargs)
|
||||||
|
|
||||||
def form_valid(self, form: OTPVerifyForm):
|
def form_valid(self, form: OTPVerifyForm):
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{% extends 'login/form_with_user.html' %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block above_form %}
|
||||||
|
{{ block.super }}
|
||||||
|
<p><b>{% trans 'Enter the Verification Code from your Authenticator App.' %}</b></p>
|
||||||
|
{% endblock %}
|
|
@ -107,8 +107,8 @@ class EnableView(LoginRequiredMixin, FormView):
|
||||||
self.static_device = StaticDevice(user=request.user, confirmed=False)
|
self.static_device = StaticDevice(user=request.user, confirmed=False)
|
||||||
self.static_device.save()
|
self.static_device.save()
|
||||||
# Create 9 tokens and save them
|
# Create 9 tokens and save them
|
||||||
# pylint: disable=unused-variable
|
# TODO: Send static tokens via E-Mail
|
||||||
for counter in range(0, 9):
|
for _counter in range(0, 9):
|
||||||
token = StaticToken(device=self.static_device, token=StaticToken.random_token())
|
token = StaticToken(device=self.static_device, token=StaticToken.random_token())
|
||||||
token.save()
|
token.save()
|
||||||
else:
|
else:
|
||||||
|
|
Reference in New Issue