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,3 +274,82 @@ Parameters: | ||
| 274 | + `hook_id` (required) - The ID of hook to delete | 274 | + `hook_id` (required) - The ID of hook to delete |
| 275 | 275 | ||
| 276 | Will return status `200 OK` on success, or `404 Not found` on fail. | 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 | \ No newline at end of file | 356 | \ No newline at end of file |
lib/api/projects.rb
| @@ -424,6 +424,49 @@ module Gitlab | @@ -424,6 +424,49 @@ module Gitlab | ||
| 424 | present tree.data | 424 | present tree.data |
| 425 | end | 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 | end | 470 | end |
| 428 | end | 471 | end |
| 429 | end | 472 | end |
spec/requests/api/projects_spec.rb
| @@ -11,6 +11,8 @@ describe Gitlab::API do | @@ -11,6 +11,8 @@ describe Gitlab::API do | ||
| 11 | let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') } | 11 | let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') } |
| 12 | let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } | 12 | let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } |
| 13 | let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } | 13 | let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } |
| 14 | + let(:key) { create(:key, project: project) } | ||
| 15 | + | ||
| 14 | before { project.team << [user, :reporter] } | 16 | before { project.team << [user, :reporter] } |
| 15 | 17 | ||
| 16 | describe "GET /projects" do | 18 | describe "GET /projects" do |
| @@ -380,4 +382,59 @@ describe Gitlab::API do | @@ -380,4 +382,59 @@ describe Gitlab::API do | ||
| 380 | response.status.should == 404 | 382 | response.status.should == 404 |
| 381 | end | 383 | end |
| 382 | end | 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 | end | 440 | end |