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:
Raphael Michel
2026-03-17 14:43:56 +01:00
committed by GitHub
parent eddde2b6c0
commit df0b580dd6
203 changed files with 5374 additions and 2331 deletions

View File

@@ -55,12 +55,12 @@ your views:
)
class AdminView(EventPermissionRequiredMixin, View):
permission = 'can_view_orders'
permission = 'event.orders:read'
...
@event_permission_required('can_view_orders')
@event_permission_required('event.orders:read')
def admin_view(request, organizer, event):
...
@@ -78,7 +78,7 @@ event-related views, there is also a signal that allows you to add the view to t
@receiver(nav_event, dispatch_uid='friends_tickets_nav')
def navbar_info(sender, request, **kwargs):
url = resolve(request.path_info)
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_vouchers'):
if not request.user.has_event_permission(request.organizer, request.event, 'event.vouchers:read'):
return []
return [{
'label': _('My plugin view'),
@@ -118,7 +118,7 @@ for good integration. If you just want to display a form, you could do it like t
class MySettingsView(EventSettingsViewMixin, EventSettingsFormView):
model = Event
permission = 'can_change_settings'
permission = 'event.settings.general:write'
form_class = MySettingsForm
template_name = 'my_plugin/settings.html'
@@ -204,13 +204,13 @@ In case of ``orga_router`` and ``event_router``, permission checking is done for
in the control panel. However, you need to make sure on your own only to return the correct subset of data! ``request
.event`` and ``request.organizer`` are available as usual.
To require a special permission like ``can_view_orders``, you do not need to inherit from a special ViewSet base
To require a special permission like ``event.orders:read``, you do not need to inherit from a special ViewSet base
class, you can just set the ``permission`` attribute on your viewset:
.. code-block:: python
class MyViewSet(ModelViewSet):
permission = 'can_view_orders'
permission = 'event.orders:read'
...
If you want to check the permission only for some methods of your viewset, you have to do it yourself. Note here that
@@ -220,7 +220,7 @@ following:
.. code-block:: python
perm_holder = (request.auth if isinstance(request.auth, TeamAPIToken) else request.user)
if perm_holder.has_event_permission(request.event.organizer, request.event, 'can_view_orders'):
if perm_holder.has_event_permission(request.event.organizer, request.event, 'event.orders:read'):
...

View File

@@ -80,8 +80,24 @@ The exporter class
.. autoattribute:: category
.. autoattribute:: feature
.. autoattribute:: export_form_fields
.. autoattribute:: repeatable_read
.. automethod:: render
This is an abstract method, you **must** override this!
.. automethod:: available_for_user
.. automethod:: get_required_event_permission
On organizer level, by default exporters are expected to handle on a *set of events* and the system will automatically
add a form field that allows the selection of events, limited to events the user has correct permissions for. If this
does not fit your organizer, because it is not related to events, you should **also** inherit from the following class:
.. class:: pretix.base.exporter.OrganizerLevelExportMixin
.. automethod:: get_required_organizer_permission

View File

@@ -14,7 +14,8 @@ Core
:members: periodic_task, event_live_issues, event_copy_data, email_filter, register_notification_types, notification,
item_copy_data, register_sales_channel_types, register_global_settings, quota_availability, global_email_filter,
register_ticket_secret_generators, gift_card_transaction_display,
register_text_placeholders, register_mail_placeholders, device_info_updated
register_text_placeholders, register_mail_placeholders, device_info_updated,
register_event_permission_groups, register_organizer_permission_groups
Order events
""""""""""""