FEATURE: add support for "skip_validations" option in UploadCreator (#13094)

FEATURE: add support for “skip_validations” option in UploadCreator (#13094)

FIX: do not validate uploads when running uploads:fix_missing_s3 task

diff --git a/lib/tasks/uploads.rake b/lib/tasks/uploads.rake
index 8d183a5..99bbbe2 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 63364e7..cd2f4c1 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 69f2450..3fafb32 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

GitHub sha: 13016053

This commit appears in #13094 which was approved by eviltrout. It was merged by techAPJ.