diff --git a/doc/admin/config.rst b/doc/admin/config.rst index 7acd7cd1b..878a5ceb5 100644 --- a/doc/admin/config.rst +++ b/doc/admin/config.rst @@ -434,3 +434,19 @@ pretix can make use of some external tools if they are installed. Currently, the .. _Python documentation: https://docs.python.org/3/library/configparser.html?highlight=configparser#supported-ini-file-structure .. _Celery documentation: http://docs.celeryproject.org/en/latest/userguide/configuration.html + +Maximum upload file sizes +------------------------- + +You can configure the maximum file size for uploading various files:: + + [pretix_file_upload] + ; Max upload size for images in MiB, defaults to 10 MiB + max_size_image = 12 + ; Max upload size for favicons in MiB, defaults to 1 MiB + max_size_favicon = 2 + ; Max upload size for email attachments in MiB, defaults to 10 MiB + max_size_email_attachment = 15 + ; Max upload size for other files in MiB, defaults to 10 MiB + ; This includes all file upload type order questions + max_size_other = 100 diff --git a/src/pretix/api/serializers/item.py b/src/pretix/api/serializers/item.py index 58ebf999e..84938d9c7 100644 --- a/src/pretix/api/serializers/item.py +++ b/src/pretix/api/serializers/item.py @@ -34,6 +34,7 @@ import os.path from decimal import Decimal +from django.conf import settings from django.core.exceptions import ValidationError from django.db import transaction from django.db.models import QuerySet @@ -161,7 +162,7 @@ class ItemSerializer(I18nAwareModelSerializer): meta_data = MetaDataField(required=False, source='*') picture = UploadedFileField(required=False, allow_null=True, allowed_types=( 'image/png', 'image/jpeg', 'image/gif' - ), max_size=10 * 1024 * 1024) + ), max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE) class Meta: model = Item diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index f4267f734..1b08d4994 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -26,6 +26,7 @@ from collections import Counter, defaultdict from decimal import Decimal import pycountry +from django.conf import settings from django.core.files import File from django.db.models import F, Q from django.utils.timezone import now @@ -191,7 +192,7 @@ class AnswerSerializer(I18nAwareModelSerializer): ) if cf.type not in allowed_types: raise ValidationError('The submitted file "{fid}" has a file type that is not allowed in this field.'.format(fid=data)) - if cf.file.size > 10 * 1024 * 1024: + if cf.file.size > settings.FILE_UPLOAD_MAX_SIZE_OTHER: raise ValidationError('The submitted file "{fid}" is too large to be used in this field.'.format(fid=data)) data['options'] = [] diff --git a/src/pretix/api/views/checkin.py b/src/pretix/api/views/checkin.py index 15a1eb71a..e246df59c 100644 --- a/src/pretix/api/views/checkin.py +++ b/src/pretix/api/views/checkin.py @@ -20,6 +20,7 @@ # . # import django_filters +from django.conf import settings from django.core.exceptions import ValidationError from django.db import transaction from django.db.models import ( @@ -603,7 +604,7 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet): ) if cf.type not in allowed_types: raise ValidationError('The submitted file "{fid}" has a file type that is not allowed in this field.'.format(fid=data)) - if cf.file.size > 10 * 1024 * 1024: + if cf.file.size > settings.FILE_UPLOAD_MAX_SIZE_OTHER: raise ValidationError('The submitted file "{fid}" is too large to be used in this field.'.format(fid=data)) return cf.file diff --git a/src/pretix/base/forms/questions.py b/src/pretix/base/forms/questions.py index 3d5cbf963..f65dc1fd1 100644 --- a/src/pretix/base/forms/questions.py +++ b/src/pretix/base/forms/questions.py @@ -46,6 +46,7 @@ import vat_moss.errors import vat_moss.id from babel import Locale from django import forms +from django.conf import settings from django.contrib import messages from django.core.exceptions import ValidationError from django.core.files.uploadedfile import SimpleUploadedFile @@ -507,7 +508,7 @@ class PortraitImageField(SizeValidationMixin, ExtValidationMixin, forms.FileFiel def __init__(self, *args, **kwargs): kwargs.setdefault('ext_whitelist', (".png", ".jpg", ".jpeg", ".jfif", ".tif", ".tiff", ".bmp")) - kwargs.setdefault('max_size', 10 * 1024 * 1024) + kwargs.setdefault('max_size', settings.FILE_UPLOAD_MAX_SIZE_IMAGE) super().__init__(*args, **kwargs) @@ -739,7 +740,7 @@ class BaseQuestionsForm(forms.Form): ".pptx", ".ppt", ".doc", ".xlsx", ".xls", ".jfif", ".heic", ".heif", ".pages", ".bmp", ".tif", ".tiff" ), - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_OTHER, ) elif q.type == Question.TYPE_DATE: attrs = {} diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index 0533f37bf..82360f45b 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -404,7 +404,7 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st logger.exception('Could not attach invoice to email') pass - if attach_size < 4 * 1024 * 1024: + if attach_size < settings.FILE_UPLOAD_MAX_SIZE_EMAIL_ATTACHMENT: # Do not attach more than 4MB, it will bounce way to often. for a in args: try: diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 61cb6dcaa..49f754b06 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -2059,7 +2059,7 @@ Your {organizer} team""")) 'form_kwargs': dict( label=_('Header image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, 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 ' @@ -2070,7 +2070,7 @@ Your {organizer} team""")) allowed_types=[ 'image/png', 'image/jpeg', 'image/gif' ], - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, ) }, @@ -2101,7 +2101,7 @@ Your {organizer} team""")) 'form_kwargs': dict( label=_('Header image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, 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 ' 'can increase the size with the setting below. We recommend not using small details on the picture ' @@ -2112,7 +2112,7 @@ Your {organizer} team""")) allowed_types=[ 'image/png', 'image/jpeg', 'image/gif' ], - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, ) }, 'organizer_logo_image_large': { @@ -2132,7 +2132,7 @@ Your {organizer} team""")) 'form_kwargs': dict( label=_('Social media image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, 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 ' @@ -2143,7 +2143,7 @@ Your {organizer} team""")) allowed_types=[ 'image/png', 'image/jpeg', 'image/gif' ], - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, ) }, 'invoice_logo_image': { @@ -2154,7 +2154,7 @@ Your {organizer} team""")) label=_('Logo image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), required=False, - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, help_text=_('We will show your logo with a maximal height and width of 2.5 cm.') ), 'serializer_class': UploadedFileField, @@ -2162,7 +2162,7 @@ Your {organizer} team""")) allowed_types=[ 'image/png', 'image/jpeg', 'image/gif' ], - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, ) }, 'frontpage_text': { diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py index 7badbb5a3..868762af7 100644 --- a/src/pretix/control/forms/organizer.py +++ b/src/pretix/control/forms/organizer.py @@ -313,7 +313,7 @@ class OrganizerSettingsForm(SettingsForm): organizer_logo_image = ExtFileField( label=_('Header image'), ext_whitelist=(".png", ".jpg", ".gif", ".jpeg"), - max_size=10 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE, 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 ' @@ -324,7 +324,7 @@ class OrganizerSettingsForm(SettingsForm): label=_('Favicon'), ext_whitelist=(".ico", ".png", ".jpg", ".gif", ".jpeg"), required=False, - max_size=1 * 1024 * 1024, + max_size=settings.FILE_UPLOAD_MAX_SIZE_FAVICON, 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.') ) diff --git a/src/pretix/control/views/orderimport.py b/src/pretix/control/views/orderimport.py index fba81db7a..991987740 100644 --- a/src/pretix/control/views/orderimport.py +++ b/src/pretix/control/views/orderimport.py @@ -69,7 +69,7 @@ class ImportView(EventPermissionRequiredMixin, TemplateView): 'event': request.event.slug, 'organizer': request.organizer.slug, })) - if request.FILES['file'].size > 1024 * 1024 * 10: + if request.FILES['file'].size > settings.FILE_UPLOAD_MAX_SIZE_OTHER: messages.error(request, _('Please do not upload files larger than 10 MB.')) return redirect(reverse('control:event.orders.import', kwargs={ 'event': request.event.slug, diff --git a/src/pretix/control/views/pdf.py b/src/pretix/control/views/pdf.py index d364df248..cf67bc5a2 100644 --- a/src/pretix/control/views/pdf.py +++ b/src/pretix/control/views/pdf.py @@ -58,7 +58,7 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView): accepted_formats = ( 'application/pdf', ) - maxfilesize = 1024 * 1024 * 10 + maxfilesize = settings.FILE_UPLOAD_MAX_SIZE_IMAGE minfilesize = 10 title = None diff --git a/src/pretix/plugins/sendmail/forms.py b/src/pretix/plugins/sendmail/forms.py index 0a9a384de..c90881654 100644 --- a/src/pretix/plugins/sendmail/forms.py +++ b/src/pretix/plugins/sendmail/forms.py @@ -34,6 +34,7 @@ # License for the specific language governing permissions and limitations under the License. from django import forms +from django.conf import settings from django.core.exceptions import ValidationError from django.urls import reverse from django.utils.translation import gettext_lazy as _, pgettext_lazy @@ -89,7 +90,7 @@ class MailForm(FormPlaceholderMixin, forms.Form): ), help_text=_('Sending an attachment increases the chance of your email not arriving or being sorted into spam folders. We recommend only using PDFs ' 'of no more than 2 MB in size.'), - max_size=10 * 1024 * 1024 + max_size=settings.FILE_UPLOAD_MAX_SIZE_EMAIL_ATTACHMENT ) # TODO i18n items = forms.ModelMultipleChoiceField( widget=forms.CheckboxSelectMultiple( diff --git a/src/pretix/settings.py b/src/pretix/settings.py index e9db10e07..223c3586c 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -845,4 +845,10 @@ COUNTRIES_OVERRIDE = { DATA_UPLOAD_MAX_NUMBER_FIELDS = 25000 DATA_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10 MB +# File sizes are in MiB +FILE_UPLOAD_MAX_SIZE_IMAGE = 1024 * 1024 * config.getint("pretix_file_upload", "max_size_image", fallback=10) +FILE_UPLOAD_MAX_SIZE_FAVICON = 1024 * 1024 * config.getint("pretix_file_upload", "max_size_favicon", fallback=1) +FILE_UPLOAD_MAX_SIZE_EMAIL_ATTACHMENT = 1024 * 1024 * config.getint("pretix_file_upload", "max_size_email_attachment", fallback=10) +FILE_UPLOAD_MAX_SIZE_OTHER = 1024 * 1024 * config.getint("pretix_file_upload", "max_size_other", fallback=10) + DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' # sadly. we would prefer BigInt, and should use it for all new models but the migration will be hard