Merge branch 'api-gpg-key-management' into 'master'
API: Add GPG key management Closes #36926 See merge request !13828
This commit is contained in:
commit
063e285e6a
5 changed files with 696 additions and 0 deletions
5
changelogs/unreleased/api-gpg-key-management.yml
Normal file
5
changelogs/unreleased/api-gpg-key-management.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: 'API: Add GPG key management'
|
||||
merge_request: 13828
|
||||
author: Robert Schilling
|
||||
type: added
|
211
doc/api/users.md
211
doc/api/users.md
|
@ -550,6 +550,217 @@ Parameters:
|
|||
|
||||
Will return `200 OK` on success, or `404 Not found` if either user or key cannot be found.
|
||||
|
||||
## List all GPG keys
|
||||
|
||||
Get a list of currently authenticated user's GPG keys.
|
||||
|
||||
```
|
||||
GET /user/gpg_keys
|
||||
```
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----",
|
||||
"created_at": "2017-09-05T09:17:46.264Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Get a specific GPG key
|
||||
|
||||
Get a specific GPG key of currently authenticated user.
|
||||
|
||||
```
|
||||
GET /user/gpg_keys/:key_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `key_id` | integer | yes | The ID of the GPG key |
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys/1
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----",
|
||||
"created_at": "2017-09-05T09:17:46.264Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Add a GPG key
|
||||
|
||||
Creates a new GPG key owned by the currently authenticated user.
|
||||
|
||||
```
|
||||
POST /user/gpg_keys
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| key | string | yes | The new GPG key |
|
||||
|
||||
```bash
|
||||
curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----",
|
||||
"created_at": "2017-09-05T09:17:46.264Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Delete a GPG key
|
||||
|
||||
Delete a GPG key owned by currently authenticated user.
|
||||
|
||||
```
|
||||
DELETE /user/gpg_keys/:key_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `key_id` | integer | yes | The ID of the GPG key |
|
||||
|
||||
```bash
|
||||
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys/1
|
||||
```
|
||||
|
||||
Returns `204 No Content` on success, or `404 Not found` if the key cannot be found.
|
||||
|
||||
## List all GPG keys for given user
|
||||
|
||||
Get a list of a specified user's GPG keys. Available only for admins.
|
||||
|
||||
```
|
||||
GET /users/:id/gpg_keys
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer | yes | The ID of the user |
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----",
|
||||
"created_at": "2017-09-05T09:17:46.264Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Get a specific GPG key for a given user
|
||||
|
||||
Get a specific GPG key for a given user. Available only for admins.
|
||||
|
||||
```
|
||||
GET /users/:id/gpg_keys/:key_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer | yes | The ID of the user |
|
||||
| `key_id` | integer | yes | The ID of the GPG key |
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys/1
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----",
|
||||
"created_at": "2017-09-05T09:17:46.264Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Add a GPG key for a given user
|
||||
|
||||
Create new GPG key owned by the specified user. Available only for admins.
|
||||
|
||||
```
|
||||
POST /users/:id/gpg_keys
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer | yes | The ID of the user |
|
||||
| `key_id` | integer | yes | The ID of the GPG key |
|
||||
|
||||
```bash
|
||||
curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----",
|
||||
"created_at": "2017-09-05T09:17:46.264Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Delete a GPG key for a given user
|
||||
|
||||
Delete a GPG key owned by a specified user. Available only for admins.
|
||||
|
||||
```
|
||||
DELETE /users/:id/gpg_keys/:key_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer | yes | The ID of the user |
|
||||
| `key_id` | integer | yes | The ID of the GPG key |
|
||||
|
||||
```bash
|
||||
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys/1
|
||||
```
|
||||
|
||||
## List emails
|
||||
|
||||
Get a list of currently authenticated user's emails.
|
||||
|
|
|
@ -491,6 +491,10 @@ module API
|
|||
expose :user, using: Entities::UserPublic
|
||||
end
|
||||
|
||||
class GPGKey < Grape::Entity
|
||||
expose :id, :key, :created_at
|
||||
end
|
||||
|
||||
class Note < Grape::Entity
|
||||
# Only Issue and MergeRequest have iid
|
||||
NOTEABLE_TYPES_WITH_IID = %w(Issue MergeRequest).freeze
|
||||
|
|
150
lib/api/users.rb
150
lib/api/users.rb
|
@ -233,6 +233,86 @@ module API
|
|||
destroy_conditionally!(key)
|
||||
end
|
||||
|
||||
desc 'Add a GPG key to a specified user. Available only for admins.' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
success Entities::GPGKey
|
||||
end
|
||||
params do
|
||||
requires :id, type: Integer, desc: 'The ID of the user'
|
||||
requires :key, type: String, desc: 'The new GPG key'
|
||||
end
|
||||
post ':id/gpg_keys' do
|
||||
authenticated_as_admin!
|
||||
|
||||
user = User.find_by(id: params.delete(:id))
|
||||
not_found!('User') unless user
|
||||
|
||||
key = user.gpg_keys.new(declared_params(include_missing: false))
|
||||
|
||||
if key.save
|
||||
present key, with: Entities::GPGKey
|
||||
else
|
||||
render_validation_error!(key)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Get the GPG keys of a specified user. Available only for admins.' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
success Entities::GPGKey
|
||||
end
|
||||
params do
|
||||
requires :id, type: Integer, desc: 'The ID of the user'
|
||||
use :pagination
|
||||
end
|
||||
get ':id/gpg_keys' do
|
||||
authenticated_as_admin!
|
||||
|
||||
user = User.find_by(id: params[:id])
|
||||
not_found!('User') unless user
|
||||
|
||||
present paginate(user.gpg_keys), with: Entities::GPGKey
|
||||
end
|
||||
|
||||
desc 'Delete an existing GPG key from a specified user. Available only for admins.' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
end
|
||||
params do
|
||||
requires :id, type: Integer, desc: 'The ID of the user'
|
||||
requires :key_id, type: Integer, desc: 'The ID of the GPG key'
|
||||
end
|
||||
delete ':id/gpg_keys/:key_id' do
|
||||
authenticated_as_admin!
|
||||
|
||||
user = User.find_by(id: params[:id])
|
||||
not_found!('User') unless user
|
||||
|
||||
key = user.gpg_keys.find_by(id: params[:key_id])
|
||||
not_found!('GPG Key') unless key
|
||||
|
||||
status 204
|
||||
key.destroy
|
||||
end
|
||||
|
||||
desc 'Revokes an existing GPG key from a specified user. Available only for admins.' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
end
|
||||
params do
|
||||
requires :id, type: Integer, desc: 'The ID of the user'
|
||||
requires :key_id, type: Integer, desc: 'The ID of the GPG key'
|
||||
end
|
||||
post ':id/gpg_keys/:key_id/revoke' do
|
||||
authenticated_as_admin!
|
||||
|
||||
user = User.find_by(id: params[:id])
|
||||
not_found!('User') unless user
|
||||
|
||||
key = user.gpg_keys.find_by(id: params[:key_id])
|
||||
not_found!('GPG Key') unless key
|
||||
|
||||
key.revoke
|
||||
status :accepted
|
||||
end
|
||||
|
||||
desc 'Add an email address to a specified user. Available only for admins.' do
|
||||
success Entities::Email
|
||||
end
|
||||
|
@ -492,6 +572,76 @@ module API
|
|||
destroy_conditionally!(key)
|
||||
end
|
||||
|
||||
desc "Get the currently authenticated user's GPG keys" do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
success Entities::GPGKey
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
end
|
||||
get 'gpg_keys' do
|
||||
present paginate(current_user.gpg_keys), with: Entities::GPGKey
|
||||
end
|
||||
|
||||
desc 'Get a single GPG key owned by currently authenticated user' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
success Entities::GPGKey
|
||||
end
|
||||
params do
|
||||
requires :key_id, type: Integer, desc: 'The ID of the GPG key'
|
||||
end
|
||||
get 'gpg_keys/:key_id' do
|
||||
key = current_user.gpg_keys.find_by(id: params[:key_id])
|
||||
not_found!('GPG Key') unless key
|
||||
|
||||
present key, with: Entities::GPGKey
|
||||
end
|
||||
|
||||
desc 'Add a new GPG key to the currently authenticated user' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
success Entities::GPGKey
|
||||
end
|
||||
params do
|
||||
requires :key, type: String, desc: 'The new GPG key'
|
||||
end
|
||||
post 'gpg_keys' do
|
||||
key = current_user.gpg_keys.new(declared_params)
|
||||
|
||||
if key.save
|
||||
present key, with: Entities::GPGKey
|
||||
else
|
||||
render_validation_error!(key)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Revoke a GPG key owned by currently authenticated user' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
end
|
||||
params do
|
||||
requires :key_id, type: Integer, desc: 'The ID of the GPG key'
|
||||
end
|
||||
post 'gpg_keys/:key_id/revoke' do
|
||||
key = current_user.gpg_keys.find_by(id: params[:key_id])
|
||||
not_found!('GPG Key') unless key
|
||||
|
||||
key.revoke
|
||||
status :accepted
|
||||
end
|
||||
|
||||
desc 'Delete a GPG key from the currently authenticated user' do
|
||||
detail 'This feature was added in GitLab 10.0'
|
||||
end
|
||||
params do
|
||||
requires :key_id, type: Integer, desc: 'The ID of the SSH key'
|
||||
end
|
||||
delete 'gpg_keys/:key_id' do
|
||||
key = current_user.gpg_keys.find_by(id: params[:key_id])
|
||||
not_found!('GPG Key') unless key
|
||||
|
||||
status 204
|
||||
key.destroy
|
||||
end
|
||||
|
||||
desc "Get the currently authenticated user's email addresses" do
|
||||
success Entities::Email
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ describe API::Users do
|
|||
let(:user) { create(:user) }
|
||||
let(:admin) { create(:admin) }
|
||||
let(:key) { create(:key, user: user) }
|
||||
let(:gpg_key) { create(:gpg_key, user: user) }
|
||||
let(:email) { create(:email, user: user) }
|
||||
let(:omniauth_user) { create(:omniauth_user) }
|
||||
let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') }
|
||||
|
@ -753,6 +754,164 @@ describe API::Users do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'POST /users/:id/keys' do
|
||||
before do
|
||||
admin
|
||||
end
|
||||
|
||||
it 'does not create invalid GPG key' do
|
||||
post api("/users/#{user.id}/gpg_keys", admin)
|
||||
|
||||
expect(response).to have_http_status(400)
|
||||
expect(json_response['error']).to eq('key is missing')
|
||||
end
|
||||
|
||||
it 'creates GPG key' do
|
||||
key_attrs = attributes_for :gpg_key
|
||||
expect do
|
||||
post api("/users/#{user.id}/gpg_keys", admin), key_attrs
|
||||
|
||||
expect(response).to have_http_status(201)
|
||||
end.to change { user.gpg_keys.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns 400 for invalid ID' do
|
||||
post api('/users/999999/gpg_keys', admin)
|
||||
|
||||
expect(response).to have_http_status(400)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /user/:id/gpg_keys' do
|
||||
before do
|
||||
admin
|
||||
end
|
||||
|
||||
context 'when unauthenticated' do
|
||||
it 'returns authentication error' do
|
||||
get api("/users/#{user.id}/gpg_keys")
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'returns 404 for non-existing user' do
|
||||
get api('/users/999999/gpg_keys', admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 User Not Found')
|
||||
end
|
||||
|
||||
it 'returns 404 error if key not foud' do
|
||||
delete api("/users/#{user.id}/gpg_keys/42", admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
|
||||
it 'returns array of GPG keys' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
get api("/users/#{user.id}/gpg_keys", admin)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.first['key']).to eq(gpg_key.key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /user/:id/gpg_keys/:key_id' do
|
||||
before do
|
||||
admin
|
||||
end
|
||||
|
||||
context 'when unauthenticated' do
|
||||
it 'returns authentication error' do
|
||||
delete api("/users/#{user.id}/keys/42")
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'deletes existing key' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
expect do
|
||||
delete api("/users/#{user.id}/gpg_keys/#{gpg_key.id}", admin)
|
||||
|
||||
expect(response).to have_http_status(204)
|
||||
end.to change { user.gpg_keys.count }.by(-1)
|
||||
end
|
||||
|
||||
it 'returns 404 error if user not found' do
|
||||
user.keys << key
|
||||
user.save
|
||||
|
||||
delete api("/users/999999/gpg_keys/#{gpg_key.id}", admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 User Not Found')
|
||||
end
|
||||
|
||||
it 'returns 404 error if key not foud' do
|
||||
delete api("/users/#{user.id}/gpg_keys/42", admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /user/:id/gpg_keys/:key_id/revoke' do
|
||||
before do
|
||||
admin
|
||||
end
|
||||
|
||||
context 'when unauthenticated' do
|
||||
it 'returns authentication error' do
|
||||
post api("/users/#{user.id}/gpg_keys/42/revoke")
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'revokes existing key' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
expect do
|
||||
post api("/users/#{user.id}/gpg_keys/#{gpg_key.id}/revoke", admin)
|
||||
|
||||
expect(response).to have_http_status(:accepted)
|
||||
end.to change { user.gpg_keys.count }.by(-1)
|
||||
end
|
||||
|
||||
it 'returns 404 error if user not found' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
post api("/users/999999/gpg_keys/#{gpg_key.id}/revoke", admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 User Not Found')
|
||||
end
|
||||
|
||||
it 'returns 404 error if key not foud' do
|
||||
post api("/users/#{user.id}/gpg_keys/42/revoke", admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /users/:id/emails" do
|
||||
before do
|
||||
admin
|
||||
|
@ -1153,6 +1312,173 @@ describe API::Users do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'GET /user/gpg_keys' do
|
||||
context 'when unauthenticated' do
|
||||
it 'returns authentication error' do
|
||||
get api('/user/gpg_keys')
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'returns array of GPG keys' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
get api('/user/gpg_keys', user)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.first['key']).to eq(gpg_key.key)
|
||||
end
|
||||
|
||||
context 'scopes' do
|
||||
let(:path) { '/user/gpg_keys' }
|
||||
let(:api_call) { method(:api) }
|
||||
|
||||
include_examples 'allows the "read_user" scope'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /user/gpg_keys/:key_id' do
|
||||
it 'returns a single key' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
get api("/user/gpg_keys/#{gpg_key.id}", user)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response['key']).to eq(gpg_key.key)
|
||||
end
|
||||
|
||||
it 'returns 404 Not Found within invalid ID' do
|
||||
get api('/user/gpg_keys/42', user)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
|
||||
it "returns 404 error if admin accesses user's GPG key" do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
get api("/user/gpg_keys/#{gpg_key.id}", admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
|
||||
it 'returns 404 for invalid ID' do
|
||||
get api('/users/gpg_keys/ASDF', admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
||||
context 'scopes' do
|
||||
let(:path) { "/user/gpg_keys/#{gpg_key.id}" }
|
||||
let(:api_call) { method(:api) }
|
||||
|
||||
include_examples 'allows the "read_user" scope'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /user/gpg_keys' do
|
||||
it 'creates a GPG key' do
|
||||
key_attrs = attributes_for :gpg_key
|
||||
expect do
|
||||
post api('/user/gpg_keys', user), key_attrs
|
||||
|
||||
expect(response).to have_http_status(201)
|
||||
end.to change { user.gpg_keys.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns a 401 error if unauthorized' do
|
||||
post api('/user/gpg_keys'), key: 'some key'
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
|
||||
it 'does not create GPG key without key' do
|
||||
post api('/user/gpg_keys', user)
|
||||
|
||||
expect(response).to have_http_status(400)
|
||||
expect(json_response['error']).to eq('key is missing')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /user/gpg_keys/:key_id/revoke' do
|
||||
it 'revokes existing GPG key' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
expect do
|
||||
post api("/user/gpg_keys/#{gpg_key.id}/revoke", user)
|
||||
|
||||
expect(response).to have_http_status(:accepted)
|
||||
end.to change { user.gpg_keys.count}.by(-1)
|
||||
end
|
||||
|
||||
it 'returns 404 if key ID not found' do
|
||||
post api('/user/gpg_keys/42/revoke', user)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
|
||||
it 'returns 401 error if unauthorized' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
post api("/user/gpg_keys/#{gpg_key.id}/revoke")
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
|
||||
it 'returns a 404 for invalid ID' do
|
||||
post api('/users/gpg_keys/ASDF/revoke', admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /user/gpg_keys/:key_id' do
|
||||
it 'deletes existing GPG key' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
expect do
|
||||
delete api("/user/gpg_keys/#{gpg_key.id}", user)
|
||||
|
||||
expect(response).to have_http_status(204)
|
||||
end.to change { user.gpg_keys.count}.by(-1)
|
||||
end
|
||||
|
||||
it 'returns 404 if key ID not found' do
|
||||
delete api('/user/gpg_keys/42', user)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(json_response['message']).to eq('404 GPG Key Not Found')
|
||||
end
|
||||
|
||||
it 'returns 401 error if unauthorized' do
|
||||
user.gpg_keys << gpg_key
|
||||
user.save
|
||||
|
||||
delete api("/user/gpg_keys/#{gpg_key.id}")
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
|
||||
it 'returns a 404 for invalid ID' do
|
||||
delete api('/users/gpg_keys/ASDF', admin)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /user/emails" do
|
||||
context "when unauthenticated" do
|
||||
it "returns authentication error" do
|
||||
|
|
Loading…
Reference in a new issue