Projet

Général

Profil

0004-utils-add-method-to-check-if-a-user-has-a-role.patch

Valentin Deniaud, 17 juillet 2019 17:06

Télécharger (3,76 ko)

Voir les différences:

Subject: [PATCH] utils: add method to check if a user has a role
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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
 mellon/exceptions.py |  4 ++++
 mellon/middleware.py |  8 ++++++++
 mellon/utils.py      | 31 +++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+)
 create mode 100644 mellon/exceptions.py
mellon/exceptions.py
1
class RolesNotInSession(Exception):
2

  
3
    def __init__(self, roles):
4
        self.roles = roles
mellon/middleware.py
3 3
from django.core.urlresolvers import reverse
4 4

  
5 5
from . import app_settings, utils
6
from .exceptions import RolesNotInSession
6 7

  
7 8
PASSIVE_TRIED_COOKIE = 'MELLON_PASSIVE_TRIED'
8 9

  
......
50 51
            # prevent loops
51 52
            response.set_cookie(PASSIVE_TRIED_COOKIE, value='1', max_age=None)
52 53
            return response
54

  
55

  
56
class RolesRequestMiddleware(object):
57
    def process_exception(self, request, exception):
58
        if isinstance(exception, RolesNotInSession):
59
            return HttpResponseRedirect(
60
                utils.get_role_request_url(request, exception.roles))
mellon/utils.py
6 6
from xml.parsers import expat
7 7

  
8 8
from django.contrib import auth
9
from django.contrib.auth.models import Group
9 10
from django.core.urlresolvers import reverse
11
from django.http import QueryDict, HttpResponseRedirect
10 12
from django.template.loader import render_to_string
11 13
from django.utils.timezone import make_aware, now, make_naive, is_aware, get_default_timezone
12 14
from django.conf import settings
......
14 16
import lasso
15 17

  
16 18
from . import app_settings
19
from .exceptions import RolesNotInSession
17 20

  
18 21

  
19 22
def create_metadata(request):
......
289 292
            if attribute_values & values:
290 293
                return True
291 294
    return False
295

  
296

  
297
def user_has_roles(request, roles):
298
    if request.user.is_staff and request.session.get('is_staff'):
299
        return True
300
    groups = set(roles).intersection(request.user.groups.all())
301
    if not groups:
302
        if request.user.is_staff:
303
            raise RolesNotInSession(('staff',))
304
        return False
305
    role_uuids = {getattr(group, 'role').uuid for group in groups}
306
    if not role_uuids:
307
        return True
308
    if set(request.session['mellon_session']['role-slug']) & role_uuids:
309
        return True
310
    raise RolesNotInSession(role_uuids)
311

  
312

  
313
def user_has_role(request, role):
314
    return user_has_roles(request, {role})
315

  
316

  
317
def get_role_request_url(request, roles):
318
    login_url = reverse(app_settings.LOGIN_URL)
319
    q = QueryDict(mutable=True)
320
    q.setlist('roles', roles)
321
    q['next'] = request.get_full_path()
322
    return '?'.join((login_url, q.urlencode(safe='/')))
292
-