From 3cea963ff14e61f60fe9fff45d81fd3bdbd39d1d Mon Sep 17 00:00:00 2001
From: Guillaume CHAUVEL <guillaume.chauvel@gmail.com>
Date: Sun, 17 Oct 2021 13:13:27 +0200
Subject: [PATCH] Allow job token to perform all release REST API operations

According to the documentation, release REST API operations
are possible using either a private or a job token

Changelog: fixed
---
 doc/api/releases/index.md             | 11 ++++++++-
 doc/ci/jobs/ci_job_token.md           |  2 +-
 ee/lib/ee/api/releases.rb             |  1 +
 ee/spec/requests/api/releases_spec.rb |  8 +++++++
 lib/api/releases.rb                   |  4 ++++
 spec/requests/api/releases_spec.rb    | 32 +++++++++++++++++++++++++++
 6 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md
index ded47b24c123ec9d..c253358f01f008ab 100644
--- a/doc/api/releases/index.md
+++ b/doc/api/releases/index.md
@@ -26,6 +26,8 @@ For authentication, the Releases API accepts either:
 
 ## List Releases
 
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
+
 Paginated list of Releases, sorted by `released_at`.
 
 ```plaintext
@@ -231,6 +233,8 @@ Example response:
 
 ## Get a Release by a tag name
 
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
+
 Get a Release for the given tag.
 
 ```plaintext
@@ -508,7 +512,8 @@ adding milestones for ancestor groups raises an error.
 
 ## Collect release evidence **(PREMIUM SELF)**
 
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199065) in GitLab 12.10.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199065) in GitLab 12.10.
+> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
 
 Create Evidence for an existing Release.
 
@@ -535,6 +540,8 @@ Example response:
 
 ## Update a release
 
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
+
 Update a release. Developer level access to the project is required to update a release.
 
 ```plaintext
@@ -642,6 +649,8 @@ Example response:
 
 ## Delete a Release
 
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
+
 Delete a release. Deleting a release doesn't delete the associated tag. Maintainer level access to the project is required to delete a release.
 
 ```plaintext
diff --git a/doc/ci/jobs/ci_job_token.md b/doc/ci/jobs/ci_job_token.md
index 308f38b22b79dc1d..b6a3011a3d6c272e 100644
--- a/doc/ci/jobs/ci_job_token.md
+++ b/doc/ci/jobs/ci_job_token.md
@@ -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 token's job](../../api/jobs.md#get-job-tokens-job).
 - [Pipeline triggers](../../api/pipeline_triggers.md), using the `token=` parameter.
