From 3289e758f76a9f0fc650eba8eabaaafd451e762c Mon Sep 17 00:00:00 2001 From: Splines Date: Mon, 23 Oct 2023 18:55:35 +0200 Subject: [PATCH 01/16] Fix wrong code alignment error --- app/views/tutorials/bulk_upload.coffee | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/tutorials/bulk_upload.coffee b/app/views/tutorials/bulk_upload.coffee index 141adf414..6e346ebc7 100644 --- a/app/views/tutorials/bulk_upload.coffee +++ b/app/views/tutorials/bulk_upload.coffee @@ -9,9 +9,10 @@ $('#bulk-upload-report').empty() locals: { report: @report } %>').show() $('#tutorial-table').empty() .append('<%= j render partial: "tutorials/table", - locals: { assignment: @assignment, - tutorial: @tutorial, -initBootstrapPopovers() stack: @stack } %>') + locals: { assignment: @assignment, + tutorial: @tutorial, + stack: @stack } %>') +initBootstrapPopovers() <% end %> <% else %> location.reload(true) From 0ff42a1279e10e3f4f849c46f070d0dcae5628c3 Mon Sep 17 00:00:00 2001 From: Splines <37160523+Splines@users.noreply.github.com> Date: Tue, 31 Oct 2023 17:14:18 +0100 Subject: [PATCH 02/16] Prevent upload of empty submission corrections (#552) * Prevent upload of empty files * Add console log for empty file * Add more specific error message for empty files * Validate file size in backend * Improve locale strings * Undo automatic linting * Undo unwanted changes * Reset whitespaces * Fix multiple files stats for bulk upload * Provide info about which file is empty to user --- app/assets/javascripts/upload.coffee | 78 +++++++++++++------ app/uploaders/correction_uploader.rb | 7 ++ app/uploaders/submission_uploader.rb | 7 ++ .../submissions/_correction_upload.html.erb | 4 +- .../tutorials/_bulk_correction_form.html.erb | 2 + config/locales/de.yml | 6 ++ config/locales/en.yml | 7 +- 7 files changed, 86 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/upload.coffee b/app/assets/javascripts/upload.coffee index c6f40e7bc..a85faaa43 100644 --- a/app/assets/javascripts/upload.coffee +++ b/app/assets/javascripts/upload.coffee @@ -262,6 +262,21 @@ imageUpload = (fileInput,endpoint='/screenshots/upload', classname="course") -> metaData.innerHTML = data.metadata.filename + ' (' + formatBytes(data.metadata.size) + ')' metaData.style.display = 'inline' + + # Disable upload if empty files were uploaded + # Temporary fix for ":type option required" error in the + # app/controllers/submissions_controller.rb -> show_correction + if data.metadata.size == 0 + console.log('empty file encountered') + $(actualButton).hide() + $('#submit-correction-btn').addClass('disabled') + alert($(actualButton).data('tr-failure-empty-file')) + else + $(uploadButton).hide() + $(actualButton).show() + $(actualButton).addClass('disabled') + $('#submit-correction-btn').removeClass('disabled') + null hiddenInput true @@ -285,23 +300,35 @@ bulkCorrectionUpload = (fileInput) -> null '/corrections/upload' '#bulk-uploadButton-button-actual' - (data) => - - data = JSON.parse data.response - console.log(data) - result = (successful: [data]) - console.log result - if result.successful.length > 0 - uploaded_files = result.successful.map (file) -> file - console.log uploaded_files - $('#upload-bulk-correction-save').prop('disabled', false) + (_, dataAll) => + console.log(dataAll) + + if dataAll.length == 0 + console.error('No files uploaded, fatal error') + return + + # Disable upload if uploaded (zip)-file is empty + # Temporary fix for ":type option required" error in the + # app/controllers/submissions_controller.rb -> show_correction + for data in dataAll + if data.metadata.size > 0 + continue + console.log('empty file encountered during bulk upload: ' + data.metadata.filename) + alert(data.metadata.filename + ' ' + + $('#bulk-uploadButton-button-actual').data('tr-failure-empty-file-bulk')) + $('#bulk-uploadButton-button-actual').hide() $(metaData).empty() - .append(fileInput.files.length+ ' ' +$(metaData).data('tr-uploads')) - $(uploadButton).hide() - return - $("#bulk-upload-area").toggle() + return + + # Successfully uploaded + console.log('bulk upload successful') + $('#upload-bulk-correction-save').prop('disabled', false) + $(metaData).empty() + .append(fileInput.files.length+ ' ' +$(metaData).data('tr-uploads')) + $(uploadButton).hide() null 'upload-bulk-correction-hidden' + false ) $('#show-bulk-upload-area').on 'click', -> $(this).hide() @@ -345,17 +372,19 @@ directUpload provides an interface to upload (multiple) files to an endpoint fileInput =document.getElementById(fileInputElement) fI = $("#"+fileInputElement) fileInput.style.display = 'none' - result = undefined - merged = undefined - files = [] - filez= [] - - uploadedFiles = [] - progressOptimize = 0 $(uploadStatusElement).hide() uploadButton = $(uploadButtonElement) $(actualUploadButtonElement).on 'click', (e) -> + # Reset variables + result = undefined + merged = undefined + files = [] + filez= [] + uploadedFiles = [] + progressOptimize = 0 + hiddenInput.value = '' + e.preventDefault() if permissionElement == null || $(permissionElement).is(":checked") #Upload blob @@ -383,8 +412,11 @@ directUpload provides an interface to upload (multiple) files to an endpoint $(progressBarElement).text( $(progressBarElement).data 'tr-success' ) - if successCallback != undefined - successCallback(xhr) + if successCallback != undefined + # The second argument is currently only used by the + # bulk upload to get all uploaded files and not just + # the last one. + successCallback(xhr, uploadedFiles2) hiddenInput.value = JSON.stringify uploadedFiles2 fileInput.value = null $(progressBarElement) diff --git a/app/uploaders/correction_uploader.rb b/app/uploaders/correction_uploader.rb index cc7a30ba3..6653ad459 100644 --- a/app/uploaders/correction_uploader.rb +++ b/app/uploaders/correction_uploader.rb @@ -6,4 +6,11 @@ class CorrectionUploader < Shrine plugin :determine_mime_type, analyzer: :marcel plugin :upload_endpoint, max_size: 30 * 1024 * 1024 # 30 MB plugin :default_storage, cache: :submission_cache, store: :submission_store + plugin :validation_helpers + + Attacher.validate do + # Reject empty file uploads + # at least 1 byte + validate_min_size 1, message: I18n.t('submission.upload_failure_empty_file') + end end diff --git a/app/uploaders/submission_uploader.rb b/app/uploaders/submission_uploader.rb index dd8d4f9e5..ad029ab3d 100644 --- a/app/uploaders/submission_uploader.rb +++ b/app/uploaders/submission_uploader.rb @@ -7,4 +7,11 @@ class SubmissionUploader < Shrine plugin :upload_endpoint, max_size: 20 * 1024 * 1024 # 20 MB plugin :default_storage, cache: :submission_cache, store: :submission_store plugin :restore_cached_data + plugin :validation_helpers + + Attacher.validate do + # Reject empty file uploads + # at least 1 byte + validate_min_size 1, message: I18n.t('submission.upload_failure_empty_file') + end end diff --git a/app/views/submissions/_correction_upload.html.erb b/app/views/submissions/_correction_upload.html.erb index 9fce486b3..c96445140 100644 --- a/app/views/submissions/_correction_upload.html.erb +++ b/app/views/submissions/_correction_upload.html.erb @@ -21,6 +21,7 @@