Commit e954438a1d3a45addebf52ab04155459d7d84db0

Authored by Boyan Tabakov
1 parent f4a6f1fd

Extended users API to support updating and deleting users.

Also added tests.
doc/api/users.md
... ... @@ -20,6 +20,8 @@ GET /users
20 20 "linkedin": "",
21 21 "twitter": "",
22 22 "dark_scheme": false,
  23 + "extern_uid": "john.smith",
  24 + "provider": "provider_name",
23 25 "theme_id": 1
24 26 },
25 27 {
... ... @@ -34,6 +36,8 @@ GET /users
34 36 "linkedin": "",
35 37 "twitter": "",
36 38 "dark_scheme": true,
  39 + "extern_uid": "jack.smith",
  40 + "provider": "provider_name",
37 41 "theme_id": 1
38 42 }
39 43 ]
... ... @@ -64,6 +68,8 @@ Parameters:
64 68 "linkedin": "",
65 69 "twitter": "",
66 70 "dark_scheme": false,
  71 + "extern_uid": "john.smith",
  72 + "provider": "provider_name",
67 73 "theme_id": 1
68 74 }
69 75 ```
... ... @@ -84,10 +90,47 @@ Parameters:
84 90 + `linkedin` - Linkedin
85 91 + `twitter` - Twitter account
86 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 97 Will return created user with status `201 Created` on success, or `404 Not
89 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 134 ## Current user
92 135  
93 136 Get currently authenticated user.
... ...
lib/api/entities.rb
... ... @@ -2,7 +2,7 @@ module Gitlab
2 2 module Entities
3 3 class User < Grape::Entity
4 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 6 end
7 7  
8 8 class UserBasic < Grape::Entity
... ...
lib/api/users.rb
... ... @@ -34,11 +34,14 @@ module Gitlab
34 34 # linkedin - Linkedin
35 35 # twitter - Twitter account
36 36 # projects_limit - Number of projects user can create
  37 + # extern_uid - External authentication provider UID
  38 + # provider - External provider
  39 + # bio - Bio
37 40 # Example Request:
38 41 # POST /users
39 42 post do
40 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 45 user = User.new attrs, as: :admin
43 46 if user.save
44 47 present user, with: Entities::User
... ... @@ -46,6 +49,48 @@ module Gitlab
46 49 not_found!
47 50 end
48 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 94 end
50 95  
51 96 resource :user do
... ...
spec/requests/api/users_spec.rb
... ... @@ -53,6 +53,54 @@ describe Gitlab::API do
53 53 end
54 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 104 describe "GET /user" do
57 105 it "should return current user" do
58 106 get api("/user", user)
... ...