diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-20 12:16:11 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-20 12:16:11 +0300 |
commit | edaa33dee2ff2f7ea3fac488d41558eb5f86d68c (patch) | |
tree | 11f143effbfeba52329fb7afbd05e6e2a3790241 /spec/services/bulk_imports | |
parent | d8a5691316400a0f7ec4f83832698f1988eb27c1 (diff) |
Add latest changes from gitlab-org/gitlab@14-7-stable-eev14.7.0-rc42
Diffstat (limited to 'spec/services/bulk_imports')
5 files changed, 127 insertions, 15 deletions
diff --git a/spec/services/bulk_imports/archive_extraction_service_spec.rb b/spec/services/bulk_imports/archive_extraction_service_spec.rb index aa823d88010..da9df31cde9 100644 --- a/spec/services/bulk_imports/archive_extraction_service_spec.rb +++ b/spec/services/bulk_imports/archive_extraction_service_spec.rb @@ -34,9 +34,9 @@ RSpec.describe BulkImports::ArchiveExtractionService do context 'when dir is not in tmpdir' do it 'raises an error' do - ['/etc', '/usr', '/', '/home', '', '/some/other/path', Rails.root].each do |path| + ['/etc', '/usr', '/', '/home', '/some/other/path', Rails.root.to_s].each do |path| expect { described_class.new(tmpdir: path, filename: 'filename').execute } - .to raise_error(BulkImports::Error, 'Invalid target directory') + .to raise_error(StandardError, "path #{path} is not allowed") end end end @@ -52,7 +52,7 @@ RSpec.describe BulkImports::ArchiveExtractionService do context 'when filepath is being traversed' do it 'raises an error' do - expect { described_class.new(tmpdir: File.join(tmpdir, '../../../'), filename: 'name').execute } + expect { described_class.new(tmpdir: File.join(Dir.mktmpdir, 'test', '..'), filename: 'name').execute } .to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path') end end diff --git a/spec/services/bulk_imports/file_decompression_service_spec.rb b/spec/services/bulk_imports/file_decompression_service_spec.rb index 4e8f78c8243..1d6aa79a37f 100644 --- a/spec/services/bulk_imports/file_decompression_service_spec.rb +++ b/spec/services/bulk_imports/file_decompression_service_spec.rb @@ -18,7 +18,7 @@ RSpec.describe BulkImports::FileDecompressionService do FileUtils.remove_entry(tmpdir) end - subject { described_class.new(dir: tmpdir, filename: gz_filename) } + subject { described_class.new(tmpdir: tmpdir, filename: gz_filename) } describe '#execute' do it 'decompresses specified file' do @@ -55,10 +55,18 @@ RSpec.describe BulkImports::FileDecompressionService do end context 'when dir is not in tmpdir' do - subject { described_class.new(dir: '/etc', filename: 'filename') } + subject { described_class.new(tmpdir: '/etc', filename: 'filename') } it 'raises an error' do - expect { subject.execute }.to raise_error(described_class::ServiceError, 'Invalid target directory') + expect { subject.execute }.to raise_error(StandardError, 'path /etc is not allowed') + end + end + + context 'when path is being traversed' do + subject { described_class.new(tmpdir: File.join(Dir.mktmpdir, 'test', '..'), filename: 'filename') } + + it 'raises an error' do + expect { subject.execute }.to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path') end end @@ -69,7 +77,7 @@ RSpec.describe BulkImports::FileDecompressionService do FileUtils.ln_s(File.join(tmpdir, gz_filename), symlink) end - subject { described_class.new(dir: tmpdir, filename: 'symlink.gz') } + subject { described_class.new(tmpdir: tmpdir, filename: 'symlink.gz') } it 'raises an error and removes the file' do expect { subject.execute }.to raise_error(described_class::ServiceError, 'Invalid file') @@ -87,7 +95,7 @@ RSpec.describe BulkImports::FileDecompressionService do subject.instance_variable_set(:@decompressed_filepath, symlink) end - subject { described_class.new(dir: tmpdir, filename: gz_filename) } + subject { described_class.new(tmpdir: tmpdir, filename: gz_filename) } it 'raises an error and removes the file' do expect { subject.execute }.to raise_error(described_class::ServiceError, 'Invalid file') diff --git a/spec/services/bulk_imports/file_download_service_spec.rb b/spec/services/bulk_imports/file_download_service_spec.rb index a24af9ae64d..bd664d6e996 100644 --- a/spec/services/bulk_imports/file_download_service_spec.rb +++ b/spec/services/bulk_imports/file_download_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe BulkImports::FileDownloadService do described_class.new( configuration: config, relative_url: '/test', - dir: tmpdir, + tmpdir: tmpdir, filename: filename, file_size_limit: file_size_limit, allowed_content_types: allowed_content_types @@ -72,7 +72,7 @@ RSpec.describe BulkImports::FileDownloadService do service = described_class.new( configuration: double, relative_url: '/test', - dir: tmpdir, + tmpdir: tmpdir, filename: filename, file_size_limit: file_size_limit, allowed_content_types: allowed_content_types @@ -157,7 +157,7 @@ RSpec.describe BulkImports::FileDownloadService do described_class.new( configuration: config, relative_url: '/test', - dir: tmpdir, + tmpdir: tmpdir, filename: 'symlink', file_size_limit: file_size_limit, allowed_content_types: allowed_content_types @@ -179,7 +179,7 @@ RSpec.describe BulkImports::FileDownloadService do described_class.new( configuration: config, relative_url: '/test', - dir: '/etc', + tmpdir: '/etc', filename: filename, file_size_limit: file_size_limit, allowed_content_types: allowed_content_types @@ -188,8 +188,28 @@ RSpec.describe BulkImports::FileDownloadService do it 'raises an error' do expect { subject.execute }.to raise_error( - described_class::ServiceError, - 'Invalid target directory' + StandardError, + 'path /etc is not allowed' + ) + end + end + + context 'when dir path is being traversed' do + subject do + described_class.new( + configuration: config, + relative_url: '/test', + tmpdir: File.join(Dir.mktmpdir('bulk_imports'), 'test', '..'), + filename: filename, + file_size_limit: file_size_limit, + allowed_content_types: allowed_content_types + ) + end + + it 'raises an error' do + expect { subject.execute }.to raise_error( + Gitlab::Utils::PathTraversalAttackError, + 'Invalid path' ) end end diff --git a/spec/services/bulk_imports/file_export_service_spec.rb b/spec/services/bulk_imports/file_export_service_spec.rb index 0d129c75384..94efceff6c6 100644 --- a/spec/services/bulk_imports/file_export_service_spec.rb +++ b/spec/services/bulk_imports/file_export_service_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe BulkImports::FileExportService do let_it_be(:project) { create(:project) } let_it_be(:export_path) { Dir.mktmpdir } - let_it_be(:relation) { 'uploads' } + let_it_be(:relation) { BulkImports::FileTransfer::BaseConfig::UPLOADS_RELATION } subject(:service) { described_class.new(project, export_path, relation) } @@ -20,6 +20,20 @@ RSpec.describe BulkImports::FileExportService do subject.execute end + context 'when relation is lfs objects' do + let_it_be(:relation) { BulkImports::FileTransfer::ProjectConfig::LFS_OBJECTS_RELATION } + + it 'executes lfs objects export service' do + expect_next_instance_of(BulkImports::LfsObjectsExportService) do |service| + expect(service).to receive(:execute) + end + + expect(subject).to receive(:tar_cf).with(archive: File.join(export_path, 'lfs_objects.tar'), dir: export_path) + + subject.execute + end + end + context 'when unsupported relation is passed' do it 'raises an error' do service = described_class.new(project, export_path, 'unsupported') diff --git a/spec/services/bulk_imports/lfs_objects_export_service_spec.rb b/spec/services/bulk_imports/lfs_objects_export_service_spec.rb new file mode 100644 index 00000000000..5ae54ed309b --- /dev/null +++ b/spec/services/bulk_imports/lfs_objects_export_service_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::LfsObjectsExportService do + let_it_be(:project) { create(:project) } + let_it_be(:lfs_json_filename) { "#{BulkImports::FileTransfer::ProjectConfig::LFS_OBJECTS_RELATION}.json" } + let_it_be(:remote_url) { 'http://my-object-storage.local' } + + let(:export_path) { Dir.mktmpdir } + let(:lfs_object) { create(:lfs_object, :with_file) } + + subject(:service) { described_class.new(project, export_path) } + + before do + stub_lfs_object_storage + + %w(wiki design).each do |repository_type| + create( + :lfs_objects_project, + project: project, + repository_type: repository_type, + lfs_object: lfs_object + ) + end + + project.lfs_objects << lfs_object + end + + after do + FileUtils.remove_entry(export_path) if Dir.exist?(export_path) + end + + describe '#execute' do + it 'exports lfs objects and their repository types' do + filepath = File.join(export_path, lfs_json_filename) + + service.execute + + expect(File).to exist(File.join(export_path, lfs_object.oid)) + expect(File).to exist(filepath) + + lfs_json = Gitlab::Json.parse(File.read(filepath)) + + expect(lfs_json).to eq( + { + lfs_object.oid => [ + LfsObjectsProject.repository_types['wiki'], + LfsObjectsProject.repository_types['design'], + nil + ] + } + ) + end + + context 'when lfs object is remotely stored' do + let(:lfs_object) { create(:lfs_object, :object_storage) } + + it 'downloads lfs object from object storage' do + expect_next_instance_of(LfsObjectUploader) do |instance| + expect(instance).to receive(:url).and_return(remote_url) + end + + expect(subject).to receive(:download).with(remote_url, File.join(export_path, lfs_object.oid)) + + service.execute + end + end + end +end |