Commit f0ee4f0d authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Add package files API endpoint

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parent adacce89
......@@ -41,3 +41,58 @@ Example response:
```
By default, the `GET` request will return 20 results, since the API is [paginated](README.md#pagination).
## List package files
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/9305) in GitLab 11.8.
Get a list of package files of a single package.
```
GET /projects/:id/packages/:package_id/package_files
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
| `package_id` | integer | yes | The ID of a package. |
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/packages/4/package_files
```
Example response:
```json
[
{
"id": 25,
"package_id": 4,
"created_at": "2018-11-07T15:25:52.199Z",
"file_name": "my-app-1.5-20181107.152550-1.jar",
"size": 2421,
"file_md5": "58e6a45a629910c6ff99145a688971ac",
"file_sha1": "ebd193463d3915d7e22219f52740056dfd26cbfe"
},
{
"id": 26,
"package_id": 4,
"created_at": "2018-11-07T15:25:56.776Z",
"file_name": "my-app-1.5-20181107.152550-1.pom",
"size": 1122,
"file_md5": "d90f11d851e17c5513586b4a7e98f1b2",
"file_sha1": "9608d068fe88aff85781811a42f32d97feb440b5"
},
{
"id": 27,
"package_id": 4,
"created_at": "2018-11-07T15:26:00.556Z",
"file_name": "maven-metadata.xml",
"size": 767,
"file_md5": "6dfd0cce1203145a927fef5e3a1c650c",
"file_sha1": "d25932de56052d320a8ac156f745ece73f6a8cd2"
}
]
```
By default, the `GET` request will return 20 results, since the API is [paginated](README.md#pagination).
# frozen_string_literal: true
module Packages
class PackageFinder
def initialize(project, package_id)
@project = project
@package_id = package_id
end
def execute
@project.packages.find(@package_id)
end
end
end
---
title: Add package files API endpoint
merge_request: 9305
author:
type: added
# frozen_string_literal: true
module API
class PackageFiles < Grape::API
include PaginationParams
before do
require_packages_enabled!
authorize_packages_feature!
authorize_read_package!
end
helpers ::API::Helpers::PackagesHelpers
params do
requires :id, type: String, desc: 'The ID of a project'
requires :package_id, type: Integer, desc: 'The ID of a package'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all package files' do
detail 'This feature was introduced in GitLab 11.8'
success EE::API::Entities::PackageFile
end
params do
use :pagination
end
get ':id/packages/:package_id/package_files' do
package = ::Packages::PackageFinder
.new(user_project, params[:package_id]).execute
present paginate(package.package_files), with: EE::API::Entities::PackageFile
end
end
end
end
......@@ -23,6 +23,7 @@ module EE
mount ::API::MavenPackages
mount ::API::NpmPackages
mount ::API::Packages
mount ::API::PackageFiles
end
end
end
......
......@@ -507,6 +507,12 @@ module EE
expose :version
expose :package_type
end
class PackageFile < Grape::Entity
expose :id, :package_id, :created_at
expose :file_name, :size
expose :file_md5, :file_sha1
end
end
end
end
{
"type": "array",
"items": {
"type": "object",
"required" : ["id", "package_id", "file_name"],
"properties" : {
"id": { "type": "integer" },
"package_id": { "type": "integer" },
"file_name": { "type": "string" },
"file_sha1": { "type": "string" }
}
}
}
# frozen_string_literal: true
require 'spec_helper'
describe API::PackageFiles do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:package) { create(:maven_package, project: project) }
before do
project.add_developer(user)
end
describe 'GET /projects/:id/packages/:package_id/package_files' do
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files" }
context 'packages feature enabled' do
before do
stub_licensed_features(packages: true)
end
context 'project is public' do
it 'returns 200' do
get api(url)
expect(response).to have_gitlab_http_status(200)
end
it 'returns 404 if package does not exist' do
get api("/projects/#{project.id}/packages/0/package_files")
expect(response).to have_gitlab_http_status(404)
end
end
context 'project is private' do
let(:project) { create(:project, :private) }
it 'returns 404 for non authenticated user' do
get api(url)
expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 for a user without access to the project' do
project.team.truncate
get api(url, user)
expect(response).to have_gitlab_http_status(404)
end
it 'returns 200 and valid response schema' do
get api(url, user)
expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/packages/package_files', dir: 'ee')
end
end
context 'with pagination params' do
let(:per_page) { 2 }
let!(:package_file_1) { package.package_files[0] }
let!(:package_file_2) { package.package_files[1] }
let!(:package_file_3) { package.package_files[2] }
before do
stub_licensed_features(packages: true)
end
context 'when viewing the first page' do
it 'returns first 2 packages' do
get api(url, user), params: { page: 1, per_page: per_page }
expect_paginated_array_response([package_file_1.id, package_file_2.id])
end
end
context 'viewing the second page' do
it 'returns the last package' do
get api(url, user), params: { page: 2, per_page: per_page }
expect_paginated_array_response([package_file_3.id])
end
end
end
end
context 'packages feature disabled' do
before do
stub_licensed_features(packages: false)
end
it 'returns 403' do
get api(url, user)
expect(response).to have_gitlab_http_status(403)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment