diff options
Diffstat (limited to 'lib/api/rubygem_packages.rb')
-rw-r--r-- | lib/api/rubygem_packages.rb | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/lib/api/rubygem_packages.rb b/lib/api/rubygem_packages.rb index 7819aab879c..8d2d4586d8d 100644 --- a/lib/api/rubygem_packages.rb +++ b/lib/api/rubygem_packages.rb @@ -12,7 +12,7 @@ module API # The Marshal version can be found by "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" # Updating the version should require a GitLab API version change. MARSHAL_VERSION = '4.8' - + PACKAGE_FILENAME = 'package.gem' FILE_NAME_REQUIREMENTS = { file_name: API::NO_SLASH_URL_PART_REGEX }.freeze @@ -26,7 +26,7 @@ module API before do require_packages_enabled! - authenticate! + authenticate_non_get! not_found! unless Feature.enabled?(:rubygem_packages, user_project) end @@ -64,8 +64,15 @@ module API requires :file_name, type: String, desc: 'Package file name' end get "gems/:file_name", requirements: FILE_NAME_REQUIREMENTS do - # To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299283 - not_found! + authorize!(:read_package, user_project) + + package_file = ::Packages::PackageFile.for_rubygem_with_file_name( + user_project, params[:file_name] + ).last! + + track_package_event('pull_package', :rubygems) + + present_carrierwave_file!(package_file.file) end namespace 'api/v1' do @@ -73,27 +80,69 @@ module API detail 'This feature was introduced in GitLab 13.9' end post 'gems/authorize' do - # To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299263 - not_found! + authorize_workhorse!( + subject: user_project, + has_length: false, + maximum_size: user_project.actual_limits.rubygems_max_file_size + ) end desc 'Upload a gem' do detail 'This feature was introduced in GitLab 13.9' end + params do + requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)' + end post 'gems' do - # To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299263 - not_found! + authorize_upload!(user_project) + bad_request!('File is too large') if user_project.actual_limits.exceeded?(:rubygems_max_file_size, params[:file].size) + + track_package_event('push_package', :rubygems) + + ActiveRecord::Base.transaction do + package = ::Packages::CreateTemporaryPackageService.new( + user_project, current_user, declared_params.merge(build: current_authenticated_job) + ).execute(:rubygems, name: ::Packages::Rubygems::TEMPORARY_PACKAGE_NAME) + + file_params = { + file: params[:file], + file_name: PACKAGE_FILENAME + } + + ::Packages::CreatePackageFileService.new( + package, file_params.merge(build: current_authenticated_job) + ).execute + end + + created! + rescue ObjectStorage::RemoteStoreError => e + Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: user_project.id }) + + forbidden! end desc 'Fetch a list of dependencies' do detail 'This feature was introduced in GitLab 13.9' end params do - optional :gems, type: String, desc: 'Comma delimited gem names' + optional :gems, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma delimited gem names' end get 'dependencies' do - # To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299282 - not_found! + authorize_read_package! + + if params[:gems].blank? + status :ok + else + results = params[:gems].map do |gem_name| + service_result = Packages::Rubygems::DependencyResolverService.new(user_project, current_user, gem_name: gem_name).execute + render_api_error!(service_result.message, service_result.http_status) if service_result.error? + + service_result.payload + end + + content_type 'application/octet-stream' + Marshal.dump(results.flatten) + end end end end |