From 6f9b53b52939246f9238d2b2c097745ef10b08c0 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Fri, 19 Apr 2019 10:53:44 +0200 Subject: [PATCH 5/5] utils: add check_session_roles decorator Can be used to decorate views and automatically trigger a roles request if necessary. --- mellon/utils.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mellon/utils.py b/mellon/utils.py index 1773d13..4e157d7 100644 --- a/mellon/utils.py +++ b/mellon/utils.py @@ -8,6 +8,7 @@ from xml.parsers import expat from django.contrib import auth from django.contrib.auth.models import Group from django.core.urlresolvers import reverse +from django.http import QueryDict, HttpResponseRedirect from django.template.loader import render_to_string from django.utils.timezone import make_aware, now, make_naive, is_aware, get_default_timezone from django.conf import settings @@ -308,3 +309,24 @@ def user_has_role(request, role_id): if role.uuid in request.session['mellon_session']['role-slug']: return True raise RolesNotInSession((role.uuid,)) + + +def check_session_roles(func, login_url=None): + """Redirect to mellon login if a required role is missing. + + login_url can be specified in order to redirect to another view. In that + case be sure to handle the 'next' and the multiple 'roles' query parameters + that get added. + """ + if not login_url: + login_url = reverse(app_settings.LOGIN_URL) + def wrapped(request, *args, **kwargs): + try: + return func(request, *args, **kwargs) + except RolesNotInSession as e: + q = QueryDict(mutable=True) + q.setlist('roles', e.roles) + q['next'] = request.get_full_path() + redirect_url = '?'.join((login_url, q.urlencode(safe='/'))) + return HttpResponseRedirect(redirect_url) + return wrapped -- 2.20.1