diff --git a/src/authentic2/middleware.py b/src/authentic2/middleware.py index 1a2a56535..3b0516a89 100644 --- a/src/authentic2/middleware.py +++ b/src/authentic2/middleware.py @@ -26,6 +26,7 @@ import urllib.parse from django import http from django.conf import settings from django.contrib import messages +from django.db.models import Model from django.utils.deprecation import MiddlewareMixin from django.utils.functional import SimpleLazyObject from django.utils.translation import ugettext as _ @@ -108,32 +109,61 @@ class ViewRestrictionMiddleware(MiddlewareMixin): def check_view_restrictions(self, request): '''Check if a restriction on accessible views must be applied''' - from django.db.models import Model - - from .models import PasswordReset user = request.user - b = user.is_authenticated - if b and isinstance(user, Model): - now = time.time() - last_time = request.session.get('last_password_reset_check', 0) - if now - last_time > 10: - if PasswordReset.objects.filter(user=request.user).exists(): - return 'password_change' - request.session['last_password_reset_check'] = now + + # If the session is unlogged, do nothing + if user is None or not user.is_authenticated: + return None + + # If the latest check was succesfull, do nothing. + now = time.time() + last_time = request.session.get('last_view_restriction_check', 0) + if now - last_time <= 60: + return None + + view = self.check_password_reset_view_restriction(request, user) + if view: + return view + for plugin in plugins.get_plugins(): if hasattr(plugin, 'check_view_restrictions'): - view = plugin.check_view_restrictions(request) + view = plugin.check_view_restrictions(request, user) if view: return view + # do not check for 60 seconds + request.session['last_password_reset_check'] = now + return None + + def check_password_reset_view_restriction(self, request, user): + # If user is authenticated and a password_reset_flag is set, force + # redirect to password change and show a message. + from . import models + + if ( + user.is_authenticated + and isinstance(user, Model) + and models.PasswordReset.objects.filter(user=request.user).exists() + ): + if request.resolver_match.url_name != 'password_change': + messages.warning(request, _('You must change your password to continue')) + return 'password_change' + def process_view(self, request, view_func, view_args, view_kwargs): - '''If current view is not the one we should be, redirect''' + '''If current view is not the one where we should be, redirect''' view = self.check_view_restrictions(request) - if not view or request.resolver_match.url_name in (view, 'auth_logout'): + if not view: + return + url_name = request.resolver_match.url_name + + # do not block on the restricted view + if url_name == view: + return + + # prevent blocking people when they logout + if url_name == 'auth_logout': return - if view == 'password_change': - messages.warning(request, _('You must change your password to continue')) return utils_misc.redirect_and_come_back(request, view)