0002-allow-checking-for-authentication-level-and-request-.patch
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 |
- |