Commit e954438a1d3a45addebf52ab04155459d7d84db0
1 parent
f4a6f1fd
Exists in
master
and in
4 other branches
Extended users API to support updating and deleting users.
Also added tests.
Showing
4 changed files
with
138 additions
and
2 deletions
Show diff stats
doc/api/users.md
| @@ -20,6 +20,8 @@ GET /users | @@ -20,6 +20,8 @@ GET /users | ||
| 20 | "linkedin": "", | 20 | "linkedin": "", |
| 21 | "twitter": "", | 21 | "twitter": "", |
| 22 | "dark_scheme": false, | 22 | "dark_scheme": false, |
| 23 | + "extern_uid": "john.smith", | ||
| 24 | + "provider": "provider_name", | ||
| 23 | "theme_id": 1 | 25 | "theme_id": 1 |
| 24 | }, | 26 | }, |
| 25 | { | 27 | { |
| @@ -34,6 +36,8 @@ GET /users | @@ -34,6 +36,8 @@ GET /users | ||
| 34 | "linkedin": "", | 36 | "linkedin": "", |
| 35 | "twitter": "", | 37 | "twitter": "", |
| 36 | "dark_scheme": true, | 38 | "dark_scheme": true, |
| 39 | + "extern_uid": "jack.smith", | ||
| 40 | + "provider": "provider_name", | ||
| 37 | "theme_id": 1 | 41 | "theme_id": 1 |
| 38 | } | 42 | } |
| 39 | ] | 43 | ] |
| @@ -64,6 +68,8 @@ Parameters: | @@ -64,6 +68,8 @@ Parameters: | ||
| 64 | "linkedin": "", | 68 | "linkedin": "", |
| 65 | "twitter": "", | 69 | "twitter": "", |
| 66 | "dark_scheme": false, | 70 | "dark_scheme": false, |
| 71 | + "extern_uid": "john.smith", | ||
| 72 | + "provider": "provider_name", | ||
| 67 | "theme_id": 1 | 73 | "theme_id": 1 |
| 68 | } | 74 | } |
| 69 | ``` | 75 | ``` |
| @@ -84,10 +90,47 @@ Parameters: | @@ -84,10 +90,47 @@ Parameters: | ||
| 84 | + `linkedin` - Linkedin | 90 | + `linkedin` - Linkedin |
| 85 | + `twitter` - Twitter account | 91 | + `twitter` - Twitter account |
| 86 | + `projects_limit` - Number of projects user can create | 92 | + `projects_limit` - Number of projects user can create |
| 93 | ++ `extern_uid` - External UID | ||
| 94 | ++ `provider` - External provider name | ||
| 95 | ++ `bio` - User's bio | ||
| 87 | 96 | ||
| 88 | Will return created user with status `201 Created` on success, or `404 Not | 97 | Will return created user with status `201 Created` on success, or `404 Not |
| 89 | found` on fail. | 98 | found` on fail. |
| 90 | 99 | ||
| 100 | +## User modification | ||
| 101 | +Modify user. Available only for admin | ||
| 102 | + | ||
| 103 | +``` | ||
| 104 | +PUT /users/:id | ||
| 105 | +``` | ||
| 106 | + | ||
| 107 | +Parameters: | ||
| 108 | ++ `email` - Email | ||
| 109 | ++ `username` - Username | ||
| 110 | ++ `name` - Name | ||
| 111 | ++ `password` - Password | ||
| 112 | ++ `skype` - Skype ID | ||
| 113 | ++ `linkedin` - Linkedin | ||
| 114 | ++ `twitter` - Twitter account | ||
| 115 | ++ `projects_limit` - Limit projects wich user can create | ||
| 116 | ++ `extern_uid` - External UID | ||
| 117 | ++ `provider` - External provider name | ||
| 118 | ++ `bio` - User's bio | ||
| 119 | + | ||
| 120 | + | ||
| 121 | +Will return created user with status `200 OK` on success, or `404 Not | ||
| 122 | +found` on fail. | ||
| 123 | + | ||
| 124 | +## User deletion | ||
| 125 | +Delete user. Available only for admin | ||
| 126 | + | ||
| 127 | +``` | ||
| 128 | +DELETE /users/:id | ||
| 129 | +``` | ||
| 130 | + | ||
| 131 | +Will return deleted user with status `200 OK` on success, or `404 Not | ||
| 132 | +found` on fail. | ||
| 133 | + | ||
| 91 | ## Current user | 134 | ## Current user |
| 92 | 135 | ||
| 93 | Get currently authenticated user. | 136 | Get currently authenticated user. |
lib/api/entities.rb
| @@ -2,7 +2,7 @@ module Gitlab | @@ -2,7 +2,7 @@ module Gitlab | ||
| 2 | module Entities | 2 | module Entities |
| 3 | class User < Grape::Entity | 3 | class User < Grape::Entity |
| 4 | expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, | 4 | expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, |
| 5 | - :dark_scheme, :theme_id, :blocked, :created_at | 5 | + :dark_scheme, :theme_id, :blocked, :created_at, :extern_uid, :provider |
| 6 | end | 6 | end |
| 7 | 7 | ||
| 8 | class UserBasic < Grape::Entity | 8 | class UserBasic < Grape::Entity |
lib/api/users.rb
| @@ -34,11 +34,14 @@ module Gitlab | @@ -34,11 +34,14 @@ module Gitlab | ||
| 34 | # linkedin - Linkedin | 34 | # linkedin - Linkedin |
| 35 | # twitter - Twitter account | 35 | # twitter - Twitter account |
| 36 | # projects_limit - Number of projects user can create | 36 | # projects_limit - Number of projects user can create |
| 37 | + # extern_uid - External authentication provider UID | ||
| 38 | + # provider - External provider | ||
| 39 | + # bio - Bio | ||
| 37 | # Example Request: | 40 | # Example Request: |
| 38 | # POST /users | 41 | # POST /users |
| 39 | post do | 42 | post do |
| 40 | authenticated_as_admin! | 43 | authenticated_as_admin! |
| 41 | - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username] | 44 | + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio] |
| 42 | user = User.new attrs, as: :admin | 45 | user = User.new attrs, as: :admin |
| 43 | if user.save | 46 | if user.save |
| 44 | present user, with: Entities::User | 47 | present user, with: Entities::User |
| @@ -46,6 +49,48 @@ module Gitlab | @@ -46,6 +49,48 @@ module Gitlab | ||
| 46 | not_found! | 49 | not_found! |
| 47 | end | 50 | end |
| 48 | end | 51 | end |
| 52 | + | ||
| 53 | + # Update user. Available only for admin | ||
| 54 | + # | ||
| 55 | + # Parameters: | ||
| 56 | + # email - Email | ||
| 57 | + # name - Name | ||
| 58 | + # password - Password | ||
| 59 | + # skype - Skype ID | ||
| 60 | + # linkedin - Linkedin | ||
| 61 | + # twitter - Twitter account | ||
| 62 | + # projects_limit - Limit projects wich user can create | ||
| 63 | + # extern_uid - External authentication provider UID | ||
| 64 | + # provider - External provider | ||
| 65 | + # bio - Bio | ||
| 66 | + # Example Request: | ||
| 67 | + # PUT /users/:id | ||
| 68 | + put ":id" do | ||
| 69 | + authenticated_as_admin! | ||
| 70 | + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio] | ||
| 71 | + user = User.find_by_id(params[:id]) | ||
| 72 | + | ||
| 73 | + if user && user.update_attributes(attrs) | ||
| 74 | + present user, with: Entities::User | ||
| 75 | + else | ||
| 76 | + not_found! | ||
| 77 | + end | ||
| 78 | + end | ||
| 79 | + | ||
| 80 | + # Delete user. Available only for admin | ||
| 81 | + # | ||
| 82 | + # Example Request: | ||
| 83 | + # DELETE /users/:id | ||
| 84 | + delete ":id" do | ||
| 85 | + authenticated_as_admin! | ||
| 86 | + user = User.find_by_id(params[:id]) | ||
| 87 | + | ||
| 88 | + if user | ||
| 89 | + user.destroy | ||
| 90 | + else | ||
| 91 | + not_found! | ||
| 92 | + end | ||
| 93 | + end | ||
| 49 | end | 94 | end |
| 50 | 95 | ||
| 51 | resource :user do | 96 | resource :user do |
spec/requests/api/users_spec.rb
| @@ -53,6 +53,54 @@ describe Gitlab::API do | @@ -53,6 +53,54 @@ describe Gitlab::API do | ||
| 53 | end | 53 | end |
| 54 | end | 54 | end |
| 55 | 55 | ||
| 56 | + describe "PUT /users/:id" do | ||
| 57 | + before { admin } | ||
| 58 | + | ||
| 59 | + it "should update user" do | ||
| 60 | + put api("/users/#{user.id}", admin), {bio: 'new test bio'} | ||
| 61 | + response.status.should == 200 | ||
| 62 | + json_response['bio'].should == 'new test bio' | ||
| 63 | + user.reload.bio.should == 'new test bio' | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + it "should not allow invalid update" do | ||
| 67 | + put api("/users/#{user.id}", admin), {email: 'invalid email'} | ||
| 68 | + response.status.should == 404 | ||
| 69 | + user.reload.email.should_not == 'invalid email' | ||
| 70 | + end | ||
| 71 | + | ||
| 72 | + it "shouldn't available for non admin users" do | ||
| 73 | + put api("/users/#{user.id}", user), attributes_for(:user) | ||
| 74 | + response.status.should == 403 | ||
| 75 | + end | ||
| 76 | + | ||
| 77 | + it "should return 404 for non-existing user" do | ||
| 78 | + put api("/users/999999", admin), {bio: 'update should fail'} | ||
| 79 | + response.status.should == 404 | ||
| 80 | + end | ||
| 81 | + end | ||
| 82 | + | ||
| 83 | + describe "DELETE /users/:id" do | ||
| 84 | + before { admin } | ||
| 85 | + | ||
| 86 | + it "should delete user" do | ||
| 87 | + delete api("/users/#{user.id}", admin) | ||
| 88 | + response.status.should == 200 | ||
| 89 | + expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound | ||
| 90 | + json_response['email'].should == user.email | ||
| 91 | + end | ||
| 92 | + | ||
| 93 | + it "shouldn't available for non admin users" do | ||
| 94 | + delete api("/users/#{user.id}", user) | ||
| 95 | + response.status.should == 403 | ||
| 96 | + end | ||
| 97 | + | ||
| 98 | + it "should return 404 for non-existing user" do | ||
| 99 | + delete api("/users/999999", admin) | ||
| 100 | + response.status.should == 404 | ||
| 101 | + end | ||
| 102 | + end | ||
| 103 | + | ||
| 56 | describe "GET /user" do | 104 | describe "GET /user" do |
| 57 | it "should return current user" do | 105 | it "should return current user" do |
| 58 | get api("/user", user) | 106 | get api("/user", user) |