mirror of
https://github.com/pretix/pretix.git
synced 2026-05-12 16:24:00 +00:00
Pluggable permissions (#5728)
* Data model draft * Refactor query and assignment usages of old permissions * Backend UI * API serializer * Big string replace * Docs, tests and fixes for teams api * Update docs for device auth * Eliminate old names * Make tests pass * Use new permissions, remove inconsistencies * Add test for translations * Show plugin permissions * Add permission for seating plans * Fix plugin activation * Fix failing test * Refactor to permission groups * Update doc/api/resources/devices.rst Co-authored-by: luelista <weller@rami.io> * Update doc/api/resources/events.rst Co-authored-by: luelista <weller@rami.io> * Update src/pretix/api/serializers/organizer.py Co-authored-by: luelista <weller@rami.io> * Fix typo * Fix python version compat * Replacement after rebase * Add proper permission handling for exports * Docs for exporters * Runtime linting of permission names * Fix typos * Show export page even without orders permission * More legacy compat * Do not strongly validate before plugins are loaded * Rebase migration * Add permission for outgoing mails * Review notes * Update doc/api/resources/teams.rst Co-authored-by: Richard Schreiber <schreiber@pretix.eu> * Clean up logic around exporters * Review and failures * Fix migration leading to forbidden combination * Handle permissions on event copying * Remove print-statements * Make test clearer * Review feedback * Add AnyPermissionOf * migration safety --------- Co-authored-by: luelista <weller@rami.io> Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
This commit is contained in:
@@ -53,6 +53,7 @@ from pretix.base.media import MEDIA_TYPES
|
||||
from pretix.base.models import Checkin, LogEntry, Order, OrderPosition
|
||||
from pretix.base.models.checkin import CheckinList
|
||||
from pretix.base.models.orders import PrintLog
|
||||
from pretix.base.permissions import AnyPermissionOf
|
||||
from pretix.base.services.checkin import (
|
||||
LazyRuleVars, _logic_annotate_for_graphic_explain,
|
||||
)
|
||||
@@ -150,7 +151,7 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList
|
||||
model = Checkin
|
||||
context_object_name = 'entries'
|
||||
template_name = 'pretixcontrol/checkin/index.html'
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.list = get_object_or_404(self.request.event.checkin_lists.all(), pk=kwargs.get("list"))
|
||||
@@ -211,7 +212,7 @@ class CheckInListBulkRevertConfirmView(CheckInListQueryMixin, EventPermissionReq
|
||||
|
||||
|
||||
class CheckInListBulkActionView(CheckInListQueryMixin, EventPermissionRequiredMixin, AsyncPostView):
|
||||
permission = ('can_change_orders', 'can_checkin_orders')
|
||||
permission = AnyPermissionOf('event.orders:write', 'event.orders:checkin')
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.list = get_object_or_404(self.request.event.checkin_lists.all(), pk=kwargs.get("list"))
|
||||
@@ -228,7 +229,7 @@ class CheckInListBulkActionView(CheckInListQueryMixin, EventPermissionRequiredMi
|
||||
self.list = get_object_or_404(request.event.checkin_lists.all(), pk=kwargs.get("list"))
|
||||
positions = self.get_queryset()
|
||||
if request.POST.get('revert') == 'true':
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_orders', request=request):
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'event.orders:write', request=request):
|
||||
raise PermissionDenied()
|
||||
for op in positions:
|
||||
if op.order.status == Order.STATUS_PAID or (
|
||||
@@ -295,7 +296,7 @@ class CheckInListBulkActionView(CheckInListQueryMixin, EventPermissionRequiredMi
|
||||
class CheckinListList(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
model = CheckinList
|
||||
context_object_name = 'checkinlists'
|
||||
permission = 'can_view_orders'
|
||||
permission = AnyPermissionOf('event.orders:read', 'event.settings.general:write')
|
||||
template_name = 'pretixcontrol/checkin/lists.html'
|
||||
ordering = ('subevent__date_from', 'name', 'pk')
|
||||
|
||||
@@ -317,9 +318,9 @@ class CheckinListList(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
cl.subevent.event = self.request.event # re-use same event object to make sure settings are cached
|
||||
ctx['checkinlists'] = clists
|
||||
|
||||
ctx['can_change_organizer_settings'] = self.request.user.has_organizer_permission(
|
||||
ctx['link_device_settings'] = self.request.user.has_organizer_permission(
|
||||
self.request.organizer,
|
||||
'can_change_organizer_settings',
|
||||
'organizer.devices:read',
|
||||
self.request
|
||||
)
|
||||
ctx['filter_form'] = self.filter_form
|
||||
@@ -335,7 +336,7 @@ class CheckinListCreate(EventPermissionRequiredMixin, CreateView):
|
||||
model = CheckinList
|
||||
form_class = CheckinListForm
|
||||
template_name = 'pretixcontrol/checkin/list_edit.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'checkinlist'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
@@ -386,7 +387,7 @@ class CheckinListUpdate(EventPermissionRequiredMixin, UpdateView):
|
||||
model = CheckinList
|
||||
form_class = CheckinListForm
|
||||
template_name = 'pretixcontrol/checkin/list_edit.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'checkinlist'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
@@ -445,7 +446,7 @@ class CheckinListUpdate(EventPermissionRequiredMixin, UpdateView):
|
||||
class CheckinListDelete(EventPermissionRequiredMixin, CompatDeleteView):
|
||||
model = CheckinList
|
||||
template_name = 'pretixcontrol/checkin/list_delete.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'checkinlist'
|
||||
|
||||
def get_object(self, queryset=None) -> CheckinList:
|
||||
@@ -476,7 +477,7 @@ class CheckinListDelete(EventPermissionRequiredMixin, CompatDeleteView):
|
||||
class CheckinListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
model = Checkin
|
||||
context_object_name = 'checkins'
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
template_name = 'pretixcontrol/checkin/checkins.html'
|
||||
ordering = ('-datetime', '-pk')
|
||||
|
||||
@@ -505,7 +506,7 @@ class CheckinListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
|
||||
class CheckInListSimulator(EventPermissionRequiredMixin, FormView):
|
||||
template_name = 'pretixcontrol/checkin/simulator.html'
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
form_class = CheckinListSimulatorForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
@@ -575,9 +576,15 @@ class CheckInListSimulator(EventPermissionRequiredMixin, FormView):
|
||||
|
||||
class CheckInResetView(CheckInListQueryMixin, EventPermissionRequiredMixin, AsyncFormView):
|
||||
form_class = CheckinResetForm
|
||||
permission = "can_change_orders"
|
||||
permission = "event.orders:write"
|
||||
template_name = "pretixcontrol/checkin/reset.html"
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# Special case, we want two permissions to be set
|
||||
if not request.user.has_event_permission(request.organizer, request.event, "event.settings.general:write", request=request):
|
||||
raise PermissionDenied()
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_error_url(self, *args):
|
||||
return reverse(
|
||||
"control:event.orders.checkinlists",
|
||||
|
||||
Reference in New Issue
Block a user