users.rb 14.2 KB
Newer Older
1
module API
N
Nihad Abbasov 已提交
2 3 4 5
  # Users API
  class Users < Grape::API
    before { authenticate! }

6
    resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do
N
Nihad Abbasov 已提交
7 8 9 10
      # Get a users list
      #
      # Example Request:
      #  GET /users
11 12
      #  GET /users?search=Admin
      #  GET /users?username=root
13 14 15
      #  GET /users?active=true
      #  GET /users?external=true
      #  GET /users?blocked=true
N
Nihad Abbasov 已提交
16
      get do
17
        unless can?(current_user, :read_users_list, nil)
F
Felipe Artur 已提交
18 19 20
          render_api_error!("Not authorized.", 403)
        end

21 22 23 24
        if params[:username].present?
          @users = User.where(username: params[:username])
        else
          @users = User.all
25
          @users = @users.active if to_boolean(params[:active])
26
          @users = @users.search(params[:search]) if params[:search].present?
27 28
          @users = @users.blocked if to_boolean(params[:blocked])
          @users = @users.external if to_boolean(params[:external]) && current_user.is_admin?
29 30
          @users = paginate @users
        end
31 32 33 34 35 36

        if current_user.is_admin?
          present @users, with: Entities::UserFull
        else
          present @users, with: Entities::UserBasic
        end
N
Nihad Abbasov 已提交
37 38 39 40 41 42 43 44 45 46
      end

      # Get a single user
      #
      # Parameters:
      #   id (required) - The ID of a user
      # Example Request:
      #   GET /users/:id
      get ":id" do
        @user = User.find(params[:id])
47

F
Felipe Artur 已提交
48
        if current_user && current_user.is_admin?
49
          present @user, with: Entities::UserFull
F
Felipe Artur 已提交
50
        elsif can?(current_user, :read_user, @user)
51
          present @user, with: Entities::User
F
Felipe Artur 已提交
52 53
        else
          render_api_error!("User not found.", 404)
54
        end
N
Nihad Abbasov 已提交
55
      end
56

57 58 59 60 61
      # Create user. Available only for admin
      #
      # Parameters:
      #   email (required)                  - Email
      #   password (required)               - Password
J
jubianchi 已提交
62 63
      #   name (required)                   - Name
      #   username (required)               - Name
64
      #   skype                             - Skype ID
V
Valeriy Sizov 已提交
65
      #   linkedin                          - Linkedin
66
      #   twitter                           - Twitter account
J
Jerome Dalbert 已提交
67
      #   website_url                       - Website url
68
      #   organization                      - Organization
69
      #   projects_limit                    - Number of projects user can create
70 71 72
      #   extern_uid                        - External authentication provider UID
      #   provider                          - External provider
      #   bio                               - Bio
R
Robert Schilling 已提交
73
      #   location                          - Location of the user
74 75
      #   admin                             - User is admin - true or false (default)
      #   can_create_group                  - User can create groups - true or false
M
Matthew Monaco 已提交
76
      #   confirm                           - Require user confirmation - true (default) or false
77
      #   external                          - Flags the user as external - true or false(default)
78 79 80 81
      # Example Request:
      #   POST /users
      post do
        authenticated_as_admin!
82
        required_attributes! [:email, :password, :name, :username]
83
        attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :bio, :location, :can_create_group, :admin, :confirm, :external, :organization]
84
        admin = attrs.delete(:admin)
85
        confirm = !(attrs.delete(:confirm) =~ /(false|f|no|0)$/i)
86 87
        user = User.build_user(attrs)
        user.admin = admin unless admin.nil?
M
Matthew Monaco 已提交
88
        user.skip_confirmation! unless confirm
89
        identity_attrs = attributes_for_keys [:provider, :extern_uid]
Z
Zeger-Jan van de Weg 已提交
90

91 92 93 94
        if identity_attrs.any?
          user.identities.build(identity_attrs)
        end

95
        if user.save
96
          present user, with: Entities::UserFull
97
        else
J
jubianchi 已提交
98 99 100 101 102 103 104 105 106
          conflict!('Email has already been taken') if User.
              where(email: user.email).
              count > 0

          conflict!('Username has already been taken') if User.
              where(username: user.username).
              count > 0

          render_validation_error!(user)
107 108
        end
      end
109 110 111 112 113 114 115 116 117 118

      # Update user. Available only for admin
      #
      # Parameters:
      #   email                             - Email
      #   name                              - Name
      #   password                          - Password
      #   skype                             - Skype ID
      #   linkedin                          - Linkedin
      #   twitter                           - Twitter account
J
Jerome Dalbert 已提交
119
      #   website_url                       - Website url
120
      #   organization                      - Organization
K
Kevin Lyda 已提交
121
      #   projects_limit                    - Limit projects each user can create
122
      #   bio                               - Bio
R
Robert Schilling 已提交
123
      #   location                          - Location of the user
124 125
      #   admin                             - User is admin - true or false (default)
      #   can_create_group                  - User can create groups - true or false
126
      #   external                          - Flags the user as external - true or false(default)
