diff options
authorValentin Deniaud <>2019-04-19 08:53:44 (GMT)
committerValentin Deniaud <>2019-06-05 12:47:56 (GMT)
commit6f9b53b52939246f9238d2b2c097745ef10b08c0 (patch)
parent7cac10994319ee1ebb61324262fd4897f9638118 (diff)
utils: add check_session_roles decoratorwip/32376-Support-des-niveaux-d-authentifi
Can be used to decorate views and automatically trigger a roles request if necessary.
1 files changed, 22 insertions, 0 deletions
diff --git a/mellon/ b/mellon/
index 1773d13..4e157d7 100644
--- a/mellon/
+++ b/mellon/
@@ -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