mirror of
https://github.com/pretix/pretix.git
synced 2026-05-03 14:54:04 +00:00
improve permission handling
This commit is contained in:
@@ -44,7 +44,24 @@ from pretix.helpers.security import (
|
||||
)
|
||||
|
||||
|
||||
class RequireAll:
|
||||
def __init__(self, *permissions):
|
||||
self.permissions = permissions
|
||||
|
||||
|
||||
class EventPermission(BasePermission):
|
||||
@staticmethod
|
||||
def _check_required_permission(request, required_permission):
|
||||
if isinstance(required_permission, RequireAll):
|
||||
if any(p not in request.eventpermset for p in required_permission.permissions):
|
||||
return False
|
||||
elif isinstance(required_permission, (list, tuple)):
|
||||
if not any(p in request.eventpermset for p in required_permission):
|
||||
return False
|
||||
else:
|
||||
if required_permission and required_permission not in request.eventpermset:
|
||||
return False
|
||||
return True
|
||||
|
||||
def has_permission(self, request, view):
|
||||
if not request.user.is_authenticated and not isinstance(request.auth, (Device, TeamAPIToken)):
|
||||
@@ -87,12 +104,8 @@ class EventPermission(BasePermission):
|
||||
else:
|
||||
request.eventpermset = perm_holder.get_event_permission_set(request.organizer, request.event)
|
||||
|
||||
if isinstance(required_permission, (list, tuple)):
|
||||
if not any(p in request.eventpermset for p in required_permission):
|
||||
return False
|
||||
else:
|
||||
if required_permission and required_permission not in request.eventpermset:
|
||||
return False
|
||||
if not self._check_required_permission(request, required_permission):
|
||||
return False
|
||||
|
||||
elif 'organizer' in request.resolver_match.kwargs:
|
||||
if not request.organizer or not perm_holder.has_organizer_permission(request.organizer, request=request):
|
||||
@@ -102,12 +115,8 @@ class EventPermission(BasePermission):
|
||||
else:
|
||||
request.orgapermset = perm_holder.get_organizer_permission_set(request.organizer)
|
||||
|
||||
if isinstance(required_permission, (list, tuple)):
|
||||
if not any(p in request.eventpermset for p in required_permission):
|
||||
return False
|
||||
else:
|
||||
if required_permission and required_permission not in request.orgapermset:
|
||||
return False
|
||||
if not self._check_required_permission(request, required_permission):
|
||||
return False
|
||||
|
||||
if isinstance(request.auth, OAuthAccessToken):
|
||||
if not request.auth.allow_scopes(['write']) and request.method not in SAFE_METHODS:
|
||||
|
||||
@@ -42,9 +42,10 @@ from django_scopes import scopes_disabled
|
||||
from rest_framework import serializers, views, viewsets
|
||||
from rest_framework.exceptions import PermissionDenied, ValidationError, NotFound
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.permissions import SAFE_METHODS
|
||||
from rest_framework.response import Response
|
||||
|
||||
from pretix.api.auth.permission import EventCRUDPermission
|
||||
from pretix.api.auth.permission import EventCRUDPermission, RequireAll
|
||||
from pretix.api.pagination import TotalOrderingFilter
|
||||
from pretix.api.serializers.event import (
|
||||
CloneEventSerializer, DeviceEventSettingsSerializer, EventSerializer,
|
||||
@@ -672,11 +673,17 @@ class EventSettingsView(views.APIView):
|
||||
class SeatViewSet(ConditionalListView, viewsets.ModelViewSet):
|
||||
serializer_class = SeatSerializer
|
||||
queryset = Seat.objects.none()
|
||||
permission = 'can_view_orders'
|
||||
write_permission = 'can_change_event_settings'
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_fields = ('zone_name', 'row_name', 'row_label', 'seat_number', 'seat_label', 'seat_guid', 'blocked',)
|
||||
|
||||
def _get_permission_name(self, request):
|
||||
perms = []
|
||||
if 'orderposition' in request.query_params.getlist('expand'):
|
||||
perms.append('can_view_orders')
|
||||
if request.method not in SAFE_METHODS:
|
||||
perms.append('can_change_event_settings')
|
||||
return RequireAll(*perms)
|
||||
|
||||
def get_queryset(self):
|
||||
if self.request.event.has_subevents and 'subevent' in self.request.resolver_match.kwargs:
|
||||
try:
|
||||
|
||||
@@ -34,6 +34,7 @@ from rest_framework.exceptions import MethodNotAllowed
|
||||
from rest_framework.filters import OrderingFilter
|
||||
from rest_framework.response import Response
|
||||
|
||||
from pretix.api.auth.permission import RequireAll
|
||||
from pretix.api.serializers.media import (
|
||||
MediaLookupInputSerializer, ReusableMediaSerializer,
|
||||
)
|
||||
@@ -61,13 +62,17 @@ with scopes_disabled():
|
||||
class ReusableMediaViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = ReusableMediaSerializer
|
||||
queryset = ReusableMedium.objects.none()
|
||||
permission = 'can_manage_reusable_media'
|
||||
write_permission = 'can_manage_reusable_media'
|
||||
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||
ordering = ('-updated', '-id')
|
||||
ordering_fields = ('created', 'updated', 'identifier', 'type', 'id')
|
||||
filterset_class = ReusableMediumFilter
|
||||
|
||||
def _get_permission_name(self, request):
|
||||
if 'linked_orderposition' in request.query_params.getlist('expand'):
|
||||
return RequireAll(['can_manage_reusable_media', 'can_view_orders'])
|
||||
else:
|
||||
return 'can_manage_reusable_media'
|
||||
|
||||
def get_queryset(self):
|
||||
s = GiftCardTransaction.objects.filter(
|
||||
card=OuterRef('pk')
|
||||
|
||||
Reference in New Issue
Block a user