Projet

Général

Profil

0002-allow-checking-for-authentication-level-and-request-.patch

Valentin Deniaud, 16 avril 2019 14:27

Télécharger (5,28 ko)

Voir les différences:

Subject: [PATCH 2/2] allow checking for authentication level and request
 increase

 chrono/agendas/models.py | 31 +++++++++++++++++++++++++------
 chrono/exceptions.py     |  4 ++++
 chrono/manager/views.py  |  2 +-
 chrono/urls_utils.py     | 17 ++++++++++++++++-
 4 files changed, 46 insertions(+), 8 deletions(-)
 create mode 100644 chrono/exceptions.py
chrono/agendas/models.py
36 36
from jsonfield import JSONField
37 37

  
38 38
from ..interval import Intervals
39
from chrono.exceptions import InsufficientAuthLevel
39 40

  
40 41

  
41 42
AGENDA_KINDS = (
......
93 94
    def get_absolute_url(self):
94 95
        return reverse('chrono-manager-agenda-view', kwargs={'pk': self.id})
95 96

  
96
    def can_be_managed(self, user):
97
    @staticmethod
98
    def user_has_sufficient_auth_level(user, role, can_raise):
99
        if hasattr(role, 'auth_level') and user.auth_level < role.auth_level.value:
100
            if can_raise:
101
                raise InsufficientAuthLevel(role.auth_level.value)
102
            return False
103
        return True
104

  
105
    def can_be_managed(self, user, can_raise=True):
97 106
        if user.is_staff:
98 107
            return True
99 108
        group_ids = [x.id for x in user.groups.all()]
100
        return bool(self.edit_role_id in group_ids)
109
        if self.edit_role_id in group_ids:
110
            return self.user_has_sufficient_auth_level(user, self.edit_role, can_raise)
111
        return False
101 112

  
102
    def can_be_viewed(self, user):
103
        if self.can_be_managed(user):
104
            return True
113
    def can_be_viewed(self, user, can_raise=True):
114
        would_have_raised = False
115
        try:
116
            if self.can_be_managed(user, can_raise):
117
                return True
118
        except InsufficientAuthLevel as e:
119
            would_have_raised = e.auth_level.value
105 120
        group_ids = [x.id for x in user.groups.all()]
106
        return bool(self.view_role_id in group_ids)
121
        if self.view_role_id in group_ids:
122
            return self.user_has_sufficient_auth_level(user, self.view_role, can_raise)
123
        if would_have_raised:
124
            raise InsufficientAuthLevel(would_have_raised)
125
        return False
107 126

  
108 127
    def get_base_meeting_duration(self):
109 128
        durations = [x.duration for x in MeetingType.objects.filter(agenda=self)]
chrono/exceptions.py
1
class InsufficientAuthLevel(Exception):
2

  
3
    def __init__(self, level):
4
        self.required_level = level
chrono/manager/views.py
534 534
            self.agenda = Agenda.objects.get(id=kwargs.get('pk'))
535 535
        except Agenda.DoesNotExist:
536 536
            raise Http404()
537
        if not self.agenda.can_be_managed(request.user):
537
        if not self.agenda.can_be_managed(request.user, can_raise=False):
538 538
            # "events" agendas settings page can be access by user with the
539 539
            # view permission as there are no other "view" page for this type
540 540
            # of agenda.
chrono/urls_utils.py
17 17
# Decorating URL includes, <https://djangosnippets.org/snippets/2532/>
18 18

  
19 19
from django.contrib.auth.decorators import user_passes_test
20
from django.contrib.auth.views import redirect_to_login
20 21
from django.core.exceptions import PermissionDenied
21 22
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
22 23
from django.db.models import Q
23 24

  
24 25
from .agendas.models import Agenda
26
from .exceptions import InsufficientAuthLevel
25 27

  
26 28

  
27 29
class DecoratedURLPattern(RegexURLPattern):
......
53 55
    return urlconf_module, app_name, namespace
54 56

  
55 57
def manager_required(function=None, login_url=None):
58

  
59
    def check_auth_level(func):
60
        def wrapped(request, *args, **kwargs):
61
            try:
62
                request.user.auth_level = request.session.get('auth_level', 1)
63
                return func(request, *args, **kwargs)
64
            except InsufficientAuthLevel as e:
65
                required_auth_level = e.required_level
66
                next_field_value = request.get_full_path()
67
                login_url = '/login/?auth_level=%s' % required_auth_level
68
                return redirect_to_login(next_field_value, login_url)
69
        return wrapped
70

  
56 71
    def check_manager(user):
57 72
        if user and user.is_staff:
58 73
            return True
......
66 81
        return False
67 82
    actual_decorator = user_passes_test(check_manager, login_url=login_url)
68 83
    if function:
69
        return actual_decorator(function)
84
        return check_auth_level(actual_decorator(function))
70 85
    return actual_decorator
71
-