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 Aug 5, 2024
1 parent 846608d commit 3e1c726
Show file tree
Hide file tree
Showing 9 changed files with 741 additions and 356 deletions.
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,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
)
5 changes: 5 additions & 0 deletions django_ckeditor_5/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,9 @@ def upload_file(request):
url = handle_uploaded_file(request.FILES["upload"])
return JsonResponse({"url": url})

if form.errors["upload"]:
return JsonResponse(
{"error": {"message": form.errors["upload"][0]}}, status=400,
)

return JsonResponse({"error": {"message": _("Invalid form data")}}, status=400)
4 changes: 4 additions & 0 deletions example/blog/blog/test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .settings import *

# set to a small number for easier testing
CKEDITOR_5_MAX_FILE_SIZE = 0.06
Loading

0 comments on commit 3e1c726

Please sign in to comment.