Commit b62445813dffec92e85540ed081e4d6e12d58dc0
1 parent
4a072be2
Exists in
master
and in
4 other branches
API: SSH keys belong to user entity
Showing
8 changed files
with
195 additions
and
212 deletions
Show diff stats
doc/api/keys.md
| ... | ... | @@ -1,79 +0,0 @@ |
| 1 | -## List keys | |
| 2 | - | |
| 3 | -Get a list of currently authenticated user's keys. | |
| 4 | - | |
| 5 | -``` | |
| 6 | -GET /keys | |
| 7 | -``` | |
| 8 | - | |
| 9 | -```json | |
| 10 | -[ | |
| 11 | - { | |
| 12 | - "id": 1, | |
| 13 | - "title" : "Public key" | |
| 14 | - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
| 15 | - 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
| 16 | - soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", | |
| 17 | - }, | |
| 18 | - { | |
| 19 | - "id": 3, | |
| 20 | - "title" : "Another Public key" | |
| 21 | - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
| 22 | - 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
| 23 | - soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" | |
| 24 | - } | |
| 25 | -] | |
| 26 | -``` | |
| 27 | - | |
| 28 | -## Single key | |
| 29 | - | |
| 30 | -Get a single key. | |
| 31 | - | |
| 32 | -``` | |
| 33 | -GET /keys/:id | |
| 34 | -``` | |
| 35 | - | |
| 36 | -Parameters: | |
| 37 | - | |
| 38 | -+ `id` (required) - The ID of a key | |
| 39 | - | |
| 40 | -```json | |
| 41 | -{ | |
| 42 | - "id": 1, | |
| 43 | - "title" : "Public key" | |
| 44 | - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
| 45 | - 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
| 46 | - soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" | |
| 47 | -} | |
| 48 | -``` | |
| 49 | -## Add key | |
| 50 | - | |
| 51 | -Create new key owned by currently authenticated user | |
| 52 | - | |
| 53 | -``` | |
| 54 | -POST /keys | |
| 55 | -``` | |
| 56 | - | |
| 57 | -Parameters: | |
| 58 | - | |
| 59 | -+ `title` (required) - new SSH Key's title | |
| 60 | -+ `key` (required) - new SSH key | |
| 61 | - | |
| 62 | -Will return created key with status `201 Created` on success, or `404 Not | |
| 63 | -found` on fail. | |
| 64 | - | |
| 65 | -## Delete key | |
| 66 | - | |
| 67 | -Delete key owned by currently authenticated user | |
| 68 | - | |
| 69 | -``` | |
| 70 | -DELETE /keys/:id | |
| 71 | -``` | |
| 72 | - | |
| 73 | -Parameters: | |
| 74 | - | |
| 75 | -+ `id` (required) - key ID | |
| 76 | - | |
| 77 | -Will return `200 OK` on success, or `404 Not Found` on fail. | |
| 78 | - | |
| 79 | - |
doc/api/users.md
| ... | ... | @@ -88,3 +88,81 @@ GET /user |
| 88 | 88 | "theme_id": 1 |
| 89 | 89 | } |
| 90 | 90 | ``` |
| 91 | + | |
| 92 | +## List SSH keys | |
| 93 | + | |
| 94 | +Get a list of currently authenticated user's SSH keys. | |
| 95 | + | |
| 96 | +``` | |
| 97 | +GET /user/keys | |
| 98 | +``` | |
| 99 | + | |
| 100 | +```json | |
| 101 | +[ | |
| 102 | + { | |
| 103 | + "id": 1, | |
| 104 | + "title" : "Public key" | |
| 105 | + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
| 106 | + 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
| 107 | + soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", | |
| 108 | + }, | |
| 109 | + { | |
| 110 | + "id": 3, | |
| 111 | + "title" : "Another Public key" | |
| 112 | + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
| 113 | + 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
| 114 | + soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" | |
| 115 | + } | |
| 116 | +] | |
| 117 | +``` | |
| 118 | + | |
| 119 | +## Single SSH key | |
| 120 | + | |
| 121 | +Get a single key. | |
| 122 | + | |
| 123 | +``` | |
| 124 | +GET /user/keys/:id | |
| 125 | +``` | |
| 126 | + | |
| 127 | +Parameters: | |
| 128 | + | |
| 129 | ++ `id` (required) - The ID of an SSH key | |
| 130 | + | |
| 131 | +```json | |
| 132 | +{ | |
| 133 | + "id": 1, | |
| 134 | + "title" : "Public key" | |
| 135 | + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 | |
| 136 | + 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 | |
| 137 | + soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" | |
| 138 | +} | |
| 139 | +``` | |
| 140 | +## Add SSH key | |
| 141 | + | |
| 142 | +Create new key owned by currently authenticated user | |
| 143 | + | |
| 144 | +``` | |
| 145 | +POST /user/keys | |
| 146 | +``` | |
| 147 | + | |
| 148 | +Parameters: | |
| 149 | + | |
| 150 | ++ `title` (required) - new SSH Key's title | |
| 151 | ++ `key` (required) - new SSH key | |
| 152 | + | |
| 153 | +Will return created key with status `201 Created` on success, or `404 Not | |
| 154 | +found` on fail. | |
| 155 | + | |
| 156 | +## Delete SSH key | |
| 157 | + | |
| 158 | +Delete key owned by currently authenticated user | |
| 159 | + | |
| 160 | +``` | |
| 161 | +DELETE /user/keys/:id | |
| 162 | +``` | |
| 163 | + | |
| 164 | +Parameters: | |
| 165 | + | |
| 166 | ++ `id` (required) - SSH key ID | |
| 167 | + | |
| 168 | +Will return `200 OK` on success, or `404 Not Found` on fail. | ... | ... |
lib/api.rb
lib/api/entities.rb
lib/api/keys.rb
| ... | ... | @@ -1,50 +0,0 @@ |
| 1 | -module Gitlab | |
| 2 | - # Keys API | |
| 3 | - class Keys < Grape::API | |
| 4 | - before { authenticate! } | |
| 5 | - resource :keys do | |
| 6 | - # Get currently authenticated user's keys | |
| 7 | - # | |
| 8 | - # Example Request: | |
| 9 | - # GET /keys | |
| 10 | - get do | |
| 11 | - present current_user.keys, with: Entities::Key | |
| 12 | - end | |
| 13 | - # Get single key owned by currently authenticated user | |
| 14 | - # | |
| 15 | - # Example Request: | |
| 16 | - # GET /keys/:id | |
| 17 | - get "/:id" do | |
| 18 | - key = current_user.keys.find params[:id] | |
| 19 | - present key, with: Entities::Key | |
| 20 | - end | |
| 21 | - # Add new ssh key to currently authenticated user | |
| 22 | - # | |
| 23 | - # Parameters: | |
| 24 | - # key (required) - New SSH Key | |
| 25 | - # title (required) - New SSH Key's title | |
| 26 | - # Example Request: | |
| 27 | - # POST /keys | |
| 28 | - post do | |
| 29 | - attrs = attributes_for_keys [:title, :key] | |
| 30 | - key = current_user.keys.new attrs | |
| 31 | - if key.save | |
| 32 | - present key, with: Entities::Key | |
| 33 | - else | |
| 34 | - not_found! | |
| 35 | - end | |
| 36 | - end | |
| 37 | - # Delete existed ssh key of currently authenticated user | |
| 38 | - # | |
| 39 | - # Parameters: | |
| 40 | - # id (required) - SSH Key ID | |
| 41 | - # Example Request: | |
| 42 | - # DELETE /keys/:id | |
| 43 | - delete "/:id" do | |
| 44 | - key = current_user.keys.find params[:id] | |
| 45 | - key.delete | |
| 46 | - end | |
| 47 | - end | |
| 48 | - end | |
| 49 | -end | |
| 50 | - |
lib/api/users.rb
| ... | ... | @@ -25,12 +25,59 @@ module Gitlab |
| 25 | 25 | end |
| 26 | 26 | end |
| 27 | 27 | |
| 28 | - # Get currently authenticated user | |
| 29 | - # | |
| 30 | - # Example Request: | |
| 31 | - # GET /user | |
| 32 | - get "/user" do | |
| 33 | - present @current_user, with: Entities::User | |
| 28 | + resource :user do | |
| 29 | + # Get currently authenticated user | |
| 30 | + # | |
| 31 | + # Example Request: | |
| 32 | + # GET /user | |
| 33 | + get do | |
| 34 | + present @current_user, with: Entities::User | |
| 35 | + end | |
| 36 | + | |
| 37 | + # Get currently authenticated user's keys | |
| 38 | + # | |
| 39 | + # Example Request: | |
| 40 | + # GET /user/keys | |
| 41 | + get "keys" do | |
| 42 | + present current_user.keys, with: Entities::SSHKey | |
| 43 | + end | |
| 44 | + | |
| 45 | + # Get single key owned by currently authenticated user | |
| 46 | + # | |
| 47 | + # Example Request: | |
| 48 | + # GET /user/keys/:id | |
| 49 | + get "keys/:id" do | |
| 50 | + key = current_user.keys.find params[:id] | |
| 51 | + present key, with: Entities::SSHKey | |
| 52 | + end | |
| 53 | + | |
| 54 | + # Add new ssh key to currently authenticated user | |
| 55 | + # | |
| 56 | + # Parameters: | |
| 57 | + # key (required) - New SSH Key | |
| 58 | + # title (required) - New SSH Key's title | |
| 59 | + # Example Request: | |
| 60 | + # POST /user/keys | |
| 61 | + post "keys" do | |
| 62 | + attrs = attributes_for_keys [:title, :key] | |
| 63 | + key = current_user.keys.new attrs | |
| 64 | + if key.save | |
| 65 | + present key, with: Entities::SSHKey | |
| 66 | + else | |
| 67 | + not_found! | |
| 68 | + end | |
| 69 | + end | |
| 70 | + | |
| 71 | + # Delete existed ssh key of currently authenticated user | |
| 72 | + # | |
| 73 | + # Parameters: | |
| 74 | + # id (required) - SSH Key ID | |
| 75 | + # Example Request: | |
| 76 | + # DELETE /user/keys/:id | |
| 77 | + delete "keys/:id" do | |
| 78 | + key = current_user.keys.find params[:id] | |
| 79 | + key.delete | |
| 80 | + end | |
| 34 | 81 | end |
| 35 | 82 | end |
| 36 | 83 | end | ... | ... |
spec/requests/api/ssh_keys_spec.rb
| ... | ... | @@ -1,73 +0,0 @@ |
| 1 | -require 'spec_helper' | |
| 2 | - | |
| 3 | -describe Gitlab::Keys do | |
| 4 | - include ApiHelpers | |
| 5 | - let(:user) { | |
| 6 | - user = Factory.create :user | |
| 7 | - user.reset_authentication_token! | |
| 8 | - user | |
| 9 | - } | |
| 10 | - let(:key) { Factory.create :key, { user: user}} | |
| 11 | - | |
| 12 | - describe "GET /keys" do | |
| 13 | - context "when unauthenticated" do | |
| 14 | - it "should return authentication error" do | |
| 15 | - get api("/keys") | |
| 16 | - response.status.should == 401 | |
| 17 | - end | |
| 18 | - end | |
| 19 | - context "when authenticated" do | |
| 20 | - it "should return array of ssh keys" do | |
| 21 | - user.keys << key | |
| 22 | - user.save | |
| 23 | - get api("/keys", user) | |
| 24 | - response.status.should == 200 | |
| 25 | - json_response.should be_an Array | |
| 26 | - json_response.first["title"].should == key.title | |
| 27 | - end | |
| 28 | - end | |
| 29 | - end | |
| 30 | - | |
| 31 | - describe "GET /keys/:id" do | |
| 32 | - it "should returm single key" do | |
| 33 | - user.keys << key | |
| 34 | - user.save | |
| 35 | - get api("/keys/#{key.id}", user) | |
| 36 | - response.status.should == 200 | |
| 37 | - json_response["title"].should == key.title | |
| 38 | - end | |
| 39 | - it "should return 404 Not Found within invalid ID" do | |
| 40 | - get api("/keys/42", user) | |
| 41 | - response.status.should == 404 | |
| 42 | - end | |
| 43 | - end | |
| 44 | - | |
| 45 | - describe "POST /keys" do | |
| 46 | - it "should not create invalid ssh key" do | |
| 47 | - post api("/keys", user), { title: "invalid key" } | |
| 48 | - response.status.should == 404 | |
| 49 | - end | |
| 50 | - it "should create ssh key" do | |
| 51 | - key_attrs = Factory.attributes :key | |
| 52 | - expect { | |
| 53 | - post api("/keys", user), key_attrs | |
| 54 | - }.to change{ user.keys.count }.by(1) | |
| 55 | - end | |
| 56 | - end | |
| 57 | - | |
| 58 | - describe "DELETE /keys/:id" do | |
| 59 | - it "should delete existed key" do | |
| 60 | - user.keys << key | |
| 61 | - user.save | |
| 62 | - expect { | |
| 63 | - delete api("/keys/#{key.id}", user) | |
| 64 | - }.to change{user.keys.count}.by(-1) | |
| 65 | - end | |
| 66 | - it "should return 404 Not Found within invalid ID" do | |
| 67 | - delete api("/keys/42", user) | |
| 68 | - response.status.should == 404 | |
| 69 | - end | |
| 70 | - end | |
| 71 | - | |
| 72 | -end | |
| 73 | - |
spec/requests/api/users_spec.rb
| ... | ... | @@ -3,7 +3,8 @@ require 'spec_helper' |
| 3 | 3 | describe Gitlab::API do |
| 4 | 4 | include ApiHelpers |
| 5 | 5 | |
| 6 | - let(:user) { Factory :user } | |
| 6 | + let(:user) { Factory :user } | |
| 7 | + let(:key) { Factory :key, user: user } | |
| 7 | 8 | |
| 8 | 9 | describe "GET /users" do |
| 9 | 10 | context "when unauthenticated" do |
| ... | ... | @@ -38,4 +39,64 @@ describe Gitlab::API do |
| 38 | 39 | json_response['email'].should == user.email |
| 39 | 40 | end |
| 40 | 41 | end |
| 42 | + | |
| 43 | + describe "GET /user/keys" do | |
| 44 | + context "when unauthenticated" do | |
| 45 | + it "should return authentication error" do | |
| 46 | + get api("/user/keys") | |
| 47 | + response.status.should == 401 | |
| 48 | + end | |
| 49 | + end | |
| 50 | + context "when authenticated" do | |
| 51 | + it "should return array of ssh keys" do | |
| 52 | + user.keys << key | |
| 53 | + user.save | |
| 54 | + get api("/user/keys", user) | |
| 55 | + response.status.should == 200 | |
| 56 | + json_response.should be_an Array | |
| 57 | + json_response.first["title"].should == key.title | |
| 58 | + end | |
| 59 | + end | |
| 60 | + end | |
| 61 | + | |
| 62 | + describe "GET /user/keys/:id" do | |
| 63 | + it "should returm single key" do | |
| 64 | + user.keys << key | |
| 65 | + user.save | |
| 66 | + get api("/user/keys/#{key.id}", user) | |
| 67 | + response.status.should == 200 | |
| 68 | + json_response["title"].should == key.title | |
| 69 | + end | |
| 70 | + it "should return 404 Not Found within invalid ID" do | |
| 71 | + get api("/user/keys/42", user) | |
| 72 | + response.status.should == 404 | |
| 73 | + end | |
| 74 | + end | |
| 75 | + | |
| 76 | + describe "POST /user/keys" do | |
| 77 | + it "should not create invalid ssh key" do | |
| 78 | + post api("/user/keys", user), { title: "invalid key" } | |
| 79 | + response.status.should == 404 | |
| 80 | + end | |
| 81 | + it "should create ssh key" do | |
| 82 | + key_attrs = Factory.attributes :key | |
| 83 | + expect { | |
| 84 | + post api("/user/keys", user), key_attrs | |
| 85 | + }.to change{ user.keys.count }.by(1) | |
| 86 | + end | |
| 87 | + end | |
| 88 | + | |
| 89 | + describe "DELETE /user/keys/:id" do | |
| 90 | + it "should delete existed key" do | |
| 91 | + user.keys << key | |
| 92 | + user.save | |
| 93 | + expect { | |
| 94 | + delete api("/user/keys/#{key.id}", user) | |
| 95 | + }.to change{user.keys.count}.by(-1) | |
| 96 | + end | |
| 97 | + it "should return 404 Not Found within invalid ID" do | |
| 98 | + delete api("/user/keys/42", user) | |
| 99 | + response.status.should == 404 | |
| 100 | + end | |
| 101 | + end | |
| 41 | 102 | end | ... | ... |