diff --git a/ee/app/services/projects/update_mirror_service.rb b/ee/app/services/projects/update_mirror_service.rb index cb04452640c9e231f40c26bade905631cecee87f..291b2488cfc07a006a253030348dbfb97b567f63 100644 --- a/ee/app/services/projects/update_mirror_service.rb +++ b/ee/app/services/projects/update_mirror_service.rb @@ -8,24 +8,13 @@ class UpdateMirrorService < BaseService UpdateError = Class.new(Error) def execute - if project.import_url && - Gitlab::HTTP_V2::UrlBlocker.blocked_url?( - normalized_url(project.import_url), - schemes: Project::VALID_MIRROR_PROTOCOLS, - allow_localhost: Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?, - allow_local_network: Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?, - deny_all_requests_except_allowed: Gitlab::CurrentSettings.deny_all_requests_except_allowed?, - outbound_local_requests_allowlist: Gitlab::CurrentSettings.outbound_local_requests_whitelist) # rubocop:disable Naming/InclusiveLanguage -- existing setting - return error("The import URL is invalid.") - end + return error("The import URL is invalid.") if import_url_invalid? unless can?(current_user, :access_git) return error('The mirror user is not allowed to perform any git operations.') end - unless project.mirror? - return success - end + return success unless project.mirror? # This should be an error, but to prevent the mirroring # from being disabled when moving between shards @@ -47,7 +36,7 @@ def execute # Updating LFS objects is expensive since it requires scanning for blobs with pointers. # Let's skip this if the repository hasn't changed. - update_lfs_objects if project.repository.checksum != checksum_before + update_lfs_objects if update_lfs_objects?(checksum_before) # Running git fetch in the repository creates loose objects in the same # way running git push *to* the repository does, so ensure we run regular @@ -61,6 +50,20 @@ def execute private + def update_lfs_objects?(checksum) + project.lfs_enabled? && project.repository.checksum != checksum + end + + def import_url_invalid? + project.import_url && Gitlab::HTTP_V2::UrlBlocker.blocked_url?( + normalized_url(project.import_url), + schemes: Project::VALID_MIRROR_PROTOCOLS, + allow_localhost: Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?, + allow_local_network: Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?, + deny_all_requests_except_allowed: Gitlab::CurrentSettings.deny_all_requests_except_allowed?, + outbound_local_requests_allowlist: Gitlab::CurrentSettings.outbound_local_requests_whitelist) # rubocop:disable Naming/InclusiveLanguage -- existing setting + end + def normalized_url(url) strong_memoize_with(:normalized_url, url) do CGI.unescape(Gitlab::UrlSanitizer.sanitize(url)) diff --git a/ee/spec/services/projects/update_mirror_service_spec.rb b/ee/spec/services/projects/update_mirror_service_spec.rb index e141d26029e0a906d7d4238fbc25c898184914f9..5377915928097d279b5101cfe5ba29cd5cd412aa 100644 --- a/ee/spec/services/projects/update_mirror_service_spec.rb +++ b/ee/spec/services/projects/update_mirror_service_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe Projects::UpdateMirrorService, feature_category: :source_code_management do + let(:lfs_enabled) { false } let(:project) do create(:project, :repository, :mirror, import_url: Project::UNKNOWN_IMPORT_URL, only_mirror_protected_branches: false) end @@ -10,7 +11,7 @@ subject(:service) { described_class.new(project, project.first_owner) } before do - allow(project).to receive(:lfs_enabled?).and_return(false) + allow(project).to receive(:lfs_enabled?).and_return(lfs_enabled) end describe "#execute" do @@ -43,8 +44,6 @@ expect(svc).to receive(:execute) end - expect(Gitlab::Metrics::Lfs).to receive_message_chain(:update_objects_error_rate, :increment).with(error: false, labels: {}) - service.execute end @@ -59,8 +58,6 @@ it "returns success when updated succeeds" do stub_fetch_mirror(project) - expect(Gitlab::Metrics::Lfs).to receive_message_chain(:update_objects_error_rate, :increment).with(error: false, labels: {}) - result = service.execute expect(result[:status]).to eq(:success) @@ -411,9 +408,7 @@ def create_file(repository) context 'updating LFS objects' do context 'when repository does not change' do - before do - allow(project).to receive(:lfs_enabled?).and_return(true) - end + let(:lfs_enabled) { true } it 'does not attempt to update LFS objects' do expect(Projects::LfsPointers::LfsImportService).not_to receive(:new) @@ -427,21 +422,18 @@ def create_file(repository) stub_fetch_mirror(project) end - context 'when Lfs is disabled in the project' do + context 'when LFS is disabled in the project' do it 'does not update LFS objects' do - allow(project).to receive(:lfs_enabled?).and_return(false) expect(Projects::LfsPointers::LfsObjectDownloadListService).not_to receive(:new) - expect(Gitlab::Metrics::Lfs).to receive_message_chain(:update_objects_error_rate, :increment).with(error: false, labels: {}) + expect(Gitlab::Metrics::Lfs).not_to receive(:update_objects_error_rate) service.execute end end - context 'when Lfs is enabled in the project' do - before do - allow(project).to receive(:lfs_enabled?).and_return(true) - end + context 'when LFS is enabled in the project' do + let(:lfs_enabled) { true } it 'updates LFS objects' do expect(Projects::LfsPointers::LfsImportService).to receive(:new).and_call_original @@ -454,7 +446,7 @@ def create_file(repository) service.execute end - context 'when Lfs import fails' do + context 'when LFS import fails' do let(:error_message) { 'error_message' } before do