Add filter_restricted / allow_restricted params

This commit is contained in:
Mira Weller
2026-09-25 18:39:56 +02:00
parent 88a0482838
commit e518b3f06c
7 changed files with 27 additions and 35 deletions
+3 -6
View File
@@ -269,16 +269,13 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
def validate_plugins(self, value):
current_plugins = self.instance.get_plugins() if self.instance and self.instance.pk else []
settings_holder = self.instance if self.instance and self.instance.pk else self.context['organizer']
plugins_available = settings_holder.get_available_plugins()
obj = self.instance if self.instance and self.instance.pk else self.context['organizer']
plugins_available = obj.get_available_plugins(filter_restricted=True)
allowed_levels = (PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID)
for plugin in value.get('plugins'):
if plugin not in plugins_available:
raise ValidationError(_('Unknown plugin: \'{name}\'.').format(name=plugin))
if getattr(plugins_available[plugin], 'restricted', False):
if plugin not in settings_holder.settings.allowed_restricted_plugins:
raise ValidationError(_('Restricted plugin: \'{name}\'.').format(name=plugin))
raise ValidationError(_('Unknown or restricted plugin: \'{name}\'.').format(name=plugin))
level = getattr(plugins_available[plugin], 'level', PLUGIN_LEVEL_EVENT)
if level not in allowed_levels:
raise ValidationError('Plugin cannot be enabled on this level: \'{name}\'.'.format(name=plugin))
+2 -6
View File
@@ -80,16 +80,12 @@ class OrganizerSerializer(I18nAwareModelSerializer):
fields = ('name', 'slug', 'public_url', 'plugins')
def validate_plugins(self, value):
plugins_available = self.instance.get_available_plugins()
settings_holder = self.instance
plugins_available = self.instance.get_available_plugins(filter_restricted=True)
allowed_levels = (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID)
for plugin in value.get('plugins'):
if plugin not in plugins_available:
raise ValidationError(_('Unknown plugin: \'{name}\'.').format(name=plugin))
if getattr(plugins_available[plugin], 'restricted', False):
if plugin not in settings_holder.settings.allowed_restricted_plugins:
raise ValidationError(_('Restricted plugin: \'{name}\'.').format(name=plugin))
raise ValidationError(_('Unknown or restricted plugin: \'{name}\'.').format(name=plugin))
if getattr(plugins_available[plugin], 'level', PLUGIN_LEVEL_EVENT) not in allowed_levels:
raise ValidationError('Plugin cannot be enabled on this level: \'{name}\'.'.format(name=plugin))
+3 -3
View File
@@ -1466,10 +1466,10 @@ class Event(PluginsMixin, EventMixin, LoggedModel):
self.items.all().delete()
self.subevents.all().delete()
def get_available_plugins(self):
from pretix.base.plugins import get_all_plugins_map
def get_available_plugins(self, filter_restricted=False):
from pretix.base.plugins import get_all_plugins_map, ALLOW_ALL
return get_all_plugins_map(event=self, only_visible=True)
return get_all_plugins_map(event=self, only_visible=True, allow_restricted=self.settings.allowed_restricted_plugins if filter_restricted else ALLOW_ALL)
@staticmethod
def clean_has_subevents(event, has_subevents):
+3 -3
View File
@@ -166,10 +166,10 @@ class Organizer(PluginsMixin, LoggedModel):
return ObjectRelatedCache(self)
def get_available_plugins(self):
from pretix.base.plugins import get_all_plugins_map
def get_available_plugins(self, *, filter_restricted=False):
from pretix.base.plugins import get_all_plugins_map, ALLOW_ALL
return get_all_plugins_map(organizer=self, only_visible=True)
return get_all_plugins_map(organizer=self, only_visible=True, allow_restricted=self.settings.allowed_restricted_plugins if filter_restricted else ALLOW_ALL)
@property
def timezone(self):
+14 -7
View File
@@ -37,6 +37,10 @@ PLUGIN_LEVEL_ORGANIZER = 'organizer'
PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID = 'event_organizer'
class ALLOW_ALL:
pass
class PluginType(Enum):
"""
Plugin type classification. THIS IS DEPRECATED, DO NOT USE ANY MORE.
@@ -49,10 +53,13 @@ class PluginType(Enum):
EXPORT = 4
def plugin_is_available(meta, event=None, organizer=None, only_visible=False):
def plugin_is_available(meta, event=None, organizer=None, only_visible=False, allow_restricted: type[ALLOW_ALL] | List[str]=ALLOW_ALL):
if only_visible and (meta.name.startswith('.') or not getattr(meta, 'visible', True)):
return False
if allow_restricted is not ALLOW_ALL and getattr(meta, 'restricted', False) and meta.module not in allow_restricted:
return False
if not hasattr(meta.app, 'is_available'):
return True
@@ -90,15 +97,15 @@ def get_plugin_meta_from_app_config(app):
return meta
def iter_all_plugins(*, event=None, organizer=None, only_visible=False) -> Iterable[type]:
def iter_all_plugins(*, event=None, organizer=None, only_visible=False, allow_restricted: type[ALLOW_ALL] | List[str]=ALLOW_ALL) -> Iterable[type]:
assert not event or not organizer
for app in apps.get_app_configs():
if meta := get_plugin_meta_from_app_config(app):
if plugin_is_available(meta, event, organizer, only_visible):
if plugin_is_available(meta, event, organizer, only_visible, allow_restricted):
yield meta
def get_all_plugins(*, event=None, organizer=None, only_visible=False) -> List[type]:
def get_all_plugins(*, event=None, organizer=None, only_visible=False, allow_restricted: type[ALLOW_ALL] | List[str]=ALLOW_ALL) -> List[type]:
"""
Returns the PretixPluginMeta classes of all plugins found in the installed Django apps.
@@ -106,14 +113,14 @@ def get_all_plugins(*, event=None, organizer=None, only_visible=False) -> List[t
calling `is_available`, not for filtering by plugin level.
"""
return sorted(
iter_all_plugins(event=event, organizer=organizer, only_visible=only_visible),
iter_all_plugins(event=event, organizer=organizer, only_visible=only_visible, allow_restricted=allow_restricted),
key=lambda m: (0 if m.module.startswith('pretix.') else 1, str(m.name).lower().replace('pretix ', ''))
)
def get_all_plugins_map(*, event=None, organizer=None, only_visible=False) -> dict[str, type]:
def get_all_plugins_map(*, event=None, organizer=None, only_visible=False, allow_restricted: type[ALLOW_ALL] | List[str]=ALLOW_ALL) -> dict[str, type]:
return {
p.module: p for p in iter_all_plugins(event=event, organizer=organizer, only_visible=only_visible)
p.module: p for p in iter_all_plugins(event=event, organizer=organizer, only_visible=only_visible, allow_restricted=allow_restricted)
}
+1 -5
View File
@@ -432,7 +432,7 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
def post(self, request, *args, **kwargs):
self.object = self.get_object()
plugins_available = self.object.get_available_plugins()
plugins_available = self.object.get_available_plugins(filter_restricted=True)
plugin_enabled = None
with transaction.atomic():
@@ -442,10 +442,6 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
module = key.split(":")[1]
if value == "enable" and module in plugins_available:
pluginmeta = plugins_available[module]
if getattr(pluginmeta, 'restricted', False):
if module not in request.event.settings.allowed_restricted_plugins:
continue
if getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT) not in (PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID):
continue
+1 -5
View File
@@ -676,7 +676,7 @@ class OrganizerPlugins(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
def post(self, request, *args, **kwargs):
self.object = self.get_object()
plugins_available = self.object.get_available_plugins()
plugins_available = self.object.get_available_plugins(filter_restricted=True)
choose_events_next = False
with transaction.atomic():
for key, value in request.POST.items():
@@ -684,10 +684,6 @@ class OrganizerPlugins(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
module = key.split(":")[1]
if value == "enable" and module in plugins_available:
pluginmeta = plugins_available[module]
if getattr(pluginmeta, 'restricted', False):
if module not in request.organizer.settings.allowed_restricted_plugins:
continue
level = getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT)
if level not in (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID):
continue