diff --git a/app/controllers/admin/product_import_controller.rb b/app/controllers/admin/product_import_controller.rb index 3a288eb538..3149735a5c 100644 --- a/app/controllers/admin/product_import_controller.rb +++ b/app/controllers/admin/product_import_controller.rb @@ -118,9 +118,7 @@ module Admin end def sanitize_file_path(file_path) - pathname = Pathname.new(file_path) - raise_invalid_file_path unless pathname.file? - pathname.realpath + FilePathSanitizer.new.sanitize(file_path, on_error: method(:raise_invalid_file_path)) end def validate_file_path(file_path) diff --git a/app/services/file_path_sanitizer.rb b/app/services/file_path_sanitizer.rb new file mode 100644 index 0000000000..e853017edc --- /dev/null +++ b/app/services/file_path_sanitizer.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class FilePathSanitizer + def sanitize(file_path, on_error: nil) + pathname = Pathname.new(file_path) + return pathname.realpath if pathname.file? + + on_error&.call + false + end +end diff --git a/spec/controllers/admin/product_import_controller_spec.rb b/spec/controllers/admin/product_import_controller_spec.rb index 431d8a2ba5..88f6793ad5 100644 --- a/spec/controllers/admin/product_import_controller_spec.rb +++ b/spec/controllers/admin/product_import_controller_spec.rb @@ -45,38 +45,4 @@ describe Admin::ProductImportController, type: :controller do end end end - - describe 'sanitize_file_path' do - let(:folder_path){ '/tmp/product_import123' } - let(:file_path) { "#{folder_path}/import.csv" } - - before do - FileUtils.mkdir_p(folder_path) - File.new(file_path, 'w') unless File.exist?(file_path) - end - - def subject(path) - # expose the private method sanitize_file_path - described_class.class_eval { public :sanitize_file_path } - described_class.new.__send__(:sanitize_file_path, path) - end - - it 'should covert relative path to absolute' do - path = "/tmp/product_import123/import.csv" - expect(subject(path).to_s).to eq file_path - - path1 = "/../../tmp/product_import123/import.csv" - expect(subject(path1).to_s).to eq file_path - - path2 = "/etc/../../../tmp/product_import123/import.csv" - expect(subject(path2).to_s).to eq file_path - end - - it "raise an exception if the file doesn't exist" do - path = '/tmp/product_import123/import1.csv' - allow_any_instance_of(described_class).to receive(:raise_invalid_file_path) - .and_raise('Invalid File Path') - expect{ subject(path) }.to raise_error('Invalid File Path') - end - end end diff --git a/spec/services/file_path_sanitizer_spec.rb b/spec/services/file_path_sanitizer_spec.rb new file mode 100644 index 0000000000..4a47c2c1b2 --- /dev/null +++ b/spec/services/file_path_sanitizer_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe FilePathSanitizer do + let(:folder_path){ '/tmp/product_import123' } + let(:file_path) { "#{folder_path}/import.csv" } + + before do + FileUtils.mkdir_p(folder_path) + File.new(file_path, 'w') unless File.exist?(file_path) + end + let(:object) { described_class.new } + + it 'should covert relative path to absolute' do + path = "/tmp/product_import123/import.csv" + expect(object.sanitize(path).to_s).to eq file_path + + path1 = "/../../tmp/product_import123/import.csv" + expect(object.sanitize(path1).to_s).to eq file_path + + path2 = "/etc/../../../tmp/product_import123/import.csv" + expect(object.sanitize(path2).to_s).to eq file_path + end + + it "call errors callback if the file doesn't exist" do + path = '/tmp/product_import123/import1.csv' + error_callback = double('error_callback') + expect(error_callback).to receive(:call) + + expect( object.sanitize(path, on_error: error_callback) ).to eq(false) + end +end