Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/packages/nuget/check_duplicates_service.rb')
-rw-r--r--app/services/packages/nuget/check_duplicates_service.rb88
1 files changed, 88 insertions, 0 deletions
diff --git a/app/services/packages/nuget/check_duplicates_service.rb b/app/services/packages/nuget/check_duplicates_service.rb
new file mode 100644
index 00000000000..7ad9038d7c1
--- /dev/null
+++ b/app/services/packages/nuget/check_duplicates_service.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Packages
+ module Nuget
+ class CheckDuplicatesService < BaseService
+ include Gitlab::Utils::StrongMemoize
+
+ ExtractionError = Class.new(StandardError)
+
+ def execute
+ return ServiceResponse.success if package_settings_allow_duplicates? || !target_package_is_duplicate?
+
+ ServiceResponse.error(
+ message: 'A package with the same name and version already exists',
+ reason: :conflict
+ )
+ rescue ExtractionError => e
+ ServiceResponse.error(message: e.message, reason: :bad_request)
+ end
+
+ private
+
+ def package_settings_allow_duplicates?
+ package_settings.nuget_duplicates_allowed? || package_settings.class.duplicates_allowed?(existing_package)
+ end
+
+ def target_package_is_duplicate?
+ existing_package.name.casecmp(metadata[:package_name]) == 0 &&
+ (existing_package.version.casecmp(metadata[:package_version]) == 0 ||
+ existing_package.normalized_nuget_version&.casecmp(metadata[:package_version]) == 0)
+ end
+
+ def package_settings
+ project.namespace.package_settings
+ end
+ strong_memoize_attr :package_settings
+
+ def existing_package
+ ::Packages::Nuget::PackageFinder
+ .new(
+ current_user,
+ project,
+ package_name: metadata[:package_name],
+ package_version: metadata[:package_version]
+ )
+ .execute
+ .first
+ end
+ strong_memoize_attr :existing_package
+
+ def metadata
+ if remote_package_file?
+ ExtractMetadataContentService
+ .new(nuspec_file_content)
+ .execute
+ .payload
+ else # to cover the case when package file is on disk not in object storage
+ MetadataExtractionService
+ .new(mock_package_file)
+ .execute
+ .payload
+ end
+ end
+ strong_memoize_attr :metadata
+
+ def remote_package_file?
+ params[:remote_url].present?
+ end
+
+ def nuspec_file_content
+ ExtractRemoteMetadataFileService
+ .new(params[:remote_url])
+ .execute
+ .payload
+ rescue ExtractRemoteMetadataFileService::ExtractionError => e
+ raise ExtractionError, e.message
+ end
+
+ def mock_package_file
+ ::Packages::PackageFile.new(
+ params
+ .slice(:file, :file_name)
+ .merge(package: ::Packages::Package.nuget.build)
+ )
+ end
+ end
+ end
+end