Change restricted plugins from event-level action to org-level whitelist (#2489)

This commit is contained in:
Raphael Michel
2022-02-23 15:04:16 +01:00
committed by GitHub
parent 65fb492728
commit 14e0d9cbf4
9 changed files with 47 additions and 12 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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']),

View File

@@ -32,9 +32,9 @@
{% endblocktrans %}</p>
{% endif %}
<p>{{ plugin.description }}</p>
{% if plugin.restricted and not request.user.is_staff %}
{% if plugin.restricted and plugin.module not in request.event.settings.allowed_restricted_plugins %}
<span class="text-muted">
{% 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." %}
</span>
{% endif %}
{% if plugin.app.compatibility_errors %}
@@ -62,7 +62,7 @@
{% if plugin.app.compatibility_errors %}
<button class="btn disabled btn-block btn-default"
disabled="disabled">{% trans "Incompatible" %}</button>
{% elif plugin.restricted and not staff_session %}
{% elif plugin.restricted and plugin.module not in request.event.settings.allowed_restricted_plugins %}
<button class="btn disabled btn-block btn-default"
disabled="disabled">{% trans "Not available" %}</button>
{% elif plugin.module in plugins_active %}

View File

@@ -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 %}
</fieldset>
<fieldset>
<legend>{% trans "Organizer page" %}</legend>

View File

@@ -354,19 +354,17 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
}
with transaction.atomic():
allow_restricted = request.user.has_active_staff_session(request.session.session_key)
for key, value in request.POST.items():
if key.startswith("plugin:"):
module = key.split(":")[1]
if value == "enable" and module in plugins_available:
if getattr(plugins_available[module], 'restricted', False):
if not allow_restricted:
if module not in request.event.settings.allowed_restricted_plugins:
continue
self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user,
data={'plugin': module})
self.object.enable_plugin(module, allow_restricted=allow_restricted)
self.object.enable_plugin(module, allow_restricted=request.event.settings.allowed_restricted_plugins)
else:
self.request.event.log_action('pretix.event.plugins.disabled', user=self.request.user,
data={'plugin': module})
@@ -1415,7 +1413,7 @@ class QuickSetupView(FormView):
})
quota.items.add(*items)
self.request.event.set_active_plugins(plugins_active, allow_restricted=True)
self.request.event.set_active_plugins(plugins_active, allow_restricted=plugins_active)
self.request.event.save()
messages.success(self.request, _('Your changes have been saved. You can now go on with looking at the details '
'or take your event live to start selling!'))

View File

@@ -265,7 +265,7 @@ class EventWizard(SafeSessionWizardView):
event.has_subevents = foundation_data['has_subevents']
event.testmode = True
form_dict['basics'].save()
event.set_active_plugins(settings.PRETIX_PLUGINS_DEFAULT.split(","), allow_restricted=True)
event.set_active_plugins(settings.PRETIX_PLUGINS_DEFAULT.split(","), allow_restricted=settings.PRETIX_PLUGINS_DEFAULT.split(","))
event.save(update_fields=['plugins'])
event.log_action(
'pretix.event.added',

View File

@@ -407,6 +407,7 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
return OrganizerSettingsForm(
obj=self.object,
prefix='settings',
is_admin=self.request.user.has_active_staff_session(self.request.session.session_key),
data=self.request.POST if self.request.method == 'POST' else None,
files=self.request.FILES if self.request.method == 'POST' else None
)