Commit 70a33833 authored by Markus Koller's avatar Markus Koller

Merge branch 'reset-runner-authentication-token' into 'master'

API: Add endpoint to reset runner authentication token

See merge request gitlab-org/gitlab!69561
parents e3a2a18c c2e34204
......@@ -15,7 +15,7 @@ There are two tokens to take into account when connecting a runner with GitLab.
| Token | Description |
| ----- | ----------- |
| Registration token | Token used to [register the runner](https://docs.gitlab.com/runner/register/). It can be [obtained through GitLab](../ci/runners/index.md). |
| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained either automatically when [registering a runner](https://docs.gitlab.com/runner/register/), or manually when [registering the runner via the Runner API](#register-a-new-runner). |
| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runner API when you manually [register a runner](#register-a-new-runner) or [reset the authentication token](#reset-runners-authentication-token). |
Here's an example of how the two tokens are used in runner registration:
......@@ -720,3 +720,28 @@ POST /groups/:id/runners/reset_registration_token
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/groups/9/runners/reset_registration_token"
```
## Reset runner's authentication token
Resets the runner's authentication token.
```plaintext
POST /runners/:id/reset_authentication_token
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a runner |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/runners/1/reset_authentication_token"
```
Example response:
```json
{
"token": "6337ff461c94fd3fa32ba3b1ff4125"
}
```
......@@ -130,6 +130,20 @@ module API
present paginate(jobs), with: Entities::Ci::JobBasicWithProject
end
desc 'Reset runner authentication token' do
success Entities::Ci::ResetTokenResult
end
params do
requires :id, type: Integer, desc: 'The ID of the runner'
end
post ':id/reset_authentication_token' do
runner = get_runner(params[:id])
authenticate_update_runner!(runner)
runner.reset_token!
present runner.token, with: Entities::Ci::ResetTokenResult
end
end
params do
......@@ -226,13 +240,13 @@ module API
before { authenticate_non_get! }
desc 'Resets runner registration token' do
success Entities::Ci::ResetRegistrationTokenResult
success Entities::Ci::ResetTokenResult
end
post 'reset_registration_token' do
authorize! :update_runners_registration_token
ApplicationSetting.current.reset_runners_registration_token!
present ApplicationSetting.current_without_cache.runners_registration_token, with: Entities::Ci::ResetRegistrationTokenResult
present ApplicationSetting.current_without_cache.runners_registration_token, with: Entities::Ci::ResetTokenResult
end
end
......@@ -243,14 +257,14 @@ module API
before { authenticate_non_get! }
desc 'Resets runner registration token' do
success Entities::Ci::ResetRegistrationTokenResult
success Entities::Ci::ResetTokenResult
end
post ':id/runners/reset_registration_token' do
project = find_project! user_project.id
authorize! :update_runners_registration_token, project
project.reset_runners_token!
present project.runners_token, with: Entities::Ci::ResetRegistrationTokenResult
present project.runners_token, with: Entities::Ci::ResetTokenResult
end
end
......@@ -261,14 +275,14 @@ module API
before { authenticate_non_get! }
desc 'Resets runner registration token' do
success Entities::Ci::ResetRegistrationTokenResult
success Entities::Ci::ResetTokenResult
end
post ':id/runners/reset_registration_token' do
group = find_group! user_group.id
authorize! :update_runners_registration_token, group
group.reset_runners_token!
present group.runners_token, with: Entities::Ci::ResetRegistrationTokenResult
present group.runners_token, with: Entities::Ci::ResetTokenResult
end
end
......
......@@ -3,7 +3,7 @@
module API
module Entities
module Ci
class ResetRegistrationTokenResult < Grape::Entity
class ResetTokenResult < Grape::Entity
expose(:token) {|object| object}
end
end
......
......@@ -600,6 +600,94 @@ RSpec.describe API::Ci::Runners do
end
end
describe 'POST /runners/:id/reset_authentication_token' do
context 'admin user' do
it 'resets shared runner authentication token' do
expect do
post api("/runners/#{shared_runner.id}/reset_authentication_token", admin)
expect(response).to have_gitlab_http_status(:success)
expect(json_response).to eq({ 'token' => shared_runner.reload.token })
end.to change { shared_runner.reload.token }
end
it 'returns 404 if runner does not exist' do
post api('/runners/0/reset_authentication_token', admin)
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'authorized user' do
it 'does not reset project runner authentication token without access to it' do
expect do
post api("/runners/#{project_runner.id}/reset_authentication_token", user2)
expect(response).to have_gitlab_http_status(:forbidden)
end.not_to change { project_runner.reload.token }
end
it 'resets project runner authentication token for owned project' do
expect do
post api("/runners/#{project_runner.id}/reset_authentication_token", user)
expect(response).to have_gitlab_http_status(:success)
expect(json_response).to eq({ 'token' => project_runner.reload.token })
end.to change { project_runner.reload.token }
end
it 'does not reset group runner authentication token with guest access' do
expect do
post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_guest)
expect(response).to have_gitlab_http_status(:forbidden)
end.not_to change { group_runner_a.reload.token }
end
it 'does not reset group runner authentication token with reporter access' do
expect do
post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_reporter)
expect(response).to have_gitlab_http_status(:forbidden)
end.not_to change { group_runner_a.reload.token }
end
it 'does not reset group runner authentication token with developer access' do
expect do
post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_developer)
expect(response).to have_gitlab_http_status(:forbidden)
end.not_to change { group_runner_a.reload.token }
end
it 'does not reset group runner authentication token with maintainer access' do
expect do
post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_maintainer)
expect(response).to have_gitlab_http_status(:forbidden)
end.not_to change { group_runner_a.reload.token }
end
it 'resets group runner authentication token with owner access' do
expect do
post api("/runners/#{group_runner_a.id}/reset_authentication_token", user)
expect(response).to have_gitlab_http_status(:success)
expect(json_response).to eq({ 'token' => group_runner_a.reload.token })
end.to change { group_runner_a.reload.token }
end
end
context 'unauthorized user' do
it 'does not reset authentication token' do
expect do
post api("/runners/#{shared_runner.id}/reset_authentication_token")
expect(response).to have_gitlab_http_status(:unauthorized)
end.not_to change { shared_runner.reload.token }
end
end
end
describe 'GET /runners/:id/jobs' do
let_it_be(:job_1) { create(:ci_build) }
let_it_be(:job_2) { create(:ci_build, :running, runner: shared_runner, project: project) }
......
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