From f342e46f53b673e441e64fc37892b31beb68de38 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 10 Oct 2017 22:54:36 +0200 Subject: [PATCH] API: Require can_change_items for more endpoints --- src/pretix/api/auth/permission.py | 17 +++++++++++------ src/pretix/api/views/event.py | 1 + src/pretix/api/views/item.py | 4 ++++ src/tests/api/conftest.py | 5 ++++- src/tests/api/test_permissions.py | 7 +++++++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/pretix/api/auth/permission.py b/src/pretix/api/auth/permission.py index be028ad442..279d57de4d 100644 --- a/src/pretix/api/auth/permission.py +++ b/src/pretix/api/auth/permission.py @@ -13,6 +13,13 @@ class EventPermission(BasePermission): return True return False + if request.method not in SAFE_METHODS and hasattr(view, 'write_permission'): + required_permission = getattr(view, 'write_permission') + elif hasattr(view, 'permission'): + required_permission = getattr(view, 'permission') + else: + required_permission = None + perm_holder = (request.auth if isinstance(request.auth, TeamAPIToken) else request.user) if 'event' in request.resolver_match.kwargs and 'organizer' in request.resolver_match.kwargs: @@ -25,9 +32,8 @@ class EventPermission(BasePermission): request.organizer = request.event.organizer request.eventpermset = perm_holder.get_event_permission_set(request.organizer, request.event) - if hasattr(view, 'permission'): - if view.permission and view.permission not in request.eventpermset: - return False + if required_permission and required_permission not in request.eventpermset: + return False elif 'organizer' in request.resolver_match.kwargs: request.organizer = Organizer.objects.filter( @@ -37,7 +43,6 @@ class EventPermission(BasePermission): return False request.orgapermset = perm_holder.get_organizer_permission_set(request.organizer) - if hasattr(view, 'permission'): - if view.permission and view.permission not in request.orgapermset: - return False + if required_permission and required_permission not in request.orgapermset: + return False return True diff --git a/src/pretix/api/views/event.py b/src/pretix/api/views/event.py index 365e1857af..5fd6518179 100644 --- a/src/pretix/api/views/event.py +++ b/src/pretix/api/views/event.py @@ -39,6 +39,7 @@ class SubEventViewSet(viewsets.ReadOnlyModelViewSet): class TaxRuleViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = TaxRuleSerializer queryset = TaxRule.objects.none() + write_permission = 'can_change_event_settings' def get_queryset(self): return self.request.event.tax_rules.all() diff --git a/src/pretix/api/views/item.py b/src/pretix/api/views/item.py index ea77201680..0273f5c889 100644 --- a/src/pretix/api/views/item.py +++ b/src/pretix/api/views/item.py @@ -34,6 +34,7 @@ class ItemViewSet(viewsets.ReadOnlyModelViewSet): ordering_fields = ('id', 'position') ordering = ('position', 'id') filter_class = ItemFilter + permission = 'can_change_items' def get_queryset(self): return self.request.event.items.select_related('tax_rule').prefetch_related('variations', 'addons').all() @@ -52,6 +53,7 @@ class ItemCategoryViewSet(viewsets.ReadOnlyModelViewSet): filter_class = ItemCategoryFilter ordering_fields = ('id', 'position') ordering = ('position', 'id') + permission = 'can_change_items' def get_queryset(self): return self.request.event.categories.all() @@ -63,6 +65,7 @@ class QuestionViewSet(viewsets.ReadOnlyModelViewSet): filter_backends = (OrderingFilter,) ordering_fields = ('id', 'position') ordering = ('position', 'id') + permission = 'can_change_items' def get_queryset(self): return self.request.event.questions.prefetch_related('options').all() @@ -81,6 +84,7 @@ class QuotaViewSet(viewsets.ReadOnlyModelViewSet): filter_class = QuotaFilter ordering_fields = ('id', 'size') ordering = ('id',) + permission = 'can_change_items' def get_queryset(self): return self.request.event.quotas.all() diff --git a/src/tests/api/conftest.py b/src/tests/api/conftest.py index 6fa2548d9a..04e97094e1 100644 --- a/src/tests/api/conftest.py +++ b/src/tests/api/conftest.py @@ -35,7 +35,10 @@ def event(organizer, meta_prop): @pytest.fixture def team(organizer): - return Team.objects.create(organizer=organizer) + return Team.objects.create( + organizer=organizer, + can_change_items=True, + ) @pytest.fixture diff --git a/src/tests/api/test_permissions.py b/src/tests/api/test_permissions.py index cab6314551..3a7179ef34 100644 --- a/src/tests/api/test_permissions.py +++ b/src/tests/api/test_permissions.py @@ -11,6 +11,8 @@ event_urls = [ 'questions/', 'quotas/', 'vouchers/', + 'subevents/', + 'taxrules/', 'waitinglistentries/', ] @@ -20,6 +22,10 @@ event_permission_urls = [ ('get', 'can_view_vouchers', 'vouchers/', 200), ('get', 'can_view_orders', 'invoices/', 200), ('get', 'can_view_orders', 'waitinglistentries/', 200), + ('get', 'can_change_items', 'categories/', 200), + ('get', 'can_change_items', 'items/', 200), + ('get', 'can_change_items', 'questions/', 200), + ('get', 'can_change_items', 'quotas/', 200), ] @@ -27,6 +33,7 @@ event_permission_urls = [ def token_client(client, team): team.can_view_orders = True team.can_view_vouchers = True + team.can_change_items = True team.save() t = team.tokens.create(name='Foo') client.credentials(HTTP_AUTHORIZATION='Token ' + t.token)