Commit afee5303ff3a31d4b3eca82e19c7a326f2c86659
Exists in
master
and in
4 other branches
Merge pull request #3149 from m4tthumphrey/api-deploy-keys
Added methods to manage project deploy keys via API
Showing
3 changed files
with
179 additions
and
0 deletions
Show diff stats
doc/api/projects.md
... | ... | @@ -274,3 +274,82 @@ Parameters: |
274 | 274 | + `hook_id` (required) - The ID of hook to delete |
275 | 275 | |
276 | 276 | Will return status `200 OK` on success, or `404 Not found` on fail. |
277 | + | |
278 | + | |
279 | +## List deploy keys | |
280 | + | |
281 | +Get a list of a project's deploy keys. | |
282 | + | |
283 | +``` | |
284 | +GET /projects/:id/keys | |
285 | +``` | |
286 | + | |
287 | +```json | |
288 | +[ | |
289 | + { | |
290 | + "id": 1, | |
291 | + "title" : "Public key" | |
292 | + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
293 | + 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
294 | + soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", | |
295 | + }, | |
296 | + { | |
297 | + "id": 3, | |
298 | + "title" : "Another Public key" | |
299 | + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
300 | + 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
301 | + soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" | |
302 | + } | |
303 | +] | |
304 | +``` | |
305 | + | |
306 | +## Single deploy key | |
307 | + | |
308 | +Get a single key. | |
309 | + | |
310 | +``` | |
311 | +GET /projects/:id/keys/:key_id | |
312 | +``` | |
313 | + | |
314 | +Parameters: | |
315 | + | |
316 | ++ `id` (required) - The ID of an deploy key | |
317 | + | |
318 | +```json | |
319 | +{ | |
320 | + "id": 1, | |
321 | + "title" : "Public key" | |
322 | + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
323 | + 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
324 | + soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" | |
325 | +} | |
326 | +``` | |
327 | +## Add deploy key | |
328 | + | |
329 | +Create new deploy key for a project | |
330 | + | |
331 | +``` | |
332 | +POST /projects/:id/keys | |
333 | +``` | |
334 | + | |
335 | +Parameters: | |
336 | + | |
337 | ++ `title` (required) - new deploy key's title | |
338 | ++ `key` (required) - new deploy key | |
339 | + | |
340 | +Will return created key with status `201 Created` on success, or `404 Not | |
341 | +found` on fail. | |
342 | + | |
343 | +## Delete deploy key | |
344 | + | |
345 | +Delete a deploy key from a project | |
346 | + | |
347 | +``` | |
348 | +DELETE /projects/:id/keys/:key_id | |
349 | +``` | |
350 | + | |
351 | +Parameters: | |
352 | + | |
353 | ++ `id` (required) - Deploy key ID | |
354 | + | |
355 | +Will return `200 OK` on success, or `404 Not Found` on fail. | |
277 | 356 | \ No newline at end of file | ... | ... |
lib/api/projects.rb
... | ... | @@ -424,6 +424,49 @@ module Gitlab |
424 | 424 | present tree.data |
425 | 425 | end |
426 | 426 | |
427 | + # Get a specific project's keys | |
428 | + # | |
429 | + # Example Request: | |
430 | + # GET /projects/:id/keys | |
431 | + get ":id/keys" do | |
432 | + present user_project.deploy_keys, with: Entities::SSHKey | |
433 | + end | |
434 | + | |
435 | + # Get single key owned by currently authenticated user | |
436 | + # | |
437 | + # Example Request: | |
438 | + # GET /projects/:id/keys/:id | |
439 | + get ":id/keys/:key_id" do | |
440 | + key = user_project.deploy_keys.find params[:key_id] | |
441 | + present key, with: Entities::SSHKey | |
442 | + end | |
443 | + | |
444 | + # Add new ssh key to currently authenticated user | |
445 | + # | |
446 | + # Parameters: | |
447 | + # key (required) - New SSH Key | |
448 | + # title (required) - New SSH Key's title | |
449 | + # Example Request: | |
450 | + # POST /projects/:id/keys | |
451 | + post ":id/keys" do | |
452 | + attrs = attributes_for_keys [:title, :key] | |
453 | + key = user_project.deploy_keys.new attrs | |
454 | + if key.save | |
455 | + present key, with: Entities::SSHKey | |
456 | + else | |
457 | + not_found! | |
458 | + end | |
459 | + end | |
460 | + | |
461 | + # Delete existed ssh key of currently authenticated user | |
462 | + # | |
463 | + # Example Request: | |
464 | + # DELETE /projects/:id/keys/:id | |
465 | + delete ":id/keys/:key_id" do | |
466 | + key = user_project.deploy_keys.find params[:key_id] | |
467 | + key.delete | |
468 | + end | |
469 | + | |
427 | 470 | end |
428 | 471 | end |
429 | 472 | end | ... | ... |
spec/requests/api/projects_spec.rb
... | ... | @@ -11,6 +11,8 @@ describe Gitlab::API do |
11 | 11 | let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') } |
12 | 12 | let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } |
13 | 13 | let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } |
14 | + let(:key) { create(:key, project: project) } | |
15 | + | |
14 | 16 | before { project.team << [user, :reporter] } |
15 | 17 | |
16 | 18 | describe "GET /projects" do |
... | ... | @@ -380,4 +382,59 @@ describe Gitlab::API do |
380 | 382 | response.status.should == 404 |
381 | 383 | end |
382 | 384 | end |
385 | + | |
386 | + describe "GET /projects/:id/keys" do | |
387 | + it "should return array of ssh keys" do | |
388 | + project.deploy_keys << key | |
389 | + project.save | |
390 | + get api("/projects/#{project.id}/keys", user) | |
391 | + response.status.should == 200 | |
392 | + json_response.should be_an Array | |
393 | + json_response.first['title'].should == key.title | |
394 | + end | |
395 | + end | |
396 | + | |
397 | + describe "GET /projects/:id/keys/:key_id" do | |
398 | + it "should return a single key" do | |
399 | + project.deploy_keys << key | |
400 | + project.save | |
401 | + get api("/projects/#{project.id}/keys/#{key.id}", user) | |
402 | + response.status.should == 200 | |
403 | + json_response['title'].should == key.title | |
404 | + end | |
405 | + | |
406 | + it "should return 404 Not Found with invalid ID" do | |
407 | + get api("/projects/#{project.id}/keys/404", user) | |
408 | + response.status.should == 404 | |
409 | + end | |
410 | + end | |
411 | + | |
412 | + describe "POST /projects/:id/keys" do | |
413 | + it "should not create an invalid ssh key" do | |
414 | + post api("/projects/#{project.id}/keys", user), { title: "invalid key" } | |
415 | + response.status.should == 404 | |
416 | + end | |
417 | + | |
418 | + it "should create new ssh key" do | |
419 | + key_attrs = attributes_for :key | |
420 | + expect { | |
421 | + post api("/projects/#{project.id}/keys", user), key_attrs | |
422 | + }.to change{ project.deploy_keys.count }.by(1) | |
423 | + end | |
424 | + end | |
425 | + | |
426 | + describe "DELETE /projects/:id/keys/:key_id" do | |
427 | + it "should delete existing key" do | |
428 | + project.deploy_keys << key | |
429 | + project.save | |
430 | + expect { | |
431 | + delete api("/projects/#{project.id}/keys/#{key.id}", user) | |
432 | + }.to change{ project.deploy_keys.count }.by(-1) | |
433 | + end | |
434 | + | |
435 | + it "should return 404 Not Found with invalid ID" do | |
436 | + delete api("/projects/#{project.id}/keys/404", user) | |
437 | + response.status.should == 404 | |
438 | + end | |
439 | + end | |
383 | 440 | end | ... | ... |