diff --git a/Gemfile.lock b/Gemfile.lock index 7682540eba0..155e03e5456 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -644,7 +644,7 @@ DEPENDENCIES simplecov sinatra six - slack-notifier (~> 0.2.0) + slack-notifier (~> 0.3.2) slim spinach-rails spring (= 1.1.1) @@ -662,4 +662,4 @@ DEPENDENCIES unicorn (~> 4.6.3) unicorn-worker-killer version_sorter - webmock \ No newline at end of file + webmock diff --git a/doc/api/users.md b/doc/api/users.md index 2d5dedb3a39..2b927c30777 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -220,6 +220,18 @@ Parameters: + **none** +## List SSH keys for user + +Get a list of a specified user's SSH keys. Available only for admin + +``` +GET /users/:uid/keys +``` + +Parameters: + ++ `uid` (required) - id of specified user + ## Single SSH key @@ -286,3 +298,18 @@ Parameters: + `id` (required) - SSH key ID +## Delete SSH key + +Deletes key owned by a specified user. Available only for admin. + +``` +DELETE /users/:uid/keys/:id +``` + +Parameters: + ++ `uid` (required) - id of specified user ++ `id` (required) - SSH key ID + +Will return `200 Ok` on success, or `404 Not found` if either user or key cannot be found. + diff --git a/lib/api/users.rb b/lib/api/users.rb index ae808b6272b..6ed2740c333 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -113,6 +113,45 @@ module API end end + # Get ssh keys of a specified user. Only available to admin users. + # + # Parameters: + # uid (required) - The ID of a user + # Example Request: + # GET /users/:uid/keys + get ':uid/keys' do + authenticated_as_admin! + user = User.find_by(id: params[:uid]) + if user + present user.keys, with: Entities::SSHKey + else + not_found! + end + end + + # Delete existing ssh key of a specified user. Only available to admin + # users. + # + # Parameters: + # uid (required) - The ID of a user + # id (required) - SSH Key ID + # Example Request: + # DELETE /users/:uid/keys/:id + delete ':uid/keys/:id' do + authenticated_as_admin! + user = User.find_by(id: params[:uid]) + if user + begin + key = user.keys.find params[:id] + key.destroy + rescue ActiveRecord::RecordNotFound + not_found! + end + else + not_found! + end + end + # Delete user. Available only for admin # # Example Request: diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 86610c47513..a6d300b099b 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -242,6 +242,67 @@ describe API::API, api: true do end end + describe 'GET /user/:uid/keys' do + before { admin } + + context 'when unauthenticated' do + it 'should return authentication error' do + get api("/users/#{user.id}/keys") + response.status.should == 401 + end + end + + context 'when authenticated' do + it 'should return 404 for non-existing user' do + get api('/users/999999/keys', admin) + response.status.should == 404 + end + + it 'should return array of ssh keys' do + user.keys << key + user.save + get api("/users/#{user.id}/keys", admin) + response.status.should == 200 + json_response.should be_an Array + json_response.first['title'].should == key.title + end + end + end + + describe 'DELETE /user/:uid/keys/:id' do + before { admin } + + context 'when unauthenticated' do + it 'should return authentication error' do + delete api("/users/#{user.id}/keys/42") + response.status.should == 401 + end + end + + context 'when authenticated' do + it 'should delete existing key' do + user.keys << key + user.save + expect { + delete api("/users/#{user.id}/keys/#{key.id}", admin) + }.to change { user.keys.count }.by(-1) + response.status.should == 200 + end + + it 'should return 404 error if user not found' do + user.keys << key + user.save + delete api("/users/999999/keys/#{key.id}", admin) + response.status.should == 404 + end + + it 'should return 404 error if key not foud' do + delete api("/users/#{user.id}/keys/42", admin) + response.status.should == 404 + end + end + end + describe "DELETE /users/:id" do before { admin }