diff --git a/doc/development/api/plugins.rst b/doc/development/api/plugins.rst index 9aa8c96b17..a6a5a5cc9b 100644 --- a/doc/development/api/plugins.rst +++ b/doc/development/api/plugins.rst @@ -92,6 +92,7 @@ those will be displayed but not block the plugin execution. The ``AppConfig`` class may implement a method ``is_available(event)`` that checks if a plugin is available for a specific event. If not, it will not be shown in the plugin list of that event. +You should not define ``is_available`` and ``restricted`` on the same plugin. Plugin registration ------------------- diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index c721dccdae..7501b63b83 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -1179,21 +1179,21 @@ class Event(EventMixin, LoggedModel): if not p.name.startswith('.') and getattr(p, 'visible', True) } - def set_active_plugins(self, modules, allow_restricted=False): + def set_active_plugins(self, modules, allow_restricted=frozenset()): plugins_active = self.get_plugins() plugins_available = self.get_available_plugins() enable = [m for m in modules if m not in plugins_active and m in plugins_available] for module in enable: - if getattr(plugins_available[module].app, 'restricted', False) and not allow_restricted: + if getattr(plugins_available[module].app, 'restricted', False) and module not in allow_restricted: modules.remove(module) elif hasattr(plugins_available[module].app, 'installed'): getattr(plugins_available[module].app, 'installed')(self) self.plugins = ",".join(modules) - def enable_plugin(self, module, allow_restricted=False): + def enable_plugin(self, module, allow_restricted=frozenset()): plugins_active = self.get_plugins() from pretix.presale.style import regenerate_css diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 339441f427..5c3f9400d6 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -94,6 +94,25 @@ def primary_font_kwargs(): } +def restricted_plugin_kwargs(): + from pretix.base.plugins import get_all_plugins + + plugins_available = [ + (p.module, p.name) for p in get_all_plugins(None) + if ( + not p.name.startswith('.') and + getattr(p, 'visible', True) and + getattr(p, 'restricted', False) and + not hasattr(p, 'is_available') # this means you should not really use restricted and is_available + ) + ] + return { + 'widget': forms.CheckboxSelectMultiple, + 'label': _("Allow usage of restricted plugins"), + 'choices': plugins_available, + } + + class LazyI18nStringList(UserList): def __init__(self, init_list=None): super().__init__() @@ -109,6 +128,13 @@ class LazyI18nStringList(UserList): DEFAULTS = { + 'allowed_restricted_plugins': { + 'default': [], + 'type': list, + 'form_class': forms.MultipleChoiceField, + 'serializer_class': serializers.MultipleChoiceField, + 'form_kwargs': lambda: restricted_plugin_kwargs(), + }, 'customer_accounts': { 'default': 'False', 'type': bool, diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py index 09965764b0..28539980da 100644 --- a/src/pretix/control/forms/organizer.py +++ b/src/pretix/control/forms/organizer.py @@ -286,6 +286,7 @@ class OrganizerSettingsForm(SettingsForm): required=False, ) auto_fields = [ + 'allowed_restricted_plugins', 'customer_accounts', 'customer_accounts_link_by_email', 'invoice_regenerate_allowed', @@ -339,7 +340,12 @@ class OrganizerSettingsForm(SettingsForm): ) def __init__(self, *args, **kwargs): + is_admin = kwargs.pop('is_admin', False) super().__init__(*args, **kwargs) + + if not is_admin: + del self.fields['allowed_restricted_plugins'] + self.fields['name_scheme'].choices = ( (k, _('Ask for {fields}, display like {example}').format( fields=' + '.join(str(vv[1]) for vv in v['fields']), diff --git a/src/pretix/control/templates/pretixcontrol/event/plugins.html b/src/pretix/control/templates/pretixcontrol/event/plugins.html index 428169da40..6d81083c62 100644 --- a/src/pretix/control/templates/pretixcontrol/event/plugins.html +++ b/src/pretix/control/templates/pretixcontrol/event/plugins.html @@ -32,9 +32,9 @@ {% endblocktrans %}
{% endif %}{{ plugin.description }}
- {% if plugin.restricted and not request.user.is_staff %} + {% if plugin.restricted and plugin.module not in request.event.settings.allowed_restricted_plugins %} - {% trans "This plugin needs to be enabled by a system administrator for your event." %} + {% trans "This plugin needs to be enabled by a system administrator for your account." %} {% endif %} {% if plugin.app.compatibility_errors %} @@ -62,7 +62,7 @@ {% if plugin.app.compatibility_errors %} - {% elif plugin.restricted and not staff_session %} + {% elif plugin.restricted and plugin.module not in request.event.settings.allowed_restricted_plugins %} {% elif plugin.module in plugins_active %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/edit.html b/src/pretix/control/templates/pretixcontrol/organizers/edit.html index 34bc2520e0..4018db1bc9 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/edit.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/edit.html @@ -36,6 +36,9 @@ {% bootstrap_field sform.contact_mail layout="control" %} {% bootstrap_field sform.organizer_info_text layout="control" %} {% bootstrap_field sform.event_team_provisioning layout="control" %} + {% if sform.allowed_restricted_plugins %} + {% bootstrap_field sform.allowed_restricted_plugins layout="control" %} + {% endif %}