127 128 129 130
      # Example Request:
      #   PUT /users/:id
      put ":id" do
        authenticated_as_admin!
131

132
        attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :bio, :location, :can_create_group, :admin, :external, :organization]
133
        user = User.find(params[:id])
J
jubianchi 已提交
134
        not_found!('User') unless user
135

136 137
        admin = attrs.delete(:admin)
        user.admin = admin unless admin.nil?
J
jubianchi 已提交
138 139 140 141 142 143 144 145 146

        conflict!('Email has already been taken') if attrs[:email] &&
            User.where(email: attrs[:email]).
                where.not(id: user.id).count > 0

        conflict!('Username has already been taken') if attrs[:username] &&
            User.where(username: attrs[:username]).
                where.not(id: user.id).count > 0

147 148 149 150 151 152 153 154 155 156 157
        identity_attrs = attributes_for_keys [:provider, :extern_uid]
        if identity_attrs.any?
          identity = user.identities.find_by(provider: identity_attrs[:provider])
          if identity
            identity.update_attributes(identity_attrs)
          else
            identity = user.identities.build(identity_attrs)
            identity.save
          end
        end

158
        if user.update_attributes(attrs)
159
          present user, with: Entities::UserFull
160
        else
J
jubianchi 已提交
161
          render_validation_error!(user)
162 163 164
        end
      end

A
Angus MacArthur 已提交
165 166 167
      # Add ssh key to a specified user. Only available to admin users.
      #
      # Parameters:
D
Douwe Maan 已提交
168 169 170
      #   id (required) - The ID of a user
      #   key (required) - New SSH Key
      #   title (required) - New SSH Key's title
A
Angus MacArthur 已提交
171
      # Example Request:
D
Douwe Maan 已提交
172
      #   POST /users/:id/keys
A
Angus MacArthur 已提交
173 174
      post ":id/keys" do
        authenticated_as_admin!
J
jubianchi 已提交
175 176
        required_attributes! [:title, :key]

A
Angus MacArthur 已提交
177 178 179 180 181 182
        user = User.find(params[:id])
        attrs = attributes_for_keys [:title, :key]
        key = user.keys.new attrs
        if key.save
          present key, with: Entities::SSHKey
        else
J
jubianchi 已提交
183
          render_validation_error!(key)
A
Angus MacArthur 已提交
184 185 186
        end
      end

187 188 189
      # Get ssh keys of a specified user. Only available to admin users.
      #
      # Parameters:
D
Douwe Maan 已提交
190
      #   uid (required) - The ID of a user
191
      # Example Request:
D
Douwe Maan 已提交
192
      #   GET /users/:uid/keys
193 194 195
      get ':uid/keys' do
        authenticated_as_admin!
        user = User.find_by(id: params[:uid])
J
jubianchi 已提交
196 197 198
        not_found!('User') unless user

        present user.keys, with: Entities::SSHKey
199 200 201 202 203 204 205 206 207 208 209 210 211
      end

      # Delete existing ssh key of a specified user. Only available to admin
      # users.
      #
      # Parameters:
      #   uid (required) - The ID of a user
      #   id (required) - SSH Key ID
      # Example Request:
      #   DELETE /users/:uid/keys/:id
      delete ':uid/keys/:id' do
        authenticated_as_admin!
        user = User.find_by(id: params[:uid])
J
jubianchi 已提交
212 213 214 215 216 217 218
        not_found!('User') unless user

        begin
          key = user.keys.find params[:id]
          key.destroy
        rescue ActiveRecord::RecordNotFound
          not_found!('Key')
219 220 221
        end
      end

222 223 224
      # Add email to a specified user. Only available to admin users.
      #
      # Parameters:
D
Douwe Maan 已提交
225 226
      #   id (required) - The ID of a user
      #   email (required) - Email address
227
      # Example Request:
D
Douwe Maan 已提交
228
      #   POST /users/:id/emails
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
      post ":id/emails" do
        authenticated_as_admin!
        required_attributes! [:email]

        user = User.find(params[:id])
        attrs = attributes_for_keys [:email]
        email = user.emails.new attrs
        if email.save
          NotificationService.new.new_email(email)
          present email, with: Entities::Email
        else
          render_validation_error!(email)
        end
      end

      # Get emails of a specified user. Only available to admin users.
      #
      # Parameters:
D
Douwe Maan 已提交
247
      #   uid (required) - The ID of a user
248
      # Example Request:
D
Douwe Maan 已提交
249
      #   GET /users/:uid/emails
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
      get ':uid/emails' do
        authenticated_as_admin!
        user = User.find_by(id: params[:uid])
        not_found!('User') unless user

        present user.emails, with: Entities::Email
      end

      # Delete existing email of a specified user. Only available to admin
      # users.
      #
      # Parameters:
      #   uid (required) - The ID of a user
      #   id (required) - Email ID
      # Example Request:
      #   DELETE /users/:uid/emails/:id
      delete ':uid/emails/:id' do
        authenticated_as_admin!
        user = User.find_by(id: params[:uid])
        not_found!('User') unless user

        begin
          email = user.emails.find params[:id]
          email.destroy

          user.update_secondary_emails!
        rescue ActiveRecord::RecordNotFound
          not_found!('Email')
        end
      end

