Skip to content

Commit

Permalink
Merge pull request #115 from uclouvain/os-980
Browse files Browse the repository at this point in the history
All form document fields can have a default upload size limit
  • Loading branch information
BenJneB authored May 2, 2024
2 parents 125abcf + 563ce43 commit 77bb5a7
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 8 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ OSIS_DOCUMENT_DOMAIN_LIST = [
OSIS_DOCUMENT_ALLOWED_EXTENSIONS = ['pdf', 'txt', 'docx', 'doc', 'odt', 'png', 'jpg']
# To enabled mimetype validation
ENABLE_MIMETYPE_VALIDATION = True
# To define an upload size limit (in Bytes) (default: None)
OSIS_DOCUMENT_MAX_UPLOAD_SIZE = 52428800
```

OSIS-Document is aimed at being run on multiple servers, so on your primary server, add it to your `urls.py`
Expand Down
3 changes: 1 addition & 2 deletions osis_document/contrib/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
import uuid
from os.path import dirname
from typing import Set, List, Union
from typing import List, Union

from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.validators import ArrayMinLengthValidator
Expand Down
17 changes: 15 additions & 2 deletions osis_document/contrib/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# ##############################################################################

from django import forms
from django.conf import settings
from django.contrib.postgres.forms import SplitArrayField
from django.utils.translation import gettext_lazy as _

Expand Down Expand Up @@ -68,11 +69,23 @@ class FileUploadField(SplitArrayField):
'max_files': _("Too many files uploaded"),
'min_files': _("Too few files uploaded"),
'invalid_token': _("Invalid token"),
'item_invalid': _("Item %(nth)s in the array did not validate:"),
}

def __init__(self, **kwargs):
self.mimetypes = kwargs.pop('mimetypes', None)
self.max_size = kwargs.pop('max_size', None)

# Define an upload limit size based on the app settings and the field settings
absolute_upload_size_limit = getattr(settings, 'OSIS_DOCUMENT_MAX_UPLOAD_SIZE', None)
field_upload_size_limit = kwargs.pop('max_size', None)

if field_upload_size_limit:
if absolute_upload_size_limit and field_upload_size_limit > absolute_upload_size_limit:
field_upload_size_limit = absolute_upload_size_limit
else:
field_upload_size_limit = absolute_upload_size_limit

self.max_size = field_upload_size_limit
self.max_files = kwargs.pop('max_files', None)
self.min_files = kwargs.pop('min_files', None)
self.upload_to = kwargs.pop('upload_to', None)
Expand Down Expand Up @@ -152,7 +165,7 @@ def prepare_value(self, value):
get_remote_token(
v,
write_token=True,
for_modified_upload=self.for_modified_upload
for_modified_upload=self.for_modified_upload,
)
if is_uuid(v)
else v
Expand Down
4 changes: 4 additions & 0 deletions osis_document/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ msgstr ""
msgid "Invalid upload UUID"
msgstr ""

#, python-format
msgid "Item %(nth)s in the array did not validate:"
msgstr ""

msgid "MIME Type"
msgstr ""

Expand Down
4 changes: 4 additions & 0 deletions osis_document/locale/fr_BE/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ msgstr "Jeton invalide"
msgid "Invalid upload UUID"
msgstr "UUID de téléchargement non valide"

#, python-format
msgid "Item %(nth)s in the array did not validate:"
msgstr "L'élément n°%(nth)s du tableau n’est pas valide :"

msgid "MIME Type"
msgstr "Type MIME"

Expand Down
6 changes: 2 additions & 4 deletions osis_document/tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ def test_model_form_submit(
self.assertEqual(len(document.documents), 0)

@patch('osis_document.api.utils.get_remote_metadata')

@patch('osis_document.api.utils.get_several_remote_metadata')
def test_model_form_confirms_remotely_with_correct_path(
self,
Expand All @@ -154,7 +153,7 @@ def test_model_form_confirms_remotely_with_correct_path(
):
token = WriteTokenFactory()

get_remote_metadata.return_value = {"name": "test.jpg"}
get_remote_metadata.return_value = {"name": "test.jpg", "size": 1}
get_several_remote_metadata.return_value = {
str(token.token): get_remote_metadata.return_value
}
Expand All @@ -169,7 +168,6 @@ def test_model_form_confirms_remotely_with_correct_path(
request_mock.assert_called_with(expected_url, json={'upload_to': 'path'}, headers={'X-Api-Key': 'very-secret'})

@patch('osis_document.api.utils.get_remote_metadata')

@patch('osis_document.api.utils.get_several_remote_metadata')
def test_model_form_confirms_remotely_with_document_expiration_policy(
self,
Expand All @@ -178,7 +176,7 @@ def test_model_form_confirms_remotely_with_document_expiration_policy(
):
token = WriteTokenFactory()

get_remote_metadata.return_value = {"name": "test.jpg"}
get_remote_metadata.return_value = {"name": "test.jpg", "size": 1}
get_several_remote_metadata.return_value = {
str(token.token): get_remote_metadata.return_value
}
Expand Down
24 changes: 24 additions & 0 deletions osis_document/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,30 @@ class TestForm(forms.Form):
error = TokenField.default_error_messages['size']
self.assertIn(str(error), form.errors['media'][0])

# The max size is not defined in the settings
with override_settings(OSIS_DOCUMENT_MAX_UPLOAD_SIZE=None):
class TestForm(forms.Form):
media_with_limited_size = FileUploadField(max_size=2)
media_without_limited_size = FileUploadField()

form = TestForm()

self.assertEqual(form.fields['media_with_limited_size'].max_size, 2)
self.assertEqual(form.fields['media_without_limited_size'].max_size, None)

# The max size is defined in the settings
with override_settings(OSIS_DOCUMENT_MAX_UPLOAD_SIZE=10):
class TestForm(forms.Form):
media_with_lower_limited_size = FileUploadField(max_size=2)
media_with_greater_limited_size = FileUploadField(max_size=15)
media_without_limited_size = FileUploadField()

form = TestForm()

self.assertEqual(form.fields['media_with_lower_limited_size'].max_size, 2)
self.assertEqual(form.fields['media_with_greater_limited_size'].max_size, 10)
self.assertEqual(form.fields['media_without_limited_size'].max_size, 10)

def test_check_mimetype(self):
class TestForm(forms.Form):
media = FileUploadField(mimetypes=('image/jpeg',))
Expand Down

0 comments on commit 77bb5a7

Please sign in to comment.