Commit afee5303ff3a31d4b3eca82e19c7a326f2c86659

Authored by Dmitriy Zaporozhets
2 parents 65d78253 f411772e

Merge pull request #3149 from m4tthumphrey/api-deploy-keys

Added methods to manage project deploy keys via API
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
... ...