Commit 05e792b4c492e04aaa7e301432f71e01d63c02bc

Authored by Timm Friebe
1 parent cd623218

Implement GET /users/:uid/keys for admin users

Complements POST operation added in gitlabhq/gitlabhq#3146

Implement DELETE /users/:uid/keys/:id for admin users

Fix "Line is too long. [83/80]"

Use single quotes as advised

Use single quotes as advised

Use single quotes as advised

Fix missing space around { and }

Fix typo in documentation

Only catch  ActiveRecord::RecordNotFound, let other exceptions propagate

Raise a "404 Not found" if key to be deleted cannot be found
As requested by @jvanbaarsen in https://github.com/gitlabhq/gitlabhq/pull/6781#discussion_r11735114

Remove tab
Unconfigured vim on this box, grrrr./
Gemfile.lock
... ... @@ -644,7 +644,7 @@ DEPENDENCIES
644 644 simplecov
645 645 sinatra
646 646 six
647   - slack-notifier (~> 0.2.0)
  647 + slack-notifier (~> 0.3.2)
648 648 slim
649 649 spinach-rails
650 650 spring (= 1.1.1)
... ... @@ -662,4 +662,4 @@ DEPENDENCIES
662 662 unicorn (~> 4.6.3)
663 663 unicorn-worker-killer
664 664 version_sorter
665   - webmock
666 665 \ No newline at end of file
  666 + webmock
... ...
doc/api/users.md
... ... @@ -220,6 +220,18 @@ Parameters:
220 220  
221 221 + **none**
222 222  
  223 +## List SSH keys for user
  224 +
  225 +Get a list of a specified user's SSH keys. Available only for admin
  226 +
  227 +```
  228 +GET /users/:uid/keys
  229 +```
  230 +
  231 +Parameters:
  232 +
  233 ++ `uid` (required) - id of specified user
  234 +
223 235  
224 236 ## Single SSH key
225 237  
... ... @@ -286,3 +298,18 @@ Parameters:
286 298  
287 299 + `id` (required) - SSH key ID
288 300  
  301 +## Delete SSH key
  302 +
  303 +Deletes key owned by a specified user. Available only for admin.
  304 +
  305 +```
  306 +DELETE /users/:uid/keys/:id
  307 +```
  308 +
  309 +Parameters:
  310 +
  311 ++ `uid` (required) - id of specified user
  312 ++ `id` (required) - SSH key ID
  313 +
  314 +Will return `200 Ok` on success, or `404 Not found` if either user or key cannot be found.
  315 +
... ...
lib/api/users.rb
... ... @@ -113,6 +113,45 @@ module API
113 113 end
114 114 end
115 115  
  116 + # Get ssh keys of a specified user. Only available to admin users.
  117 + #
  118 + # Parameters:
  119 + # uid (required) - The ID of a user
  120 + # Example Request:
  121 + # GET /users/:uid/keys
  122 + get ':uid/keys' do
  123 + authenticated_as_admin!
  124 + user = User.find_by(id: params[:uid])
  125 + if user
  126 + present user.keys, with: Entities::SSHKey
  127 + else
  128 + not_found!
  129 + end
  130 + end
  131 +
  132 + # Delete existing ssh key of a specified user. Only available to admin
  133 + # users.
  134 + #
  135 + # Parameters:
  136 + # uid (required) - The ID of a user
  137 + # id (required) - SSH Key ID
  138 + # Example Request:
  139 + # DELETE /users/:uid/keys/:id
  140 + delete ':uid/keys/:id' do
  141 + authenticated_as_admin!
  142 + user = User.find_by(id: params[:uid])
  143 + if user
  144 + begin
  145 + key = user.keys.find params[:id]
  146 + key.destroy
  147 + rescue ActiveRecord::RecordNotFound
  148 + not_found!
  149 + end
  150 + else
  151 + not_found!
  152 + end
  153 + end
  154 +
116 155 # Delete user. Available only for admin
117 156 #
118 157 # Example Request:
... ...
spec/requests/api/users_spec.rb
... ... @@ -242,6 +242,67 @@ describe API::API, api: true do
242 242 end
243 243 end
244 244  
  245 + describe 'GET /user/:uid/keys' do
  246 + before { admin }
  247 +
  248 + context 'when unauthenticated' do
  249 + it 'should return authentication error' do
  250 + get api("/users/#{user.id}/keys")
  251 + response.status.should == 401
  252 + end
  253 + end
  254 +
  255 + context 'when authenticated' do
  256 + it 'should return 404 for non-existing user' do
  257 + get api('/users/999999/keys', admin)
  258 + response.status.should == 404
  259 + end
  260 +
  261 + it 'should return array of ssh keys' do
  262 + user.keys << key
  263 + user.save
  264 + get api("/users/#{user.id}/keys", admin)
  265 + response.status.should == 200
  266 + json_response.should be_an Array
  267 + json_response.first['title'].should == key.title
  268 + end
  269 + end
  270 + end
  271 +
  272 + describe 'DELETE /user/:uid/keys/:id' do
  273 + before { admin }
  274 +
  275 + context 'when unauthenticated' do
  276 + it 'should return authentication error' do
  277 + delete api("/users/#{user.id}/keys/42")
  278 + response.status.should == 401
  279 + end
  280 + end
  281 +
  282 + context 'when authenticated' do
  283 + it 'should delete existing key' do
  284 + user.keys << key
  285 + user.save
  286 + expect {
  287 + delete api("/users/#{user.id}/keys/#{key.id}", admin)
  288 + }.to change { user.keys.count }.by(-1)
  289 + response.status.should == 200
  290 + end
  291 +
  292 + it 'should return 404 error if user not found' do
  293 + user.keys << key
  294 + user.save
  295 + delete api("/users/999999/keys/#{key.id}", admin)
  296 + response.status.should == 404
  297 + end
  298 +
  299 + it 'should return 404 error if key not foud' do
  300 + delete api("/users/#{user.id}/keys/42", admin)
  301 + response.status.should == 404
  302 + end
  303 + end
  304 + end
  305 +
245 306 describe "DELETE /users/:id" do
246 307 before { admin }
247 308  
... ...