diff options
Diffstat (limited to 'lib/api/nuget_project_packages.rb')
-rw-r--r-- | lib/api/nuget_project_packages.rb | 120 |
1 files changed, 94 insertions, 26 deletions
diff --git a/lib/api/nuget_project_packages.rb b/lib/api/nuget_project_packages.rb index 5bae08d4dae..03d1492908d 100644 --- a/lib/api/nuget_project_packages.rb +++ b/lib/api/nuget_project_packages.rb @@ -16,6 +16,7 @@ module API feature_category :package_registry PACKAGE_FILENAME = 'package.nupkg' + SYMBOL_PACKAGE_FILENAME = 'package.snupkg' default_format :json @@ -33,6 +34,10 @@ module API end helpers do + params :file_params do + requires :package, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)' + end + def project_or_group authorized_user_project end @@ -40,6 +45,49 @@ module API def snowplow_gitlab_standard_context { project: authorized_user_project, namespace: authorized_user_project.namespace } end + + def authorize_nuget_upload + authorize_workhorse!( + subject: project_or_group, + has_length: false, + maximum_size: project_or_group.actual_limits.nuget_max_file_size + ) + end + + def temp_file_name(symbol_package) + return ::Packages::Nuget::TEMPORARY_SYMBOL_PACKAGE_NAME if symbol_package + + ::Packages::Nuget::TEMPORARY_PACKAGE_NAME + end + + def file_name(symbol_package) + return SYMBOL_PACKAGE_FILENAME if symbol_package + + PACKAGE_FILENAME + end + + def upload_nuget_package_file(symbol_package: false) + authorize_upload!(project_or_group) + bad_request!('File is too large') if project_or_group.actual_limits.exceeded?(:nuget_max_file_size, params[:package].size) + + file_params = params.merge( + file: params[:package], + file_name: file_name(symbol_package) + ) + + package = ::Packages::CreateTemporaryPackageService.new( + project_or_group, current_user, declared_params.merge(build: current_authenticated_job) + ).execute(:nuget, name: temp_file_name(symbol_package)) + + package_file = ::Packages::CreatePackageFileService.new(package, file_params.merge(build: current_authenticated_job)) + .execute + + yield(package) if block_given? + + ::Packages::Nuget::ExtractionWorker.perform_async(package_file.id) # rubocop:disable CodeReuse/Worker + + created! + end end params do @@ -55,40 +103,54 @@ module API end params do - requires :package, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)' + use :file_params end put do - authorize_upload!(project_or_group) - bad_request!('File is too large') if project_or_group.actual_limits.exceeded?(:nuget_max_file_size, params[:package].size) - - file_params = params.merge( - file: params[:package], - file_name: PACKAGE_FILENAME - ) - - package = ::Packages::CreateTemporaryPackageService.new( - project_or_group, current_user, declared_params.merge(build: current_authenticated_job) - ).execute(:nuget, name: ::Packages::Nuget::TEMPORARY_PACKAGE_NAME) - - package_file = ::Packages::CreatePackageFileService.new(package, file_params.merge(build: current_authenticated_job)) - .execute + upload_nuget_package_file do |package| + track_package_event( + 'push_package', + :nuget, + category: 'API::NugetPackages', + user: current_user, + project: package.project, + namespace: package.project.namespace + ) + end + rescue ObjectStorage::RemoteStoreError => e + Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: project_or_group.id }) - track_package_event('push_package', :nuget, category: 'API::NugetPackages', user: current_user, project: package.project, namespace: package.project.namespace) + forbidden! + end + put 'authorize' do + authorize_nuget_upload + end - ::Packages::Nuget::ExtractionWorker.perform_async(package_file.id) # rubocop:disable CodeReuse/Worker + # https://docs.microsoft.com/en-us/nuget/api/symbol-package-publish-resource + desc 'The NuGet Symbol Package Publish endpoint' do + detail 'This feature was introduced in GitLab 14.1' + end - created! + params do + use :file_params + end + put 'symbolpackage' do + upload_nuget_package_file(symbol_package: true) do |package| + track_package_event( + 'push_symbol_package', + :nuget, + category: 'API::NugetPackages', + user: current_user, + project: package.project, + namespace: package.project.namespace + ) + end rescue ObjectStorage::RemoteStoreError => e Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: project_or_group.id }) forbidden! end - put 'authorize' do - authorize_workhorse!( - subject: project_or_group, - has_length: false, - maximum_size: project_or_group.actual_limits.nuget_max_file_size - ) + put 'symbolpackage/authorize' do + authorize_nuget_upload end # https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource @@ -115,14 +177,20 @@ module API requires :package_version, type: String, desc: 'The NuGet package version', regexp: API::NO_SLASH_URL_PART_REGEX requires :package_filename, type: String, desc: 'The NuGet package filename', regexp: API::NO_SLASH_URL_PART_REGEX end - get '*package_version/*package_filename', format: :nupkg do + get '*package_version/*package_filename', format: [:nupkg, :snupkg] do filename = "#{params[:package_filename]}.#{params[:format]}" package_file = ::Packages::PackageFileFinder.new(find_package(params[:package_name], params[:package_version]), filename, with_file_name_like: true) .execute not_found!('Package') unless package_file - track_package_event('pull_package', :nuget, category: 'API::NugetPackages', project: package_file.project, namespace: package_file.project.namespace) + track_package_event( + params[:format] == 'snupkg' ? 'pull_symbol_package' : 'pull_package', + :nuget, + category: 'API::NugetPackages', + project: package_file.project, + namespace: package_file.project.namespace + ) # nuget and dotnet don't support 302 Moved status codes, supports_direct_download has to be set to false present_carrierwave_file!(package_file.file, supports_direct_download: false) |