281 282 283 284 285 286
      # Delete user. Available only for admin
      #
      # Example Request:
      #   DELETE /users/:id
      delete ":id" do
        authenticated_as_admin!
S
skv 已提交
287
        user = User.find_by(id: params[:id])
288 289

        if user
290
          DeleteUserService.new(current_user).execute(user)
291
        else
J
jubianchi 已提交
292
          not_found!('User')
293 294
        end
      end
295 296 297 298 299 300 301 302 303

      # Block user. Available only for admin
      #
      # Example Request:
      #   PUT /users/:id/block
      put ':id/block' do
        authenticated_as_admin!
        user = User.find_by(id: params[:id])

304 305 306
        if !user
          not_found!('User')
        elsif !user.ldap_blocked?
307 308
          user.block
        else
309
          forbidden!('LDAP blocked users cannot be modified by the API')
310 311 312 313 314 315 316 317 318 319 320
        end
      end

      # Unblock user. Available only for admin
      #
      # Example Request:
      #   PUT /users/:id/unblock
      put ':id/unblock' do
        authenticated_as_admin!
        user = User.find_by(id: params[:id])

321 322
        if !user
          not_found!('User')
G
Gabriel Mazetto 已提交
323
        elsif user.ldap_blocked?
324
          forbidden!('LDAP blocked users cannot be unblocked by the API')
G
Gabriel Mazetto 已提交
325 326
        else
          user.activate
327 328
        end
      end
329 330 331 332 333 334 335 336 337 338 339 340

      desc 'Get contribution events of a specified user' do
        detail 'This feature was introduced in GitLab 8.13.'
        success Entities::Event
      end
      params do
        requires :id, type: String, desc: 'The user ID'
      end
      get ':id/events' do
        user = User.find_by(id: declared(params).id)
        not_found!('User') unless user

341
        events = user.events.
342 343 344
          merge(ProjectsFinder.new.execute(current_user)).
          references(:project).
          with_associations.
A
Airat Shigapov 已提交
345
          recent
346 347 348

        present paginate(events), with: Entities::Event
      end
N
Nihad Abbasov 已提交
349 350
    end

351 352 353 354 355 356
    resource :user do
      # Get currently authenticated user
      #
      # Example Request:
      #   GET /user
      get do
357
        present @current_user, with: Entities::UserFull
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
      end

      # Get currently authenticated user's keys
      #
      # Example Request:
      #   GET /user/keys
      get "keys" do
        present current_user.keys, with: Entities::SSHKey
      end

      # Get single key owned by currently authenticated user
      #
      # Example Request:
      #   GET /user/keys/:id
      get "keys/:id" do
        key = current_user.keys.find params[:id]
        present key, with: Entities::SSHKey
      end

      # Add new ssh key to currently authenticated user
      #
      # Parameters:
      #   key (required) - New SSH Key
      #   title (required) - New SSH Key's title
      # Example Request:
      #   POST /user/keys
      post "keys" do
385
        required_attributes! [:title, :key]
386

387 388 389 390 391
        attrs = attributes_for_keys [:title, :key]
        key = current_user.keys.new attrs
        if key.save
          present key, with: Entities::SSHKey
        else
J
jubianchi 已提交
392
          render_validation_error!(key)
393 394 395
        end
      end

396
      # Delete existing ssh key of currently authenticated user
397 398 399 400 401 402
      #
      # Parameters:
      #   id (required) - SSH Key ID
      # Example Request:
      #   DELETE /user/keys/:id
      delete "keys/:id" do
403 404
        begin
          key = current_user.keys.find params[:id]
405
          key.destroy
406 407
        rescue
        end
408
      end
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460

      # Get currently authenticated user's emails
      #
      # Example Request:
      #   GET /user/emails
      get "emails" do
        present current_user.emails, with: Entities::Email
      end

      # Get single email owned by currently authenticated user
      #
      # Example Request:
      #   GET /user/emails/:id
      get "emails/:id" do
        email = current_user.emails.find params[:id]
        present email, with: Entities::Email
      end

      # Add new email to currently authenticated user
      #
      # Parameters:
      #   email (required) - Email address
      # Example Request:
      #   POST /user/emails
      post "emails" do
        required_attributes! [:email]

        attrs = attributes_for_keys [:email]
        email = current_user.emails.new attrs
        if email.save
          NotificationService.new.new_email(email)
          present email, with: Entities::Email
        else
          render_validation_error!(email)
        end
      end

      # Delete existing email of currently authenticated user
      #
      # Parameters:
      #   id (required) - EMail ID
      # Example Request:
      #   DELETE /user/emails/:id
      delete "emails/:id" do
        begin
          email = current_user.emails.find params[:id]
          email.destroy

          current_user.update_secondary_emails!
        rescue
        end
      end
N
Nihad Abbasov 已提交
461 462 463
    end
  end
end