Skip to content

Commit

Permalink
add option to limit the file size for image and file uploads
Browse files Browse the repository at this point in the history
- add a validator to validate the max file size (FileMaxSizeValidator)
- return the first form error in a JsonResponse so it is actually shown to the
  user instead of a generic error message.
- add separate test_settings for pytest (to allow testing with small
  file sizes)
- add tests for file extension and file size
  • Loading branch information
goapunk committed Jul 18, 2024
1 parent b55cb47 commit b52c964
Show file tree
Hide file tree
Showing 11 changed files with 1,019 additions and 357 deletions.
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,17 @@ distinguish between image and file upload. Exposing the file upload to
all/untrusted users poses a risk!
Restrict upload file size:
^^^^^^^^^^^^^^^^^^^^^^^^^^
You can restrict the maximum size for uploaded images and files by adding
.. code-block:: python
CKEDITOR_5_MAX_FILE_SIZE = 5 # Max size in MB
to your config. Default is 0 (allow any file size).
Installing from GitHub:
^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
Expand Down
3 changes: 3 additions & 0 deletions django_ckeditor_5/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.conf import settings
from django.core.validators import FileExtensionValidator

from django_ckeditor_5.validators import FileMaxSizeValidator


class UploadFileForm(forms.Form):
upload = forms.FileField(
Expand All @@ -13,5 +15,6 @@ class UploadFileForm(forms.Form):
["jpg", "jpeg", "png", "gif", "bmp", "webp", "tiff"],
),
),
FileMaxSizeValidator(getattr(settings, "CKEDITOR_5_MAX_FILE_SIZE", 0)),
],
)
40 changes: 40 additions & 0 deletions django_ckeditor_5/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django import get_version
from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible

if get_version() >= "4.0":
from django.utils.translation import gettext_lazy as _
else:
from django.utils.translation import ugettext_lazy as _


@deconstructible()
class FileMaxSizeValidator:
"""Validate that a file is not bigger than max_size mb, otherwise raise ValidationError.
If zero is passed for max_size any file size is allowed.
"""

message = _("File should be at most %(max_size)s MB.")
code = "invalid_size"

def __init__(self, max_size):
self.max_size = max_size * 1024 * 1024
self.orig_max_size = max_size

def __call__(self, value):
if value.size > self.max_size > 0:
raise ValidationError(
self.message,
code=self.code,
params={
"max_size": self.orig_max_size,
},
)

def __eq__(self, other):
return (
isinstance(other, self.__class__)
and self.max_size == other.max_size
and self.message == other.message
and self.code == other.code
)
3 changes: 3 additions & 0 deletions django_ckeditor_5/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,7 @@ def upload_file(request):
if form.is_valid():
url = handle_uploaded_file(request.FILES["upload"])
return JsonResponse({"url": url})
elif form.errors["upload"]:
return JsonResponse({"error": {"message": form.errors["upload"][0]}}, status=400)

raise Http404(_("Page not found."))
Loading

0 comments on commit b52c964

Please sign in to comment.