Commit 05e792b4c492e04aaa7e301432f71e01d63c02bc
1 parent
cd623218
Exists in
spb-stable
and in
2 other branches
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./
Showing
4 changed files
with
129 additions
and
2 deletions
Show diff stats
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 | ... | ... |