summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-11-30 04:50:30 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-30 04:50:45 +0000
commit0ee83f38c7f7f9f89c1753d7c2ff38b5387bc425 (patch)
tree3d41201040293d3010b52b83dc6f6bc35bd2344d
parentffa153da919ea7fd63594dd3d310cf68ebb9a440 (diff)
downloadgitlab-ce-0ee83f38c7f7f9f89c1753d7c2ff38b5387bc425.tar.gz
Add latest changes from gitlab-org/security/gitlab@15-5-stable-ee
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/models/integrations/jira.rb5
-rw-r--r--app/models/repository.rb8
-rw-r--r--app/services/packages/nuget/metadata_extraction_service.rb10
-rw-r--r--app/services/projects/import_service.rb32
-rw-r--r--lib/gitlab/git/repository.rb13
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb10
-rw-r--r--spec/fixtures/packages/nuget/corrupted_package.nupkgbin0 -> 3513 bytes
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb7
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb63
-rw-r--r--spec/models/integrations/jira_spec.rb13
-rw-r--r--spec/models/project_import_state_spec.rb2
-rw-r--r--spec/models/repository_spec.rb13
-rw-r--r--spec/requests/jira_connect/users_controller_spec.rb11
-rw-r--r--spec/services/packages/nuget/metadata_extraction_service_spec.rb11
-rw-r--r--spec/services/projects/import_service_spec.rb163
18 files changed, 317 insertions, 52 deletions
diff --git a/Gemfile b/Gemfile
index 8a8c0a444a9..9ea2dd6c2c0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -503,7 +503,7 @@ gem 'ssh_data', '~> 1.3'
gem 'spamcheck', '~> 1.0.0'
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 15.4.0-rc2'
+gem 'gitaly', '~> 15.5.2'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index afcbc5a6a65..c4ff7b9ff33 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -198,7 +198,7 @@
{"name":"gettext_i18n_rails","version":"1.8.0","platform":"ruby","checksum":"95e5cf8440b1e08705b27f2bccb56143272c5a7a0dabcf54ea1bd701140a496f"},
{"name":"gettext_i18n_rails_js","version":"1.3.0","platform":"ruby","checksum":"5d10afe4be3639bff78c50a56768c20f39aecdabc580c08aa45573911c2bd687"},
{"name":"git","version":"1.11.0","platform":"ruby","checksum":"7e95ba4da8298a0373ef1a6862aa22007d761f3c8274b675aa787966fecea0f1"},
-{"name":"gitaly","version":"15.4.0.pre.rc2","platform":"ruby","checksum":"48764528a730605a46f00cf86c7cfcb92d25f4f3d8cb9e09557baac3e9f3f8e3"},
+{"name":"gitaly","version":"15.5.2","platform":"ruby","checksum":"62babe0596a4505bf95051ea50f17160055e6cf6cacf209273691542120d7881"},
{"name":"github-markup","version":"1.7.0","platform":"ruby","checksum":"97eb27c70662d9cc1d5997cd6c99832026fae5d4913b5dce1ce6c9f65078e69d"},
{"name":"gitlab","version":"4.16.1","platform":"ruby","checksum":"13fd7059cbdad5a1a21b15fa2cf9070b97d92e27f8c688581fe3d84dc038074f"},
{"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 8bf67a41f45..b5ab43d16a6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -547,7 +547,7 @@ GEM
rails (>= 3.2.0)
git (1.11.0)
rchardet (~> 1.8)
- gitaly (15.4.0.pre.rc2)
+ gitaly (15.5.2)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@@ -1622,7 +1622,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 15.4.0.pre.rc2)
+ gitaly (~> 15.5.2)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.5.2)
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index 3ca514ab1fd..e2aefb3c117 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -98,7 +98,10 @@ module Integrations
def self.valid_jira_cloud_url?(url)
return false unless url.present?
- !!URI(url).hostname&.end_with?(JIRA_CLOUD_HOST)
+ uri = URI.parse(url)
+ uri.is_a?(URI::HTTPS) && !!uri.hostname&.end_with?(JIRA_CLOUD_HOST)
+ rescue URI::InvalidURIError
+ false
end
def data_fields
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 3413b3e3424..3f1f6fbb3e8 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -980,12 +980,12 @@ class Repository
end
end
- def clone_as_mirror(url, http_authorization_header: "")
- import_repository(url, http_authorization_header: http_authorization_header, mirror: true)
+ def clone_as_mirror(url, http_authorization_header: "", resolved_address: "")
+ import_repository(url, http_authorization_header: http_authorization_header, mirror: true, resolved_address: resolved_address)
end
- def fetch_as_mirror(url, forced: false, refmap: :all_refs, prune: true, http_authorization_header: "")
- fetch_remote(url, refmap: refmap, forced: forced, prune: prune, http_authorization_header: http_authorization_header)
+ def fetch_as_mirror(url, forced: false, refmap: :all_refs, prune: true, http_authorization_header: "", resolved_address: "")
+ fetch_remote(url, refmap: refmap, forced: forced, prune: prune, http_authorization_header: http_authorization_header, resolved_address: resolved_address)
end
def fetch_source_branch!(source_repository, source_branch, local_ref)
diff --git a/app/services/packages/nuget/metadata_extraction_service.rb b/app/services/packages/nuget/metadata_extraction_service.rb
index 66abd189153..02086b2a282 100644
--- a/app/services/packages/nuget/metadata_extraction_service.rb
+++ b/app/services/packages/nuget/metadata_extraction_service.rb
@@ -104,9 +104,15 @@ module Packages
entry = zip_file.glob('*.nuspec').first
raise ExtractionError, 'nuspec file not found' unless entry
- raise ExtractionError, 'nuspec file too big' if entry.size > MAX_FILE_SIZE
+ raise ExtractionError, 'nuspec file too big' if MAX_FILE_SIZE < entry.size
- entry.get_input_stream.read
+ Tempfile.open("nuget_extraction_package_file_#{@package_file_id}") do |file|
+ entry.extract(file.path) { true } # allow #extract to overwrite the file
+ file.unlink
+ file.read
+ end
+ rescue Zip::EntrySizeError => e
+ raise ExtractionError, "nuspec file has the wrong entry size: #{e.message}"
end
end
diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb
index de7ede4eabf..6a13b8e38c1 100644
--- a/app/services/projects/import_service.rb
+++ b/app/services/projects/import_service.rb
@@ -53,6 +53,8 @@ module Projects
private
+ attr_reader :resolved_address
+
def after_execute_hook
# Defined in EE::Projects::ImportService
end
@@ -64,11 +66,7 @@ module Projects
def add_repository_to_project
if project.external_import? && !unknown_url?
begin
- Gitlab::UrlBlocker.validate!(
- project.import_url,
- schemes: Project::VALID_IMPORT_PROTOCOLS,
- ports: Project::VALID_IMPORT_PORTS
- )
+ @resolved_address = get_resolved_address
rescue Gitlab::UrlBlocker::BlockedUrlError => e
raise e, s_("ImportProjects|Blocked import URL: %{message}") % { message: e.message }
end
@@ -97,9 +95,9 @@ module Projects
if refmap
project.ensure_repository
- project.repository.fetch_as_mirror(project.import_url, refmap: refmap)
+ project.repository.fetch_as_mirror(project.import_url, refmap: refmap, resolved_address: resolved_address)
else
- project.repository.import_repository(project.import_url)
+ project.repository.import_repository(project.import_url, resolved_address: resolved_address)
end
rescue ::Gitlab::Git::CommandError => e
# Expire cache to prevent scenarios such as:
@@ -157,6 +155,26 @@ module Projects
def importer_imports_repository?
has_importer? && importer_class.try(:imports_repository?)
end
+
+ def get_resolved_address
+ Gitlab::UrlBlocker
+ .validate!(
+ project.import_url,
+ schemes: Project::VALID_IMPORT_PROTOCOLS,
+ ports: Project::VALID_IMPORT_PORTS,
+ dns_rebind_protection: dns_rebind_protection?)
+ .then do |(import_url, resolved_host)|
+ next '' if resolved_host.nil? || !import_url.scheme.in?(%w[http https])
+
+ import_url.host.to_s
+ end
+ end
+
+ def dns_rebind_protection?
+ return false if Gitlab.http_proxy_env?
+
+ Gitlab::CurrentSettings.dns_rebinding_protection_enabled?
+ end
end
end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 9bbe17dcad1..4294e3aaaa7 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -855,7 +855,11 @@ module Gitlab
# no_tags - should we use --no-tags flag?
# prune - should we use --prune flag?
# check_tags_changed - should we ask gitaly to calculate whether any tags changed?
- def fetch_remote(url, refmap: nil, ssh_auth: nil, forced: false, no_tags: false, prune: true, check_tags_changed: false, http_authorization_header: "")
+ # resolved_address - resolved IP address for provided URL
+ def fetch_remote( # rubocop:disable Metrics/ParameterLists
+ url,
+ refmap: nil, ssh_auth: nil, forced: false, no_tags: false, prune: true,
+ check_tags_changed: false, http_authorization_header: "", resolved_address: "")
wrapped_gitaly_errors do
gitaly_repository_client.fetch_remote(
url,
@@ -866,16 +870,17 @@ module Gitlab
prune: prune,
check_tags_changed: check_tags_changed,
timeout: GITLAB_PROJECTS_TIMEOUT,
- http_authorization_header: http_authorization_header
+ http_authorization_header: http_authorization_header,
+ resolved_address: resolved_address
)
end
end
- def import_repository(url, http_authorization_header: '', mirror: false)
+ def import_repository(url, http_authorization_header: '', mirror: false, resolved_address: '')
raise ArgumentError, "don't use disk paths with import_repository: #{url.inspect}" if url.start_with?('.', '/')
wrapped_gitaly_errors do
- gitaly_repository_client.import_repository(url, http_authorization_header: http_authorization_header, mirror: mirror)
+ gitaly_repository_client.import_repository(url, http_authorization_header: http_authorization_header, mirror: mirror, resolved_address: resolved_address)
end
end
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index f11437552e1..6a4a4e28193 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -78,7 +78,7 @@ module Gitlab
# rubocop: disable Metrics/ParameterLists
# The `remote` parameter is going away soonish anyway, at which point the
# Rubocop warning can be enabled again.
- def fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: true, check_tags_changed: false, http_authorization_header: "")
+ def fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: true, check_tags_changed: false, http_authorization_header: "", resolved_address: "")
request = Gitaly::FetchRemoteRequest.new(
repository: @gitaly_repo,
force: forced,
@@ -89,7 +89,8 @@ module Gitlab
remote_params: Gitaly::Remote.new(
url: url,
mirror_refmaps: Array.wrap(refmap).map(&:to_s),
- http_authorization_header: http_authorization_header
+ http_authorization_header: http_authorization_header,
+ resolved_address: resolved_address
)
)
@@ -145,12 +146,13 @@ module Gitlab
)
end
- def import_repository(source, http_authorization_header: '', mirror: false)
+ def import_repository(source, http_authorization_header: '', mirror: false, resolved_address: '')
request = Gitaly::CreateRepositoryFromURLRequest.new(
repository: @gitaly_repo,
url: source,
http_authorization_header: http_authorization_header,
- mirror: mirror
+ mirror: mirror,
+ resolved_address: resolved_address
)
GitalyClient.call(
diff --git a/spec/fixtures/packages/nuget/corrupted_package.nupkg b/spec/fixtures/packages/nuget/corrupted_package.nupkg
new file mode 100644
index 00000000000..54f05c62aea
--- /dev/null
+++ b/spec/fixtures/packages/nuget/corrupted_package.nupkg
Binary files differ
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index f3d3fd2034c..e9dcfb43766 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -528,12 +528,13 @@ RSpec.describe Gitlab::Git::Repository do
prune: false,
check_tags_changed: false,
refmap: nil,
- http_authorization_header: ""
+ http_authorization_header: "",
+ resolved_address: '172.16.123.1'
}
expect(repository.gitaly_repository_client).to receive(:fetch_remote).with(url, expected_opts)
- repository.fetch_remote(url, ssh_auth: ssh_auth, forced: true, no_tags: true, prune: false, check_tags_changed: false)
+ repository.fetch_remote(url, ssh_auth: ssh_auth, forced: true, no_tags: true, prune: false, check_tags_changed: false, resolved_address: '172.16.123.1')
end
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RepositoryService, :fetch_remote do
@@ -2454,7 +2455,7 @@ RSpec.describe Gitlab::Git::Repository do
it 'delegates to Gitaly' do
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |svc|
- expect(svc).to receive(:import_repository).with(url, http_authorization_header: '', mirror: false).and_return(nil)
+ expect(svc).to receive(:import_repository).with(url, http_authorization_header: '', mirror: false, resolved_address: '').and_return(nil)
end
repository.import_repository(url)
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
index 58ace05b0d3..5aef250afac 100644
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -133,6 +133,40 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
end
end
+ describe '#import_repository' do
+ let(:source) { 'https://example.com/git/repo.git' }
+
+ it 'sends a create_repository_from_url message' do
+ expected_request = gitaly_request_with_params(
+ url: source,
+ resolved_address: ''
+ )
+
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:create_repository_from_url)
+ .with(expected_request, kind_of(Hash))
+ .and_return(double(value: true))
+
+ client.import_repository(source)
+ end
+
+ context 'when http_host is provided' do
+ it 'sends a create_repository_from_url message with http_host provided in the request' do
+ expected_request = gitaly_request_with_params(
+ url: source,
+ resolved_address: '172.16.123.1'
+ )
+
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:create_repository_from_url)
+ .with(expected_request, kind_of(Hash))
+ .and_return(double(value: true))
+
+ client.import_repository(source, resolved_address: '172.16.123.1')
+ end
+ end
+ end
+
describe '#fetch_remote' do
let(:url) { 'https://example.com/git/repo.git' }
@@ -141,7 +175,8 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
remote_params: Gitaly::Remote.new(
url: url,
http_authorization_header: "",
- mirror_refmaps: []
+ mirror_refmaps: [],
+ resolved_address: ''
),
ssh_key: '',
known_hosts: '',
@@ -159,6 +194,32 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
client.fetch_remote(url, refmap: nil, ssh_auth: nil, forced: false, no_tags: false, timeout: 1, check_tags_changed: false)
end
+ context 'with resolved address' do
+ it 'sends a fetch_remote_request message' do
+ expected_request = gitaly_request_with_params(
+ remote_params: Gitaly::Remote.new(
+ url: url,
+ http_authorization_header: "",
+ mirror_refmaps: [],
+ resolved_address: '172.16.123.1'
+ ),
+ ssh_key: '',
+ known_hosts: '',
+ force: false,
+ no_tags: false,
+ no_prune: false,
+ check_tags_changed: false
+ )
+
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:fetch_remote)
+ .with(expected_request, kind_of(Hash))
+ .and_return(double(value: true))
+
+ client.fetch_remote(url, refmap: nil, ssh_auth: nil, forced: false, no_tags: false, timeout: 1, check_tags_changed: false, resolved_address: '172.16.123.1')
+ end
+ end
+
context 'SSH auth' do
where(:ssh_mirror_url, :ssh_key_auth, :ssh_private_key, :ssh_known_hosts, :expected_params) do
false | false | 'key' | 'known_hosts' | {}
diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb
index 9f928442b28..a1c8767b822 100644
--- a/spec/models/integrations/jira_spec.rb
+++ b/spec/models/integrations/jira_spec.rb
@@ -230,9 +230,12 @@ RSpec.describe Integrations::Jira do
where(:url, :result) do
'https://abc.atlassian.net' | true
+ 'http://abc.atlassian.net' | false
'abc.atlassian.net' | false # This is how it behaves currently, but we may need to consider adding scheme if missing
'https://somethingelse.com' | false
- nil | false
+ 'javascript://test.atlassian.net/%250dalert(document.domain)' | false
+ 'https://example.com".atlassian.net' | false
+ nil | false
end
with_them do
@@ -289,7 +292,7 @@ RSpec.describe Integrations::Jira do
let(:server_info_results) { { 'deploymentType' => 'FutureCloud' } }
context 'and URL ends in .atlassian.net' do
- let(:api_url) { 'http://example-api.atlassian.net' }
+ let(:api_url) { 'https://example-api.atlassian.net' }
it 'deployment_type is set to cloud' do
expect(integration.jira_tracker_data).to be_deployment_cloud
@@ -297,7 +300,7 @@ RSpec.describe Integrations::Jira do
end
context 'and URL is something else' do
- let(:api_url) { 'http://my-jira-api.someserver.com' }
+ let(:api_url) { 'https://my-jira-api.someserver.com' }
it 'deployment_type is set to server' do
expect(integration.jira_tracker_data).to be_deployment_server
@@ -309,7 +312,7 @@ RSpec.describe Integrations::Jira do
let(:server_info_results) { {} }
context 'and URL ends in .atlassian.net' do
- let(:api_url) { 'http://example-api.atlassian.net' }
+ let(:api_url) { 'https://example-api.atlassian.net' }
it 'deployment_type is set to cloud' do
expect(Gitlab::AppLogger).to receive(:warn).with(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: server_info_results, url: api_url)
@@ -318,7 +321,7 @@ RSpec.describe Integrations::Jira do
end
context 'and URL is something else' do
- let(:api_url) { 'http://my-jira-api.someserver.com' }
+ let(:api_url) { 'https://my-jira-api.someserver.com' }
it 'deployment_type is set to server' do
expect(Gitlab::AppLogger).to receive(:warn).with(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: server_info_results, url: api_url)
diff --git a/spec/models/project_import_state_spec.rb b/spec/models/project_import_state_spec.rb
index db79185d759..ba1a29a8b27 100644
--- a/spec/models/project_import_state_spec.rb
+++ b/spec/models/project_import_state_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe ProjectImportState, type: :model do
before do
allow_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:import_repository)
- .with(project.import_url, http_authorization_header: '', mirror: false).and_return(true)
+ .with(project.import_url, http_authorization_header: '', mirror: false, resolved_address: '').and_return(true)
# Works around https://github.com/rspec/rspec-mocks/issues/910
allow(Project).to receive(:find).with(project.id).and_return(project)
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 6fbf69ec23a..b38ff76c6cd 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1224,11 +1224,22 @@ RSpec.describe Repository do
it 'fetches the URL without creating a remote' do
expect(repository)
.to receive(:fetch_remote)
- .with(url, forced: false, prune: true, refmap: :all_refs, http_authorization_header: "")
+ .with(url, forced: false, prune: true, refmap: :all_refs, http_authorization_header: "", resolved_address: '')
.and_return(nil)
repository.fetch_as_mirror(url)
end
+
+ context 'with http_host provided' do
+ it 'fetches the URL with resolved_address value' do
+ expect(repository)
+ .to receive(:fetch_remote)
+ .with(url, forced: false, prune: true, refmap: :all_refs, http_authorization_header: "", resolved_address: '172.16.123.1')
+ .and_return(nil)
+
+ repository.fetch_as_mirror(url, resolved_address: '172.16.123.1')
+ end
+ end
end
describe '#fetch_ref' do
diff --git a/spec/requests/jira_connect/users_controller_spec.rb b/spec/requests/jira_connect/users_controller_spec.rb
index c648d28c1bc..6e927aaba91 100644
--- a/spec/requests/jira_connect/users_controller_spec.rb
+++ b/spec/requests/jira_connect/users_controller_spec.rb
@@ -31,5 +31,16 @@ RSpec.describe JiraConnect::UsersController do
expect(response.body).not_to include('Return to GitLab')
end
end
+
+ context 'with a script injected' do
+ let(:return_to) { 'javascript://test.atlassian.net/%250dalert(document.domain)' }
+
+ it 'does not include a return url' do
+ get '/-/jira_connect/users', params: { return_to: return_to }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).not_to include('Return to GitLab')
+ end
+ end
end
end
diff --git a/spec/services/packages/nuget/metadata_extraction_service_spec.rb b/spec/services/packages/nuget/metadata_extraction_service_spec.rb
index fc21cfd502e..12bab30b4a7 100644
--- a/spec/services/packages/nuget/metadata_extraction_service_spec.rb
+++ b/spec/services/packages/nuget/metadata_extraction_service_spec.rb
@@ -114,5 +114,16 @@ RSpec.describe Packages::Nuget::MetadataExtractionService do
it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, 'nuspec file too big') }
end
+
+ context 'with a corrupted nupkg file with a wrong entry size' do
+ let(:nupkg_fixture_path) { expand_fixture_path('packages/nuget/corrupted_package.nupkg') }
+ let(:expected_error) { "nuspec file has the wrong entry size: entry 'DummyProject.DummyPackage.nuspec' should be 255B, but is larger when inflated." }
+
+ before do
+ allow(Zip::File).to receive(:new).and_return(Zip::File.new(nupkg_fixture_path, false, false))
+ end
+
+ it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, expected_error) }
+ end
end
end
diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb
index 6dc72948541..b3f8980a7bd 100644
--- a/spec/services/projects/import_service_spec.rb
+++ b/spec/services/projects/import_service_spec.rb
@@ -127,30 +127,67 @@ RSpec.describe Projects::ImportService do
project.import_type = 'bitbucket'
end
- it 'succeeds if repository import is successful' do
- expect(project.repository).to receive(:import_repository).and_return(true)
- expect_next_instance_of(Gitlab::BitbucketImport::Importer) do |importer|
- expect(importer).to receive(:execute).and_return(true)
+ context 'when importer supports refmap' do
+ before do
+ project.import_type = 'gitea'
end
- expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
- expect(service).to receive(:execute).and_return(status: :success)
+ it 'succeeds if repository fetch as mirror is successful' do
+ expect(project).to receive(:ensure_repository)
+ expect(project.repository).to receive(:fetch_as_mirror).with('https://bitbucket.org/vim/vim.git', refmap: Gitlab::LegacyGithubImport::Importer.refmap, resolved_address: '').and_return(true)
+ expect_next_instance_of(Gitlab::LegacyGithubImport::Importer) do |importer|
+ expect(importer).to receive(:execute).and_return(true)
+ end
+
+ expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
+ expect(service).to receive(:execute).and_return(status: :success)
+ end
+
+ result = subject.execute
+
+ expect(result[:status]).to eq :success
end
- result = subject.execute
+ it 'fails if repository fetch as mirror fails' do
+ expect(project).to receive(:ensure_repository)
+ expect(project.repository)
+ .to receive(:fetch_as_mirror)
+ .and_raise(Gitlab::Git::CommandError, 'Failed to import the repository /a/b/c')
- expect(result[:status]).to eq :success
+ result = subject.execute
+
+ expect(result[:status]).to eq :error
+ expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository [FILTERED]"
+ end
end
- it 'fails if repository import fails' do
- expect(project.repository)
- .to receive(:import_repository)
- .and_raise(Gitlab::Git::CommandError, 'Failed to import the repository /a/b/c')
+ context 'when importer does not support refmap' do
+ it 'succeeds if repository import is successful' do
+ expect(project.repository).to receive(:import_repository).and_return(true)
+ expect_next_instance_of(Gitlab::BitbucketImport::Importer) do |importer|
+ expect(importer).to receive(:execute).and_return(true)
+ end
- result = subject.execute
+ expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
+ expect(service).to receive(:execute).and_return(status: :success)
+ end
- expect(result[:status]).to eq :error
- expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository [FILTERED]"
+ result = subject.execute
+
+ expect(result[:status]).to eq :success
+ end
+
+ it 'fails if repository import fails' do
+ expect(project.repository)
+ .to receive(:import_repository)
+ .with('https://bitbucket.org/vim/vim.git', resolved_address: '')
+ .and_raise(Gitlab::Git::CommandError, 'Failed to import the repository /a/b/c')
+
+ result = subject.execute
+
+ expect(result[:status]).to eq :error
+ expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository [FILTERED]"
+ end
end
context 'when lfs import fails' do
@@ -287,6 +324,102 @@ RSpec.describe Projects::ImportService do
end
end
+ context 'when DNS rebind protection is disabled' do
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:dns_rebinding_protection_enabled?).and_return(false)
+ project.import_url = "https://example.com/group/project"
+
+ allow(Gitlab::UrlBlocker).to receive(:validate!)
+ .with(project.import_url, ports: Project::VALID_IMPORT_PORTS, schemes: Project::VALID_IMPORT_PROTOCOLS, dns_rebind_protection: false)
+ .and_return([Addressable::URI.parse("https://example.com/group/project"), nil])
+ end
+
+ it 'imports repository with url without additional resolved address' do
+ expect(project.repository).to receive(:import_repository).with('https://example.com/group/project', resolved_address: '').and_return(true)
+
+ expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
+ expect(service).to receive(:execute).and_return(status: :success)
+ end
+
+ result = subject.execute
+
+ expect(result[:status]).to eq(:success)
+ end
+ end
+
+ context 'when DNS rebind protection is enabled' do
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:http_proxy_env?).and_return(false)
+ allow(Gitlab::CurrentSettings).to receive(:dns_rebinding_protection_enabled?).and_return(true)
+ end
+
+ context 'when https url is provided' do
+ before do
+ project.import_url = "https://example.com/group/project"
+
+ allow(Gitlab::UrlBlocker).to receive(:validate!)
+ .with(project.import_url, ports: Project::VALID_IMPORT_PORTS, schemes: Project::VALID_IMPORT_PROTOCOLS, dns_rebind_protection: true)
+ .and_return([Addressable::URI.parse("https://172.16.123.1/group/project"), 'example.com'])
+ end
+
+ it 'imports repository with url and additional resolved address' do
+ expect(project.repository).to receive(:import_repository).with('https://example.com/group/project', resolved_address: '172.16.123.1').and_return(true)
+
+ expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
+ expect(service).to receive(:execute).and_return(status: :success)
+ end
+
+ result = subject.execute
+
+ expect(result[:status]).to eq(:success)
+ end
+ end
+
+ context 'when http url is provided' do
+ before do
+ project.import_url = "http://example.com/group/project"
+
+ allow(Gitlab::UrlBlocker).to receive(:validate!)
+ .with(project.import_url, ports: Project::VALID_IMPORT_PORTS, schemes: Project::VALID_IMPORT_PROTOCOLS, dns_rebind_protection: true)
+ .and_return([Addressable::URI.parse("http://172.16.123.1/group/project"), 'example.com'])
+ end
+
+ it 'imports repository with url and additional resolved address' do
+ expect(project.repository).to receive(:import_repository).with('http://example.com/group/project', resolved_address: '172.16.123.1').and_return(true)
+
+ expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
+ expect(service).to receive(:execute).and_return(status: :success)
+ end
+
+ result = subject.execute
+
+ expect(result[:status]).to eq(:success)
+ end
+ end
+
+ context 'when git address is provided' do
+ before do
+ project.import_url = "git://example.com/group/project.git"
+
+ allow(Gitlab::UrlBlocker).to receive(:validate!)
+ .with(project.import_url, ports: Project::VALID_IMPORT_PORTS, schemes: Project::VALID_IMPORT_PROTOCOLS, dns_rebind_protection: true)
+ .and_return([Addressable::URI.parse("git://172.16.123.1/group/project"), 'example.com'])
+ end
+
+ it 'imports repository with url and without resolved address' do
+ expect(project.repository).to receive(:import_repository).with('git://example.com/group/project.git', resolved_address: '').and_return(true)
+
+ expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
+ expect(service).to receive(:execute).and_return(status: :success)
+ end
+
+ result = subject.execute
+
+ expect(result[:status]).to eq(:success)
+ end
+ end
+ end
+
it_behaves_like 'measurable service' do
let(:base_log_data) do
{