From fb473b5e4ba23390401a10c32042f4df9924e358 Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 3 May 2023 16:50:46 +0100 Subject: [PATCH 01/11] Add MultipleFileField to handle and clean multiple files --- omeroweb/webclient/forms.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/omeroweb/webclient/forms.py b/omeroweb/webclient/forms.py index debb7fd833..35b7ce3211 100644 --- a/omeroweb/webclient/forms.py +++ b/omeroweb/webclient/forms.py @@ -62,6 +62,27 @@ ) % help_button +################################################################# +# Custom widget and validation for multiple file uploads + +class MultipleFileInput(forms.ClearableFileInput): + allow_multiple_selected = True + + +class MultipleFileField(forms.FileField): + def __init__(self, *args, **kwargs): + kwargs.setdefault("widget", MultipleFileInput()) + super().__init__(*args, **kwargs) + + def clean(self, data, initial=None): + single_file_clean = super().clean + if isinstance(data, (list, tuple)): + result = [single_file_clean(d, initial) for d in data] + else: + result = single_file_clean(data, initial) + return result + + ################################################################# # Non-model Form @@ -334,9 +355,7 @@ def __init__(self, *args, **kwargs): required=False, ) - annotation_file = forms.FileField( - widget=forms.ClearableFileInput(attrs={"multiple": True}), required=False - ) + annotation_file = MultipleFileField(required=False) class CommentAnnotationForm(BaseAnnotationForm): From bf80b251f7285f135ec26684189ab6468a67c512 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 15:57:06 +0000 Subject: [PATCH 02/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- omeroweb/webclient/forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/omeroweb/webclient/forms.py b/omeroweb/webclient/forms.py index 35b7ce3211..228e2b0e38 100644 --- a/omeroweb/webclient/forms.py +++ b/omeroweb/webclient/forms.py @@ -65,8 +65,9 @@ ################################################################# # Custom widget and validation for multiple file uploads + class MultipleFileInput(forms.ClearableFileInput): - allow_multiple_selected = True + allow_multiple_selected = True class MultipleFileField(forms.FileField): From 305fb669bdcfd9889af51f703d5884d39c229ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Besson?= Date: Thu, 4 May 2023 12:17:40 +0100 Subject: [PATCH 03/11] Bind uploaded files to the FilesAnnotationForm Presently, files uploaded in the UI are not bound to the form and thus the is_valid() check is largely a no-op. As per the default validation contract of FileField, this means that this UI can create annotations with empty files. See https://docs.djangoproject.com/en/3.2/ref/forms/api/#binding-uploaded-files --- omeroweb/webclient/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/omeroweb/webclient/views.py b/omeroweb/webclient/views.py index 8a0b3cb567..82da8ce467 100755 --- a/omeroweb/webclient/views.py +++ b/omeroweb/webclient/views.py @@ -2399,7 +2399,9 @@ def annotate_file(request, conn=None, **kwargs): if request.method == "POST": # handle form submission - form_file = FilesAnnotationForm(initial=initial, data=request.POST.copy()) + form_file = FilesAnnotationForm( + initial=initial, data=request.POST.copy(), files=request.FILES + ) if form_file.is_valid(): # Link existing files... files = form_file.cleaned_data["files"] From 1968045a5240855ea42748e02064c35fa2601e02 Mon Sep 17 00:00:00 2001 From: William Moore Date: Thu, 4 May 2023 13:57:26 +0100 Subject: [PATCH 04/11] Bump requirement to Django>=3.2.19 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b119f6c9a6..cdfaaa600b 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ def read(fname): "omero-py>=5.7.0", # minimum requirements for `omero web start` "concurrent-log-handler>=0.9.20", - "Django>=3.2.18,<4.0", + "Django>=3.2.19,<4.0", "django-pipeline==2.0.7", "django-cors-headers==3.7.0", "whitenoise>=5.3.0", From 3bda370963e6560111dc04c857ce34dc69d02eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Besson?= Date: Thu, 4 May 2023 14:11:12 +0100 Subject: [PATCH 05/11] Temporarily cap Django to 3.2.18 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b119f6c9a6..c9876c9447 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ def read(fname): "omero-py>=5.7.0", # minimum requirements for `omero web start` "concurrent-log-handler>=0.9.20", - "Django>=3.2.18,<4.0", + "Django==3.2.18,<4.0", "django-pipeline==2.0.7", "django-cors-headers==3.7.0", "whitenoise>=5.3.0", From 1dbdf0e51c3032bc51a4119f5ce043ede9d5fafb Mon Sep 17 00:00:00 2001 From: Andreas Knab Date: Fri, 5 May 2023 14:18:57 +0200 Subject: [PATCH 06/11] Update changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2606fe31bd..8270137b7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +5.20.0 (May 2023) +----------------- + +## Other changes + +- Fix multiple file uploads and support Django 3.2.19 security update [#465](https://github.com/ome/omero-web/pull/465) +- Declare portalocker as external dependency [#457](https://github.com/ome/omero-web/pull/457) + +## Bug fixes + +- Avoid creation of empty file annotations [#466](https://github.com/ome/omero-web/pull/466) + 5.19.0 (March 2023) ------------------- From f2793a1f7081ed0ecddd0e65a5b698b281908220 Mon Sep 17 00:00:00 2001 From: William Moore Date: Tue, 9 May 2023 10:18:00 +0100 Subject: [PATCH 07/11] Move MultipleFileField to custom_forms.py --- omeroweb/webclient/custom_forms.py | 20 ++++++++++++++++++++ omeroweb/webclient/forms.py | 23 +---------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/omeroweb/webclient/custom_forms.py b/omeroweb/webclient/custom_forms.py index 58fcbe5435..63f4d45671 100644 --- a/omeroweb/webclient/custom_forms.py +++ b/omeroweb/webclient/custom_forms.py @@ -379,3 +379,23 @@ def clean(self, value): else: final_values.append(val) return final_values + + +# Custom widget and validation for multiple file uploads +# See https://docs.djangoproject.com/en/3.2/topics/http/file-uploads/#uploading-multiple-files +class MultipleFileInput(forms.ClearableFileInput): + allow_multiple_selected = True + + +class MultipleFileField(forms.FileField): + def __init__(self, *args, **kwargs): + kwargs.setdefault("widget", MultipleFileInput()) + super().__init__(*args, **kwargs) + + def clean(self, data, initial=None): + single_file_clean = super().clean + if isinstance(data, (list, tuple)): + result = [single_file_clean(d, initial) for d in data] + else: + result = single_file_clean(data, initial) + return result diff --git a/omeroweb/webclient/forms.py b/omeroweb/webclient/forms.py index 228e2b0e38..62045b5398 100644 --- a/omeroweb/webclient/forms.py +++ b/omeroweb/webclient/forms.py @@ -34,6 +34,7 @@ from omeroweb.custom_forms import NonASCIIForm from .custom_forms import MetadataModelChoiceField +from .custom_forms import MultipleFileField from .custom_forms import AnnotationModelMultipleChoiceField from .custom_forms import ObjectModelMultipleChoiceField from omeroweb.webadmin.custom_forms import ExperimenterModelMultipleChoiceField @@ -62,28 +63,6 @@ ) % help_button -################################################################# -# Custom widget and validation for multiple file uploads - - -class MultipleFileInput(forms.ClearableFileInput): - allow_multiple_selected = True - - -class MultipleFileField(forms.FileField): - def __init__(self, *args, **kwargs): - kwargs.setdefault("widget", MultipleFileInput()) - super().__init__(*args, **kwargs) - - def clean(self, data, initial=None): - single_file_clean = super().clean - if isinstance(data, (list, tuple)): - result = [single_file_clean(d, initial) for d in data] - else: - result = single_file_clean(data, initial) - return result - - ################################################################# # Non-model Form From c76f3774b923c6c6487bfac6740e4af65a658e04 Mon Sep 17 00:00:00 2001 From: William Moore Date: Tue, 9 May 2023 10:36:04 +0100 Subject: [PATCH 08/11] Flake8 fix --- omeroweb/webclient/custom_forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/omeroweb/webclient/custom_forms.py b/omeroweb/webclient/custom_forms.py index 63f4d45671..9651b965db 100644 --- a/omeroweb/webclient/custom_forms.py +++ b/omeroweb/webclient/custom_forms.py @@ -382,7 +382,8 @@ def clean(self, value): # Custom widget and validation for multiple file uploads -# See https://docs.djangoproject.com/en/3.2/topics/http/file-uploads/#uploading-multiple-files +# See https://docs.djangoproject.com/en/3.2/topics/http/ +# file-uploads/#uploading-multiple-files class MultipleFileInput(forms.ClearableFileInput): allow_multiple_selected = True From 737e7023f46abacc8e8b18b3092c1d325bc4ebac Mon Sep 17 00:00:00 2001 From: Andreas Knab Date: Wed, 10 May 2023 11:02:46 +0200 Subject: [PATCH 09/11] Clarify comment --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8270137b7b..7822bbf83e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Other changes -- Fix multiple file uploads and support Django 3.2.19 security update [#465](https://github.com/ome/omero-web/pull/465) +- Fix multi-file upload validation and support Django 3.2.19 security update [#465](https://github.com/ome/omero-web/pull/465) - Declare portalocker as external dependency [#457](https://github.com/ome/omero-web/pull/457) ## Bug fixes From 67726e05386cd2261af2b8bf80af7b99d2e703d4 Mon Sep 17 00:00:00 2001 From: Andreas Knab Date: Wed, 10 May 2023 12:01:26 +0200 Subject: [PATCH 10/11] =?UTF-8?q?Bump=20version:=205.19.1.dev0=20=E2=86=92?= =?UTF-8?q?=205.20.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- omeroweb/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 0e01e07dff..f067a5dd80 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 5.19.1.dev0 +current_version = 5.20.0 commit = True tag = True sign_tags = True diff --git a/omeroweb/version.py b/omeroweb/version.py index 06b3fd01a0..2641907d6e 100644 --- a/omeroweb/version.py +++ b/omeroweb/version.py @@ -7,5 +7,5 @@ omero_buildyear = "unknown" -omeroweb_version = "5.19.1.dev0" +omeroweb_version = "5.20.0" omeroweb_buildyear = "2022" From ac66db9274b1ab80b270c8b8fe36dfa55b0e9a75 Mon Sep 17 00:00:00 2001 From: Andreas Knab Date: Wed, 10 May 2023 12:02:01 +0200 Subject: [PATCH 11/11] =?UTF-8?q?Bump=20version:=205.20.0=20=E2=86=92=205.?= =?UTF-8?q?20.1.dev0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- omeroweb/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index f067a5dd80..816f1ffe9a 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 5.20.0 +current_version = 5.20.1.dev0 commit = True tag = True sign_tags = True diff --git a/omeroweb/version.py b/omeroweb/version.py index 2641907d6e..75506082d8 100644 --- a/omeroweb/version.py +++ b/omeroweb/version.py @@ -7,5 +7,5 @@ omero_buildyear = "unknown" -omeroweb_version = "5.20.0" +omeroweb_version = "5.20.1.dev0" omeroweb_buildyear = "2022"