Commit 4d8ed076 authored by Steve Abrams's avatar Steve Abrams Committed by Michael Kozono

Add API endpoint for creating group deploy tokens

API endpoint for creating deploy tokens for
a group requiring maintainer level access.
parent 59117474
......@@ -95,6 +95,7 @@ class GroupPolicy < BasePolicy
enable :admin_cluster
enable :destroy_deploy_token
enable :read_deploy_token
enable :create_deploy_token
end
rule { owner }.policy do
......
---
title: Add api endpoint for creating group deploy tokens
merge_request: 25629
author:
type: added
......@@ -156,6 +156,45 @@ Example response:
]
```
### Create a group deploy token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
Creates a new deploy token for a group.
```
POST /groups/:id/deploy_tokens
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | New deploy token's name |
| `expires_at` | datetime | no | Expiration date for the deploy token. Does not expire if no value is provided. |
| `username` | string | no | Username for deploy token. Default is `gitlab+deploy-token-{n}` |
| `scopes` | array of strings | yes | Indicates the deploy token scopes. Must be at least one of `read_repository` or `read_registry`. |
Example request:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data '{"name": "My deploy token", "expires_at": "2021-01-01", "username": "custom-user", "scopes": ["read_repository"]}' "https://gitlab.example.com/api/v4/groups/5/deploy_tokens/"
```
Example response:
```json
{
"id": 1,
"name": "My deploy token",
"username": "custom-user",
"expires_at": "2021-01-01T00:00:00.000Z",
"token": "jMRvtPNxrn3crTAGukpZ",
"scopes": [
"read_registry"
]
}
```
### Delete a group deploy token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
......
......@@ -31,7 +31,7 @@ module API
end
params do
requires :id, type: Integer, desc: 'The ID of a project'
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before do
......@@ -74,7 +74,7 @@ module API
end
params do
requires :id, type: Integer, desc: 'The ID of a group'
requires :id, type: String, desc: 'The ID of a group'
end
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before do
......@@ -94,6 +94,27 @@ module API
present paginate(user_group.deploy_tokens), with: Entities::DeployToken
end
params do
requires :name, type: String, desc: 'The name of the deploy token'
requires :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided.'
requires :username, type: String, desc: 'Username for deploy token. Default is `gitlab+deploy-token-{n}`'
requires :scopes, type: Array[String], values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
desc: 'Indicates the deploy token scopes. Must be at least one of "read_repository" or "read_registry".'
end
desc 'Create a group deploy token' do
detail 'This feature was introduced in GitLab 12.9'
success Entities::DeployTokenWithToken
end
post ':id/deploy_tokens' do
authorize!(:create_deploy_token, user_group)
deploy_token = ::Groups::DeployTokens::CreateService.new(
user_group, current_user, scope_params.merge(declared(params, include_missing: false, include_parent_namespaces: false))
).execute
present deploy_token, with: Entities::DeployTokenWithToken
end
desc 'Delete a group deploy token' do
detail 'This feature was introduced in GitLab 12.9'
end
......
......@@ -195,56 +195,71 @@ describe API::DeployTokens do
end
end
describe 'POST /projects/:id/deploy_tokens' do
let(:params) do
{
name: 'Foo',
expires_at: 1.year.from_now,
scopes: [
'read_repository'
],
username: 'Bar'
}
end
context 'deploy token creation' do
shared_examples 'creating a deploy token' do |entity, unauthenticated_response|
let(:params) do
{
name: 'Foo',
expires_at: 1.year.from_now,
scopes: [
'read_repository'
],
username: 'Bar'
}
end
subject do
post api("/projects/#{project.id}/deploy_tokens", user), params: params
response
end
context 'when unauthenticated' do
let(:user) { nil }
context 'when unauthenticated' do
let(:user) { nil }
it { is_expected.to have_gitlab_http_status(unauthenticated_response) }
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
context 'when authenticated as non-admin user' do
before do
send(entity).add_developer(user)
end
context 'when authenticated as non-admin user' do
before do
project.add_developer(user)
it { is_expected.to have_gitlab_http_status(:forbidden) }
end
it { is_expected.to have_gitlab_http_status(:forbidden) }
end
context 'when authenticated as maintainer' do
before do
send(entity).add_maintainer(user)
end
context 'when authenticated as maintainer' do
before do
project.add_maintainer(user)
end
it 'creates the deploy token' do
expect { subject }.to change { DeployToken.count }.by(1)
it 'creates the deploy token' do
expect { subject }.to change { DeployToken.count }.by(1)
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/deploy_token')
end
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/deploy_token')
end
context 'with an invalid scope' do
before do
params[:scopes] = %w[read_repository all_access]
end
context 'with an invalid scope' do
before do
params[:scopes] = %w[read_repository all_access]
it { is_expected.to have_gitlab_http_status(:bad_request) }
end
end
end
describe 'POST /projects/:id/deploy_tokens' do
subject do
post api("/projects/#{project.id}/deploy_tokens", user), params: params
response
end
it_behaves_like 'creating a deploy token', :project, :not_found
end
it { is_expected.to have_gitlab_http_status(:bad_request) }
describe 'POST /groups/:id/deploy_tokens' do
subject do
post api("/groups/#{group.id}/deploy_tokens", user), params: params
response
end
it_behaves_like 'creating a deploy token', :group, :forbidden
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