cleanup, fix Permission Denied when Cancelling login, fix display of messages on login template

This commit is contained in:
Jens Langhammer 2019-02-25 13:02:50 +01:00
parent 07f5dce97a
commit da5568b571
8 changed files with 73 additions and 50 deletions

View File

@ -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):

View File

@ -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>

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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'))

View File

@ -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):

View File

@ -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 %}

View File

@ -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: