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 'lib/api/helpers/packages/conan/api_helpers.rb')
-rw-r--r--lib/api/helpers/packages/conan/api_helpers.rb225
1 files changed, 225 insertions, 0 deletions
diff --git a/lib/api/helpers/packages/conan/api_helpers.rb b/lib/api/helpers/packages/conan/api_helpers.rb
new file mode 100644
index 00000000000..30e690a5a1d
--- /dev/null
+++ b/lib/api/helpers/packages/conan/api_helpers.rb
@@ -0,0 +1,225 @@
+# frozen_string_literal: true
+
+module API
+ module Helpers
+ module Packages
+ module Conan
+ module ApiHelpers
+ def present_download_urls(entity)
+ authorize!(:read_package, project)
+
+ presenter = ::Packages::Conan::PackagePresenter.new(
+ recipe,
+ current_user,
+ project,
+ conan_package_reference: params[:conan_package_reference]
+ )
+
+ render_api_error!("No recipe manifest found", 404) if yield(presenter).empty?
+
+ present presenter, with: entity
+ end
+
+ def present_package_download_urls
+ present_download_urls(::API::Entities::ConanPackage::ConanPackageManifest, &:package_urls)
+ end
+
+ def present_recipe_download_urls
+ present_download_urls(::API::Entities::ConanPackage::ConanRecipeManifest, &:recipe_urls)
+ end
+
+ def recipe_upload_urls(file_names)
+ { upload_urls: Hash[
+ file_names.collect do |file_name|
+ [file_name, recipe_file_upload_url(file_name)]
+ end
+ ] }
+ end
+
+ def package_upload_urls(file_names)
+ { upload_urls: Hash[
+ file_names.collect do |file_name|
+ [file_name, package_file_upload_url(file_name)]
+ end
+ ] }
+ end
+
+ def package_file_upload_url(file_name)
+ expose_url(
+ api_v4_packages_conan_v1_files_package_path(
+ package_name: params[:package_name],
+ package_version: params[:package_version],
+ package_username: params[:package_username],
+ package_channel: params[:package_channel],
+ recipe_revision: '0',
+ conan_package_reference: params[:conan_package_reference],
+ package_revision: '0',
+ file_name: file_name
+ )
+ )
+ end
+
+ def recipe_file_upload_url(file_name)
+ expose_url(
+ api_v4_packages_conan_v1_files_export_path(
+ package_name: params[:package_name],
+ package_version: params[:package_version],
+ package_username: params[:package_username],
+ package_channel: params[:package_channel],
+ recipe_revision: '0',
+ file_name: file_name
+ )
+ )
+ end
+
+ def recipe
+ "%{package_name}/%{package_version}@%{package_username}/%{package_channel}" % params.symbolize_keys
+ end
+
+ def project
+ strong_memoize(:project) do
+ full_path = ::Packages::Conan::Metadatum.full_path_from(package_username: params[:package_username])
+ Project.find_by_full_path(full_path)
+ end
+ end
+
+ def package
+ strong_memoize(:package) do
+ project.packages
+ .with_name(params[:package_name])
+ .with_version(params[:package_version])
+ .with_conan_channel(params[:package_channel])
+ .order_created
+ .last
+ end
+ end
+
+ def token
+ strong_memoize(:token) do
+ token = nil
+ token = ::Gitlab::ConanToken.from_personal_access_token(access_token) if access_token
+ token = ::Gitlab::ConanToken.from_deploy_token(deploy_token_from_request) if deploy_token_from_request
+ token = ::Gitlab::ConanToken.from_job(find_job_from_token) if find_job_from_token
+ token
+ end
+ end
+
+ def download_package_file(file_type)
+ authorize!(:read_package, project)
+
+ package_file = ::Packages::Conan::PackageFileFinder
+ .new(
+ package,
+ params[:file_name].to_s,
+ conan_file_type: file_type,
+ conan_package_reference: params[:conan_package_reference]
+ ).execute!
+
+ track_event('pull_package') if params[:file_name] == ::Packages::Conan::FileMetadatum::PACKAGE_BINARY
+
+ present_carrierwave_file!(package_file.file)
+ end
+
+ def find_or_create_package
+ package || ::Packages::Conan::CreatePackageService.new(project, current_user, params).execute
+ end
+
+ def track_push_package_event
+ if params[:file_name] == ::Packages::Conan::FileMetadatum::PACKAGE_BINARY && params['file.size'] > 0
+ track_event('push_package')
+ end
+ end
+
+ def create_package_file_with_type(file_type, current_package)
+ unless params['file.size'] == 0
+ # conan sends two upload requests, the first has no file, so we skip record creation if file.size == 0
+ ::Packages::Conan::CreatePackageFileService.new(current_package, uploaded_package_file, params.merge(conan_file_type: file_type)).execute
+ end
+ end
+
+ def upload_package_file(file_type)
+ authorize_upload!(project)
+
+ current_package = find_or_create_package
+
+ track_push_package_event
+
+ create_package_file_with_type(file_type, current_package)
+ rescue ObjectStorage::RemoteStoreError => e
+ Gitlab::ErrorTracking.track_exception(e, file_name: params[:file_name], project_id: project.id)
+
+ forbidden!
+ end
+
+ def find_personal_access_token
+ personal_access_token = find_personal_access_token_from_conan_jwt ||
+ find_personal_access_token_from_http_basic_auth
+
+ personal_access_token
+ end
+
+ def find_user_from_job_token
+ return unless route_authentication_setting[:job_token_allowed]
+
+ job = find_job_from_token || raise(::Gitlab::Auth::UnauthorizedError)
+
+ job.user
+ end
+
+ def deploy_token_from_request
+ find_deploy_token_from_conan_jwt || find_deploy_token_from_http_basic_auth
+ end
+
+ def find_job_from_token
+ find_job_from_conan_jwt || find_job_from_http_basic_auth
+ end
+
+ # We need to override this one because it
+ # looks into Bearer authorization header
+ def find_oauth_access_token
+ end
+
+ def find_personal_access_token_from_conan_jwt
+ token = decode_oauth_token_from_jwt
+
+ return unless token
+
+ PersonalAccessToken.find_by_id_and_user_id(token.access_token_id, token.user_id)
+ end
+
+ def find_deploy_token_from_conan_jwt
+ token = decode_oauth_token_from_jwt
+
+ return unless token
+
+ deploy_token = DeployToken.active.find_by_token(token.access_token_id.to_s)
+ # note: uesr_id is not a user record id, but is the attribute set on ConanToken
+ return if token.user_id != deploy_token&.username
+
+ deploy_token
+ end
+
+ def find_job_from_conan_jwt
+ token = decode_oauth_token_from_jwt
+
+ return unless token
+
+ ::Ci::Build.find_by_token(token.access_token_id.to_s)
+ end
+
+ def decode_oauth_token_from_jwt
+ jwt = Doorkeeper::OAuth::Token.from_bearer_authorization(current_request)
+
+ return unless jwt
+
+ token = ::Gitlab::ConanToken.decode(jwt)
+
+ return unless token && token.access_token_id && token.user_id
+
+ token
+ end
+ end
+ end
+ end
+ end
+end