diff --git a/lib/tasks/uploads.rake b/lib/tasks/uploads.rake index 8d183a58a5f..99bbbe28303 100644 --- a/lib/tasks/uploads.rake +++ b/lib/tasks/uploads.rake @@ -1024,7 +1024,7 @@ def fix_missing_s3 Upload.transaction do begin upload.update_column(:sha1, SecureRandom.hex) - fixed_upload = UploadCreator.new(tempfile, "temp.#{upload.extension}").create_for(Discourse.system_user.id) + fixed_upload = UploadCreator.new(tempfile, "temp.#{upload.extension}", skip_validations: true).create_for(Discourse.system_user.id) rescue => fix_error # invalid extension is the most common issue end diff --git a/lib/upload_creator.rb b/lib/upload_creator.rb index 63364e7b4f1..cd2f4c11da3 100644 --- a/lib/upload_creator.rb +++ b/lib/upload_creator.rb @@ -24,11 +24,13 @@ class UploadCreator # - pasted (boolean) # - for_export (boolean) # - for_gravatar (boolean) + # - skip_validations (boolean) def initialize(file, filename, opts = {}) @file = file @filename = (filename || "").gsub(/[^[:print:]]/, "") @upload = Upload.new(original_filename: @filename, filesize: 0) @opts = opts + @opts[:validate] = opts[:skip_validations].present? ? !ActiveRecord::Type::Boolean.new.cast(opts[:skip_validations]) : true end def create_for(user_id) @@ -151,7 +153,7 @@ class UploadCreator @upload.assign_attributes(attrs) end - return @upload unless @upload.save + return @upload unless @upload.save(validate: @opts[:validate]) DiscourseEvent.trigger(:before_upload_creation, @file, is_image, @opts[:for_export]) @@ -161,7 +163,7 @@ class UploadCreator if url.present? @upload.url = url - @upload.save! + @upload.save!(validate: @opts[:validate]) else @upload.errors.add(:url, I18n.t("upload.store_failure", upload_id: @upload.id, user_id: user_id)) end diff --git a/spec/lib/upload_creator_spec.rb b/spec/lib/upload_creator_spec.rb index 69f24507ffa..3fafb3225ea 100644 --- a/spec/lib/upload_creator_spec.rb +++ b/spec/lib/upload_creator_spec.rb @@ -504,6 +504,32 @@ RSpec.describe UploadCreator do expect(FastImage.size(Discourse.store.path_for(upload))).to eq([320, 320]) end end + + describe 'skip validations' do + let(:filename) { "small.pdf" } + let(:file) { file_from_fixtures(filename, "pdf") } + + before do + SiteSetting.authorized_extensions = 'png|jpg' + end + + it 'creates upload when skip_validations is true' do + upload = UploadCreator.new(file, filename, + skip_validations: true + ).create_for(user.id) + + expect(upload.persisted?).to eq(true) + expect(upload.original_filename).to eq(filename) + end + + it 'does not create upload when skip_validations is false' do + upload = UploadCreator.new(file, filename, + skip_validations: false + ).create_for(user.id) + + expect(upload.persisted?).to eq(false) + end + end end describe '#clean_svg!' do