diff options
author | Robert Schilling <rschilling@student.tugraz.at> | 2017-08-25 12:24:41 +0200 |
---|---|---|
committer | Robert Schilling <rschilling@student.tugraz.at> | 2017-09-05 14:30:53 +0200 |
commit | 97371848c5fccb7ba066cc0c50c0d3ed15ec5971 (patch) | |
tree | 8eae9edab6f63bbab50ae72b71fe91b3a99e5f33 | |
parent | b69579742b5379760ccc868d359a9b6d1d225861 (diff) | |
download | gitlab-ce-97371848c5fccb7ba066cc0c50c0d3ed15ec5971.tar.gz |
API: Add GPG key management for admins
-rw-r--r-- | lib/api/users.rb | 80 | ||||
-rw-r--r-- | spec/requests/api/users_spec.rb | 158 |
2 files changed, 238 insertions, 0 deletions
diff --git a/lib/api/users.rb b/lib/api/users.rb index 82991dc9d16..1825c90a23b 100644 --- a/lib/api/users.rb +++ b/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 diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index c86a99eb6eb..37cb95a16e3 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -754,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 |