From 27b56b5aeaa972180f27e4c797dc3042666e3706 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 22 May 2020 15:01:18 +0200 Subject: [PATCH] Limit extensions and sizes of further file uploads --- src/pretix/base/forms/questions.py | 10 ++++++++-- src/pretix/control/forms/__init__.py | 25 ++++++++++++++++++++++++- src/pretix/control/forms/event.py | 3 +++ src/pretix/control/forms/organizer.py | 2 ++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/pretix/base/forms/questions.py b/src/pretix/base/forms/questions.py index 328387322..5748dbb20 100644 --- a/src/pretix/base/forms/questions.py +++ b/src/pretix/base/forms/questions.py @@ -40,7 +40,7 @@ from pretix.base.settings import ( PERSON_NAME_TITLE_GROUPS, ) from pretix.base.templatetags.rich_text import rich_text -from pretix.control.forms import SplitDateTimeField +from pretix.control.forms import ExtFileField, SplitDateTimeField from pretix.helpers.countries import CachedCountries from pretix.helpers.escapejson import escapejson_attr from pretix.helpers.i18n import get_format_without_seconds @@ -412,11 +412,17 @@ class BaseQuestionsForm(forms.Form): initial=initial.options.all() if initial else None, ) elif q.type == Question.TYPE_FILE: - field = forms.FileField( + field = ExtFileField( label=label, required=required, help_text=help_text, initial=initial.file if initial else None, widget=UploadedFileWidget(position=pos, event=event, answer=initial), + ext_whitelist=( + ".png", ".jpg", ".gif", ".jpeg", ".pdf", ".txt", ".docx", ".gif", ".svg", + ".pptx", ".ppt", ".doc", ".xlsx", ".xls", ".jfif", ".heic", ".heif", ".pages", + ".bmp", ".tif", ".tiff" + ), + max_size=10 * 1024 * 1024, ) elif q.type == Question.TYPE_DATE: field = forms.DateField( diff --git a/src/pretix/control/forms/__init__.py b/src/pretix/control/forms/__init__.py index c8ee4af09..005f1abf1 100644 --- a/src/pretix/control/forms/__init__.py +++ b/src/pretix/control/forms/__init__.py @@ -94,7 +94,30 @@ class ClearableBasenameFileInput(forms.ClearableFileInput): return ctx -class ExtFileField(forms.FileField): +class SizeFileField(forms.FileField): + + def __init__(self, *args, **kwargs): + self.max_size = kwargs.pop("max_size") + super().__init__(*args, **kwargs) + + @staticmethod + def _sizeof_fmt(num, suffix='B'): + for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']: + if abs(num) < 1024.0: + return "%3.1f%s%s" % (num, unit, suffix) + num /= 1024.0 + return "%.1f%s%s" % (num, 'Yi', suffix) + + def clean(self, *args, **kwargs): + data = super().clean(*args, **kwargs) + if data and self.max_size and data.file.size > self.max_size: + raise forms.ValidationError(_("Please do not upload files larger than {size}!").format( + SizeFileField._sizeof_fmt(self.max_size) + )) + return data + + +class ExtFileField(SizeFileField): widget = ClearableBasenameFileInput def __init__(self, *args, **kwargs): diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index af14971ab..1de4b3167 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -409,6 +409,7 @@ class EventSettingsForm(SettingsForm): label=_('Header image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), required=False, + max_size=10 * 1024 * 1024, help_text=_('If you provide a logo image, we will by default not show your event name and date ' 'in the page header. By default, we show your logo with a size of up to 1140x120 pixels. You ' 'can increase the size with the setting below. We recommend not using small details on the picture ' @@ -428,6 +429,7 @@ class EventSettingsForm(SettingsForm): label=_('Social media image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), required=False, + max_size=10 * 1024 * 1024, help_text=_('This picture will be used as a preview if you post links to your ticket shop on social media. ' 'Facebook advises to use a picture size of 1200 x 630 pixels, however some platforms like ' 'WhatsApp and Reddit only show a square preview, so we recommend to make sure it still looks good ' @@ -712,6 +714,7 @@ class InvoiceSettingsForm(SettingsForm): label=_('Logo image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), required=False, + max_size=10 * 1024 * 1024, help_text=_('We will show your logo with a maximal height and width of 2.5 cm.') ) diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py index 4e36bf8a9..f2176b256 100644 --- a/src/pretix/control/forms/organizer.py +++ b/src/pretix/control/forms/organizer.py @@ -275,6 +275,7 @@ class OrganizerSettingsForm(SettingsForm): organizer_logo_image = ExtFileField( label=_('Header image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), + max_size=10 * 1024 * 1024, required=False, help_text=_('If you provide a logo image, we will by default not show your organization name ' 'in the page header. By default, we show your logo with a size of up to 1140x120 pixels. You ' @@ -323,6 +324,7 @@ class OrganizerSettingsForm(SettingsForm): label=_('Favicon'), ext_whitelist=(".ico", ".png", ".jpg", ".gif", ".jpeg"), required=False, + max_size=1 * 1024 * 1024, help_text=_('If you provide a favicon, we will show it instead of the default pretix icon. ' 'We recommend a size of at least 200x200px to accommodate most devices.') )