Skip to content
Snippets Groups Projects
Commit a4980683 authored by Shinya Maeda's avatar Shinya Maeda :two:
Browse files

Merge branch 'feature/release-links-api-job-token' into 'master'

Allow `CI_JOB_TOKEN` auth for release links API

See merge request !89958
parents 1c2635f8 39b37971
No related branches found
No related tags found
1 merge request!89958Allow `CI_JOB_TOKEN` auth for release links API
Pipeline #563411552 passed
...@@ -6,21 +6,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -6,21 +6,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Release links API **(FREE)** # Release links API **(FREE)**
> Support for [GitLab CI/CD job token](../../ci/jobs/ci_job_token.md) authentication [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250819) in GitLab 15.1.
Use this API to manipulate GitLab [Release](../../user/project/releases/index.md) Use this API to manipulate GitLab [Release](../../user/project/releases/index.md)
links. For manipulating other Release assets, see [Release API](index.md). links. For manipulating other Release assets, see [Release API](index.md).
GitLab supports links to `http`, `https`, and `ftp` assets. GitLab supports links to `http`, `https`, and `ftp` assets.
## Authentication
For authentication, the Release Links API accepts:
- A [Personal Access Token](../../user/profile/personal_access_tokens.md) using the
`PRIVATE-TOKEN` header.
- A [Project Access Token](../../user/project/settings/project_access_tokens.md) using the `PRIVATE-TOKEN` header.
The [GitLab CI/CD job token](../../ci/jobs/ci_job_token.md) `$CI_JOB_TOKEN` is not supported. See [GitLab issue #50819](https://gitlab.com/gitlab-org/gitlab/-/issues/250819) for more details.
## Get links ## Get links
Get assets as links from a Release. Get assets as links from a Release.
......
...@@ -20,7 +20,7 @@ You can use a GitLab CI/CD job token to authenticate with specific API endpoints ...@@ -20,7 +20,7 @@ You can use a GitLab CI/CD job token to authenticate with specific API endpoints
- [Get job artifacts](../../api/job_artifacts.md#get-job-artifacts). - [Get job artifacts](../../api/job_artifacts.md#get-job-artifacts).
- [Get job token's job](../../api/jobs.md#get-job-tokens-job). - [Get job token's job](../../api/jobs.md#get-job-tokens-job).
- [Pipeline triggers](../../api/pipeline_triggers.md), using the `token=` parameter. - [Pipeline triggers](../../api/pipeline_triggers.md), using the `token=` parameter.
- [Releases](../../api/releases/index.md). - [Releases](../../api/releases/index.md) and [Release links](../../api/releases/links.md).
- [Terraform plan](../../user/infrastructure/index.md). - [Terraform plan](../../user/infrastructure/index.md).
NOTE: NOTE:
......
...@@ -29,6 +29,7 @@ class Links < ::API::Base ...@@ -29,6 +29,7 @@ class Links < ::API::Base
params do params do
use :pagination use :pagination
end end
route_setting :authentication, job_token_allowed: true
get 'links' do get 'links' do
authorize! :read_release, release authorize! :read_release, release
...@@ -45,6 +46,7 @@ class Links < ::API::Base ...@@ -45,6 +46,7 @@ class Links < ::API::Base
optional :filepath, type: String, desc: 'The filepath of the link' optional :filepath, type: String, desc: 'The filepath of the link'
optional :link_type, type: String, desc: 'The link type, one of: "runbook", "image", "package" or "other"' optional :link_type, type: String, desc: 'The link type, one of: "runbook", "image", "package" or "other"'
end end
route_setting :authentication, job_token_allowed: true
post 'links' do post 'links' do
authorize! :create_release, release authorize! :create_release, release
...@@ -65,6 +67,7 @@ class Links < ::API::Base ...@@ -65,6 +67,7 @@ class Links < ::API::Base
detail 'This feature was introduced in GitLab 11.7.' detail 'This feature was introduced in GitLab 11.7.'
success Entities::Releases::Link success Entities::Releases::Link
end end
route_setting :authentication, job_token_allowed: true
get do get do
authorize! :read_release, release authorize! :read_release, release
...@@ -82,6 +85,7 @@ class Links < ::API::Base ...@@ -82,6 +85,7 @@ class Links < ::API::Base
optional :link_type, type: String, desc: 'The link type' optional :link_type, type: String, desc: 'The link type'
at_least_one_of :name, :url at_least_one_of :name, :url
end end
route_setting :authentication, job_token_allowed: true
put do put do
authorize! :update_release, release authorize! :update_release, release
...@@ -96,6 +100,7 @@ class Links < ::API::Base ...@@ -96,6 +100,7 @@ class Links < ::API::Base
detail 'This feature was introduced in GitLab 11.7.' detail 'This feature was introduced in GitLab 11.7.'
success Entities::Releases::Link success Entities::Releases::Link
end end
route_setting :authentication, job_token_allowed: true
delete do delete do
authorize! :destroy_release, release authorize! :destroy_release, release
......
...@@ -49,6 +49,20 @@ ...@@ -49,6 +49,20 @@
expect(response).to match_response_schema('release/links') expect(response).to match_response_schema('release/links')
end end
context 'when using JOB-TOKEN auth' do
let(:job) { create(:ci_build, :running, user: maintainer) }
it 'returns releases links' do
get api("/projects/#{project.id}/releases/v0.1/assets/links", job_token: job.token)
aggregate_failures "testing response" do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('release/links')
expect(json_response.count).to eq(2)
end
end
end
end end
context 'when release does not exist' do context 'when release does not exist' do
...@@ -116,6 +130,20 @@ ...@@ -116,6 +130,20 @@
expect(response).to match_response_schema('release/link') expect(response).to match_response_schema('release/link')
end end
context 'when using JOB-TOKEN auth' do
let(:job) { create(:ci_build, :running, user: maintainer) }
it 'returns releases link' do
get api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", job_token: job.token)
aggregate_failures "testing response" do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('release/link')
expect(json_response['name']).to eq(release_link.name)
end
end
end
context 'when specified tag is not found in the project' do context 'when specified tag is not found in the project' do
it_behaves_like '404 response' do it_behaves_like '404 response' do
let(:request) { get api("/projects/#{project.id}/releases/non_existing_tag/assets/links/#{release_link.id}", maintainer) } let(:request) { get api("/projects/#{project.id}/releases/non_existing_tag/assets/links/#{release_link.id}", maintainer) }
...@@ -198,6 +226,25 @@ ...@@ -198,6 +226,25 @@
expect(response).to match_response_schema('release/link') expect(response).to match_response_schema('release/link')
end end
context 'when using JOB-TOKEN auth' do
let(:job) { create(:ci_build, :running, user: maintainer) }
it 'creates a new release link' do
expect do
post api("/projects/#{project.id}/releases/v0.1/assets/links"), params: params.merge(job_token: job.token)
end.to change { Releases::Link.count }.by(1)
release.reload
aggregate_failures "testing response" do
expect(response).to have_gitlab_http_status(:created)
expect(last_release_link.name).to eq('awesome-app.dmg')
expect(last_release_link.filepath).to eq('/binaries/awesome-app.dmg')
expect(last_release_link.url).to eq('https://example.com/download/awesome-app.dmg')
end
end
end
context 'with protected tag' do context 'with protected tag' do
context 'when user has access to the protected tag' do context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) } let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
...@@ -314,6 +361,20 @@ ...@@ -314,6 +361,20 @@
expect(response).to match_response_schema('release/link') expect(response).to match_response_schema('release/link')
end end
context 'when using JOB-TOKEN auth' do
let(:job) { create(:ci_build, :running, user: maintainer) }
it 'updates the release link' do
put api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}"), params: params.merge(job_token: job.token)
aggregate_failures "testing response" do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('release/link')
expect(json_response['name']).to eq('awesome-app.msi')
end
end
end
context 'with protected tag' do context 'with protected tag' do
context 'when user has access to the protected tag' do context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) } let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
...@@ -411,6 +472,21 @@ ...@@ -411,6 +472,21 @@
expect(response).to match_response_schema('release/link') expect(response).to match_response_schema('release/link')
end end
context 'when using JOB-TOKEN auth' do
let(:job) { create(:ci_build, :running, user: maintainer) }
it 'deletes the release link' do
expect do
delete api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", job_token: job.token)
end.to change { Releases::Link.count }.by(-1)
aggregate_failures "testing response" do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('release/link')
end
end
end
context 'with protected tag' do context 'with protected tag' do
context 'when user has access to the protected tag' do context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) } let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment