From b51ca588209e4318114f8d0c8e30a3ff6d7145b0 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 16 Jun 2023 17:33:14 +0200 Subject: [PATCH] Add BaseExporter.available_for_user() --- src/pretix/api/views/exporters.py | 9 +++++++-- src/pretix/base/exporter.py | 7 +++++++ src/pretix/base/services/export.py | 2 ++ src/pretix/control/views/orders.py | 7 ++++++- src/pretix/control/views/organizer.py | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/pretix/api/views/exporters.py b/src/pretix/api/views/exporters.py index 3a82163a25..e641e7d89a 100644 --- a/src/pretix/api/views/exporters.py +++ b/src/pretix/api/views/exporters.py @@ -133,7 +133,12 @@ class EventExportersViewSet(ExportersMixin, viewsets.ViewSet): def exporters(self): exporters = [] responses = register_data_exporters.send(self.request.event) - for ex in sorted([response(self.request.event, self.request.organizer) for r, response in responses if response], key=lambda ex: str(ex.verbose_name)): + raw_exporters = [response(self.request.event, self.request.organizer) for r, response in responses if response] + raw_exporters = [ + ex for ex in raw_exporters + if ex.available_for_user(self.request.user if self.request.user and self.request.user.is_authenticated else None) + ] + for ex in sorted(raw_exporters, key=lambda ex: str(ex.verbose_name)): ex._serializer = JobRunSerializer(exporter=ex) exporters.append(ex) return exporters @@ -166,7 +171,7 @@ class OrganizerExportersViewSet(ExportersMixin, viewsets.ViewSet): if ( not isinstance(ex, OrganizerLevelExportMixin) or perm_holder.has_organizer_permission(self.request.organizer, ex.organizer_required_permission, self.request) - ) + ) and ex.available_for_user(self.request.user if self.request.user and self.request.user.is_authenticated else None) ] for ex in sorted(raw_exporters, key=lambda ex: str(ex.verbose_name)): ex._serializer = JobRunSerializer(exporter=ex, events=events) diff --git a/src/pretix/base/exporter.py b/src/pretix/base/exporter.py index 2b911f05ba..e47854ad4b 100644 --- a/src/pretix/base/exporter.py +++ b/src/pretix/base/exporter.py @@ -157,6 +157,13 @@ class BaseExporter: """ raise NotImplementedError() # NOQA + def available_for_user(self, user) -> bool: + """ + Allows to do additional checks whether an exporter is available based on the user who calls it. Note that + ``user`` may be ``None`` e.g. during API usage. + """ + return True + class OrganizerLevelExportMixin: @property diff --git a/src/pretix/base/services/export.py b/src/pretix/base/services/export.py index d902347aaa..de4197c59a 100644 --- a/src/pretix/base/services/export.py +++ b/src/pretix/base/services/export.py @@ -290,6 +290,8 @@ def scheduled_organizer_export(self, organizer: Organizer, schedule: int) -> Non if isinstance(exporter, OrganizerLevelExportMixin): if not schedule.owner.has_organizer_permission(organizer, exporter.organizer_required_permission): has_permission = False + if exporter and not exporter.available_for_user(schedule.owner): + has_permission = False _run_scheduled_export( schedule, diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index 6f37215251..83c2b53b26 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -2261,8 +2261,13 @@ class ExportMixin: @cached_property def exporters(self): responses = register_data_exporters.send(self.request.event) + raw_exporters = [response(self.request.event, self.request.organizer) for r, response in responses if response] + raw_exporters = [ + ex for ex in raw_exporters + if ex.available_for_user(self.request.user if self.request.user and self.request.user.is_authenticated else None) + ] return sorted( - [response(self.request.event, self.request.organizer) for r, response in responses if response], + raw_exporters, key=lambda ex: (0 if ex.category else 1, ex.category or "", 0 if ex.featured else 1, str(ex.verbose_name).lower()) ) diff --git a/src/pretix/control/views/organizer.py b/src/pretix/control/views/organizer.py index 3cf86129f0..62747aa64e 100644 --- a/src/pretix/control/views/organizer.py +++ b/src/pretix/control/views/organizer.py @@ -1694,7 +1694,7 @@ class ExportMixin: not isinstance(ex, OrganizerLevelExportMixin) or self.request.user.has_organizer_permission(self.request.organizer, ex.organizer_required_permission, self.request) - ) + ) and ex.available_for_user(self.request.user if self.request.user and self.request.user.is_authenticated else None) ] return sorted( raw_exporters,