Use a protocol

This commit is contained in:
Raphael Michel
2026-04-02 15:31:41 +02:00
parent f637e1fcdd
commit 0614a9ebc3
5 changed files with 19 additions and 15 deletions

View File

@@ -47,6 +47,7 @@ from django.utils.formats import localize
from django.utils.translation import gettext, gettext_lazy as _ from django.utils.translation import gettext, gettext_lazy as _
from pretix.base.models import Event from pretix.base.models import Event
from pretix.base.models.auth import PermissionHolder
from pretix.helpers.safe_openpyxl import ( # NOQA: backwards compatibility for plugins using excel_safe from pretix.helpers.safe_openpyxl import ( # NOQA: backwards compatibility for plugins using excel_safe
SafeWorkbook, remove_invalid_excel_chars as excel_safe, SafeWorkbook, remove_invalid_excel_chars as excel_safe,
) )
@@ -59,7 +60,7 @@ class BaseExporter:
This is the base class for all data exporters This is the base class for all data exporters
""" """
def __init__(self, event, organizer, user=None, token=None, device=None, progress_callback=lambda v: None): def __init__(self, event, organizer, permission_holder: PermissionHolder=None, progress_callback=lambda v: None):
""" """
:param event: Event context, can also be a queryset of events for multi-event exports :param event: Event context, can also be a queryset of events for multi-event exports
:param organizer: Organizer context :param organizer: Organizer context
@@ -72,9 +73,7 @@ class BaseExporter:
self.organizer = organizer self.organizer = organizer
self.progress_callback = progress_callback self.progress_callback = progress_callback
self.is_multievent = isinstance(event, QuerySet) self.is_multievent = isinstance(event, QuerySet)
self.user = user self.permission_holder = permission_holder
self.token = token
self.device = device
if isinstance(event, QuerySet): if isinstance(event, QuerySet):
self.events = event self.events = event
self.event = None self.event = None

View File

@@ -38,6 +38,7 @@ import operator
import secrets import secrets
from datetime import timedelta from datetime import timedelta
from functools import reduce from functools import reduce
from typing import Protocol
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import ( from django.contrib.auth.models import (
@@ -67,6 +68,14 @@ class EmailAddressTakenError(IntegrityError):
pass pass
class PermissionHolder(Protocol):
def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool:
...
def has_organizer_permission(self, organizer, perm_name=None, request=None):
...
class UserManager(BaseUserManager): class UserManager(BaseUserManager):
""" """
This is the user manager for our custom user model. See the User This is the user manager for our custom user model. See the User

View File

@@ -229,7 +229,7 @@ class Device(LoggedModel):
""" """
return self._organizer_permission_set() if self.organizer == organizer else set() return self._organizer_permission_set() if self.organizer == organizer else set()
def has_event_permission(self, organizer, event, perm_name=None, request=None) -> bool: def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool:
""" """
Checks if this token is part of a team that grants access of type ``perm_name`` Checks if this token is part of a team that grants access of type ``perm_name``
to the event ``event``. to the event ``event``.
@@ -238,6 +238,7 @@ class Device(LoggedModel):
:param event: The event to check :param event: The event to check
:param perm_name: The permission, e.g. ``event.orders:read`` :param perm_name: The permission, e.g. ``event.orders:read``
:param request: This parameter is ignored and only defined for compatibility reasons. :param request: This parameter is ignored and only defined for compatibility reasons.
:param session_key: This parameter is ignored and only defined for compatibility reasons.
:return: bool :return: bool
""" """
has_event_access = (self.all_events and organizer == self.organizer) or ( has_event_access = (self.all_events and organizer == self.organizer) or (

View File

@@ -556,7 +556,7 @@ class TeamAPIToken(models.Model):
""" """
return self.team.organizer_permission_set() if self.team.organizer == organizer else set() return self.team.organizer_permission_set() if self.team.organizer == organizer else set()
def has_event_permission(self, organizer, event, perm_name=None, request=None) -> bool: def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool:
""" """
Checks if this token is part of a team that grants access of type ``perm_name`` Checks if this token is part of a team that grants access of type ``perm_name``
to the event ``event``. to the event ``event``.
@@ -565,6 +565,7 @@ class TeamAPIToken(models.Model):
:param event: The event to check :param event: The event to check
:param perm_name: The permission, e.g. ``event.orders:read`` :param perm_name: The permission, e.g. ``event.orders:read``
:param request: This parameter is ignored and only defined for compatibility reasons. :param request: This parameter is ignored and only defined for compatibility reasons.
:param session_key: This parameter is ignored and only defined for compatibility reasons.
:return: bool :return: bool
""" """
has_event_access = (self.team.all_events and organizer == self.team.organizer) or ( has_event_access = (self.team.all_events and organizer == self.team.organizer) or (

View File

@@ -214,9 +214,7 @@ def init_event_exporters(event, user=None, token=None, device=None, request=None
exporter: BaseExporter = response( exporter: BaseExporter = response(
event=event, event=event,
organizer=event.organizer, organizer=event.organizer,
user=user, permission_holder=token or device or user,
token=token,
device=device,
**kwargs **kwargs
) )
@@ -253,9 +251,7 @@ def init_organizer_exporters(
exporter: BaseExporter = response( exporter: BaseExporter = response(
event=Event.objects.none(), event=Event.objects.none(),
organizer=organizer, organizer=organizer,
user=user, permission_holder=token or device or user,
token=token,
device=device,
**kwargs, **kwargs,
) )
@@ -312,9 +308,7 @@ def init_organizer_exporters(
exporter: BaseExporter = response( exporter: BaseExporter = response(
event=_event_list_cache[permission_name], event=_event_list_cache[permission_name],
organizer=organizer, organizer=organizer,
user=user, permission_holder=token or device or user,
token=token,
device=device,
**kwargs, **kwargs,
) )