summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValentin Deniaud <vdeniaud@entrouvert.com>2019-05-21 09:58:58 (GMT)
committerValentin Deniaud <vdeniaud@entrouvert.com>2019-07-17 14:26:15 (GMT)
commit1c3f3d887c865f98c2d22b9f74b59e1ce0560559 (patch)
treedf21018efe3cf02113d89ecf4f54f79b86d627dd
parent12a5327367f465a7987d33bc29702903445b4399 (diff)
downloaddjango-mellon-wip/32376-Support-des-niveaux-d-authentifi.zip
django-mellon-wip/32376-Support-des-niveaux-d-authentifi.tar.gz
django-mellon-wip/32376-Support-des-niveaux-d-authentifi.tar.bz2
utils: add method to check if a user has a rolewip/32376-Support-des-niveaux-d-authentifi
Along with a middleware to allow catching the exception it raises when the user is missing roles, redirecting them appropriately. A distinction is made between roles which are obtained at the SSO, stored in session, and roles which the user could have, statically stored in database. todo: ce commit dépend totalement du provisionning tel qu'implémenté par hobo, il faudrait améliorer ça
-rw-r--r--mellon/exceptions.py4
-rw-r--r--mellon/middleware.py8
-rw-r--r--mellon/utils.py31
3 files changed, 43 insertions, 0 deletions
diff --git a/mellon/exceptions.py b/mellon/exceptions.py
new file mode 100644
index 0000000..0d4fec2
--- /dev/null
+++ b/mellon/exceptions.py
@@ -0,0 +1,4 @@
+class RolesNotInSession(Exception):
+
+ def __init__(self, roles):
+ self.roles = roles
diff --git a/mellon/middleware.py b/mellon/middleware.py
index a0b814a..ed35eb1 100644
--- a/mellon/middleware.py
+++ b/mellon/middleware.py
@@ -3,6 +3,7 @@ from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from . import app_settings, utils
+from .exceptions import RolesNotInSession
PASSIVE_TRIED_COOKIE = 'MELLON_PASSIVE_TRIED'
@@ -50,3 +51,10 @@ class PassiveAuthenticationMiddleware(object):
# prevent loops
response.set_cookie(PASSIVE_TRIED_COOKIE, value='1', max_age=None)
return response
+
+
+class RolesRequestMiddleware(object):
+ def process_exception(self, request, exception):
+ if isinstance(exception, RolesNotInSession):
+ return HttpResponseRedirect(
+ utils.get_role_request_url(request, exception.roles))
diff --git a/mellon/utils.py b/mellon/utils.py
index ee8b8a5..018246f 100644
--- a/mellon/utils.py
+++ b/mellon/utils.py
@@ -6,7 +6,9 @@ import isodate
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
@@ -14,6 +16,7 @@ from django.utils.six.moves.urllib.parse import urlparse
import lasso
from . import app_settings
+from .exceptions import RolesNotInSession
def create_metadata(request):
@@ -289,3 +292,31 @@ def has_superuser_flag(idp, saml_attributes):
if attribute_values & values:
return True
return False
+
+
+def user_has_roles(request, roles):
+ if request.user.is_staff and request.session.get('is_staff'):
+ return True
+ groups = set(roles).intersection(request.user.groups.all())
+ if not groups:
+ if request.user.is_staff:
+ raise RolesNotInSession(('staff',))
+ return False
+ role_uuids = {getattr(group, 'role').uuid for group in groups}
+ if not role_uuids:
+ return True
+ if set(request.session['mellon_session']['role-slug']) & role_uuids:
+ return True
+ raise RolesNotInSession(role_uuids)
+
+
+def user_has_role(request, role):
+ return user_has_roles(request, {role})
+
+
+def get_role_request_url(request, roles):
+ login_url = reverse(app_settings.LOGIN_URL)
+ q = QueryDict(mutable=True)
+ q.setlist('roles', roles)
+ q['next'] = request.get_full_path()
+ return '?'.join((login_url, q.urlencode(safe='/')))