Projet

Général

Profil

0001-delegate-permission-checking-to-mellon-if-possible.patch

Valentin Deniaud, 17 juillet 2019 17:07

Télécharger (7,78 ko)

Voir les différences:

Subject: [PATCH 1/3] delegate permission checking to mellon if possible

We pass request instead of user in permission method because mellon
wants to look inside the session.
 chrono/agendas/models.py | 35 ++++++++++++++++++++++++-----------
 chrono/exceptions.py     |  5 +++++
 chrono/manager/views.py  | 33 +++++++++++++++++++++------------
 chrono/settings.py       |  1 +
 4 files changed, 51 insertions(+), 23 deletions(-)
 create mode 100644 chrono/exceptions.py
chrono/agendas/models.py
35 35

  
36 36
from jsonfield import JSONField
37 37

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

  
41

  
42
try:
43
    from mellon.utils import user_has_role
44
except ImportError:
45
    def user_has_role(request, role):
46
        if request.user.is_staff:
47
            return True
48
        return request.user.groups.filter(id=role.id).exists()
39 49

  
40 50

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

  
96
    def can_be_managed(self, user):
97
        if user.is_staff:
98
            return True
99
        group_ids = [x.id for x in user.groups.all()]
100
        return bool(self.edit_role_id in group_ids)
106
    def can_be_managed(self, request):
107
        return user_has_role(request, self.edit_role)
101 108

  
102
    def can_be_viewed(self, user):
103
        if self.can_be_managed(user):
104
            return True
105
        group_ids = [x.id for x in user.groups.all()]
106
        return bool(self.view_role_id in group_ids)
109
    def can_be_viewed(self, request):
110
        could_be_managed = False
111
        try:
112
            if self.can_be_managed(request):
113
                return True
114
        except RolesNotInSession as e:
115
            could_be_managed = e
116
        has_role = user_has_role(request, self.view_role)
117
        if not has_role and could_be_managed:
118
            raise could_be_managed
119
        return has_role
107 120

  
108 121
    def get_base_meeting_duration(self):
109 122
        durations = [x.duration for x in MeetingType.objects.filter(agenda=self)]
chrono/exceptions.py
1
try:
2
    from mellon.exceptions import RolesNotInSession
3
except ImportError:
4
    class RolesNotInSession(Exception):
5
        pass
chrono/manager/views.py
35 35
from chrono.agendas.models import (Agenda, Event, MeetingType, TimePeriod,
36 36
                                   Booking, Desk, TimePeriodException,
37 37
                                   ICSError, AgendaImportError)
38
from chrono.exceptions import RolesNotInSession
38 39

  
39 40
from .forms import (AgendaAddForm, AgendaEditForm, EventForm, NewMeetingTypeForm, MeetingTypeForm,
40 41
                    TimePeriodForm, ImportEventsForm, NewDeskForm, DeskForm, TimePeriodExceptionForm,
......
130 131

  
131 132
    def get_object(self, queryset=None):
132 133
        obj = super(AgendaEditView, self).get_object(queryset=queryset)
133
        if not obj.can_be_managed(self.request.user):
134
        if not obj.can_be_managed(self.request):
134 135
            raise PermissionDenied()
135 136
        return obj
136 137

  
......
176 177
            agenda = Agenda.objects.get(id=kwargs.get('pk'))
177 178
        except Agenda.DoesNotExist:
178 179
            raise Http404()
179
        if not agenda.can_be_viewed(self.request.user):
180
        if not agenda.can_be_viewed(self.request):
180 181
            raise PermissionDenied()
181 182

  
182 183
        if agenda.kind == 'meetings':
......
206 207
        self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'))
207 208
        if self.agenda.kind != 'meetings':
208 209
            raise Http404()
209
        if not self.agenda.can_be_viewed(request.user):
210
        if not self.agenda.can_be_viewed(request):
210 211
            raise PermissionDenied()
211 212

  
212 213
        # specify 6am time to get the expected timezone on daylight saving time
......
443 444
            self.agenda = Agenda.objects.get(id=kwargs.get('pk'))
444 445
        except Agenda.DoesNotExist:
445 446
            raise Http404()
446
        if not self.agenda.can_be_managed(request.user):
447
        if not self.agenda.can_be_managed(request):
447 448
            raise PermissionDenied()
448 449
        return super(ManagedAgendaMixin, self).dispatch(request, *args, **kwargs)
449 450

  
......
466 467

  
467 468
    def dispatch(self, request, *args, **kwargs):
468 469
        self.agenda = self.get_object().agenda
469
        if not self.agenda.can_be_managed(request.user):
470
        if not self.agenda.can_be_managed(request):
470 471
            raise PermissionDenied()
471 472
        return super(ManagedAgendaSubobjectMixin, self).dispatch(request, *args, **kwargs)
472 473

  
......
487 488
            self.desk = Desk.objects.get(id=kwargs.get('pk'))
488 489
        except Desk.DoesNotExist:
489 490
            raise Http404()
490
        if not self.desk.agenda.can_be_managed(request.user):
491
        if not self.desk.agenda.can_be_managed(request):
491 492
            raise PermissionDenied()
492 493
        return super(ManagedDeskMixin, self).dispatch(request, *args, **kwargs)
493 494

  
......
511 512

  
512 513
    def dispatch(self, request, *args, **kwargs):
513 514
        self.desk = self.get_object().desk
514
        if not self.desk.agenda.can_be_managed(request.user):
515
        if not self.desk.agenda.can_be_managed(request):
515 516
            raise PermissionDenied()
516 517
        return super(ManagedDeskSubobjectMixin, self).dispatch(request, *args, **kwargs)
517 518

  
......
534 535
            self.agenda = Agenda.objects.get(id=kwargs.get('pk'))
535 536
        except Agenda.DoesNotExist:
536 537
            raise Http404()
537
        if not self.agenda.can_be_managed(request.user):
538
            # "events" agendas settings page can be access by user with the
539
            # view permission as there are no other "view" page for this type
540
            # of agenda.
541
            if self.agenda.kind != 'events' or not self.agenda.can_be_viewed(request.user):
538
        # Do something different here as "events" agendas settings page can be
539
        # access by user with the view permission as there are no other "view"
540
        # page for this type of agenda.
541
        raised_exception = None
542
        try:
543
            can_be_managed = self.agenda.can_be_managed(request)
544
        except RolesNotInSession as e:
545
            can_be_managed = False
546
            raised_exception = e
547
        if not can_be_managed:
548
            if self.agenda.kind != 'events' or not self.agenda.can_be_viewed(request):
549
                if raised_exception:
550
                    raise raised_exception
542 551
                raise PermissionDenied()
543 552
        return super(DetailView, self).dispatch(request, *args, **kwargs)
544 553

  
chrono/settings.py
141 141
        'mellon.backends.SAMLBackend',
142 142
        'django.contrib.auth.backends.ModelBackend',
143 143
    )
144
    MIDDLEWARE_CLASSES += ('mellon.middleware.RolesRequestMiddleware',)
144 145

  
145 146
LOGIN_URL = '/login/'
146 147
LOGIN_REDIRECT_URL = '/'
147
-