-- [Release creation](../../api/releases/index.md#create-a-release).
+- [Releases](../../api/releases/index.md).
 - [Terraform plan](../../user/infrastructure/index.md).
 
 The token has the same permissions to access the API as the user that executes the
diff --git a/ee/lib/ee/api/releases.rb b/ee/lib/ee/api/releases.rb
index efbf3134d8ca5a68..e5b08ccff0ef8d03 100644
--- a/ee/lib/ee/api/releases.rb
+++ b/ee/lib/ee/api/releases.rb
@@ -14,6 +14,7 @@ module Releases
           params do
             requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
           end
+          route_setting :authentication, job_token_allowed: true
           post ':id/releases/:tag_name/evidence', requirements: ::API::Releases::RELEASE_ENDPOINT_REQUIREMENTS do
             authorize_create_evidence!
 
diff --git a/ee/spec/requests/api/releases_spec.rb b/ee/spec/requests/api/releases_spec.rb
index 2bc9a5a71e23f668..8cddfb63157b0201 100644
--- a/ee/spec/requests/api/releases_spec.rb
+++ b/ee/spec/requests/api/releases_spec.rb
@@ -270,6 +270,14 @@
       expect(response).to have_gitlab_http_status(:accepted)
     end
 
+    it 'accepts the request when using JOB-TOKEN auth' do
+      job = create(:ci_build, :running, project: project, user: maintainer)
+
+      post api("/projects/#{project.id}/releases/#{tag_name}/evidence"), params: { job_token: job.token }
+
+      expect(response).to have_gitlab_http_status(:accepted)
+    end
+
     it 'creates the Evidence', :sidekiq_inline do
       expect do
         post api("/projects/#{project.id}/releases/#{tag_name}/evidence", maintainer)
diff --git a/lib/api/releases.rb b/lib/api/releases.rb
index 3b7e2b4bd279875e..7b89a177fd9c6e5a 100644
--- a/lib/api/releases.rb
+++ b/lib/api/releases.rb
@@ -32,6 +32,7 @@ class Releases < ::API::Base
         optional :include_html_description, type: Boolean,
                                desc: 'If `true`, a response includes HTML rendered markdown of the release description.'
       end
+      route_setting :authentication, job_token_allowed: true
       get ':id/releases' do
         releases = ::ReleasesFinder.new(user_project, current_user, declared_params.slice(:order_by, :sort)).execute
 
@@ -59,6 +60,7 @@ class Releases < ::API::Base
         optional :include_html_description, type: Boolean,
                                desc: 'If `true`, a response includes HTML rendered markdown of the release description.'
       end
+      route_setting :authentication, job_token_allowed: true
       get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
         authorize_download_code!
 
@@ -117,6 +119,7 @@ class Releases < ::API::Base
         optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready.'
         optional :milestones,  type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The titles of the related milestones'
       end
+      route_setting :authentication, job_token_allowed: true
       put ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
         authorize_update_release!
 
@@ -142,6 +145,7 @@ class Releases < ::API::Base
       params do
         requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
       end
+      route_setting :authentication, job_token_allowed: true
       delete ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
         authorize_destroy_release!
 
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index 90b03a480a85e9e5..cb9b6a072b112e46 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -42,6 +42,14 @@
         expect(response).to have_gitlab_http_status(:ok)
       end
 
+      it 'returns 200 HTTP status when using JOB-TOKEN auth' do
+        job = create(:ci_build, :running, project: project, user: maintainer)
+
+        get api("/projects/#{project.id}/releases"), params: { job_token: job.token }
+
+        expect(response).to have_gitlab_http_status(:ok)
+      end
+
       it 'returns releases ordered by released_at' do
         get api("/projects/#{project.id}/releases", maintainer)
 
@@ -316,6 +324,14 @@
         expect(response).to have_gitlab_http_status(:ok)
       end
 
+      it 'returns 200 HTTP status when using JOB-TOKEN auth' do
+        job = create(:ci_build, :running, project: project, user: maintainer)
+
+        get api("/projects/#{project.id}/releases/v0.1"), params: { job_token: job.token }
+
+        expect(response).to have_gitlab_http_status(:ok)
+      end
+
       it 'returns a release entry' do
         get api("/projects/#{project.id}/releases/v0.1", maintainer)
 
@@ -1008,6 +1024,14 @@
       expect(response).to have_gitlab_http_status(:ok)
     end
 
+    it 'accepts the request when using JOB-TOKEN auth' do
+      job = create(:ci_build, :running, project: project, user: maintainer)
+
+      put api("/projects/#{project.id}/releases/v0.1"), params: params.merge(job_token: job.token)
+
+      expect(response).to have_gitlab_http_status(:ok)
+    end
+
     it 'updates the description' do
       put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
 
@@ -1220,6 +1244,14 @@
       expect(response).to have_gitlab_http_status(:ok)
     end
 
+    it 'accepts the request when using JOB-TOKEN auth' do
+      job = create(:ci_build, :running, project: project, user: maintainer)
+
+      delete api("/projects/#{project.id}/releases/v0.1"), params: { job_token: job.token }
+
+      expect(response).to have_gitlab_http_status(:ok)
+    end
+
     it 'destroys the release' do
       expect do
         delete api("/projects/#{project.id}/releases/v0.1", maintainer)
-- 
GitLab