users.rb 14.0 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
N
Nihad Abbasov 已提交
13
      get do
14
        unless can?(current_user, :read_users_list, nil)
F
Felipe Artur 已提交
15 16 17
          render_api_error!("Not authorized.", 403)
        end

18 19 20 21 22 23 24 25
        if params[:username].present?
          @users = User.where(username: params[:username])
        else
          @users = User.all
          @users = @users.active if params[:active].present?
          @users = @users.search(params[:search]) if params[:search].present?
          @users = paginate @users
        end
26 27 28 29 30 31

        if current_user.is_admin?
          present @users, with: Entities::UserFull
        else
          present @users, with: Entities::UserBasic
        end
N
Nihad Abbasov 已提交
32 33 34 35 36 37 38 39 40 41
      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])
42

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

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

86 87 88 89
        if identity_attrs.any?
          user.identities.build(identity_attrs)
        end

90
        if user.save
91
          present user, with: Entities::UserFull
92
        else
J
jubianchi 已提交
93 94 95 96 97 98 99 100 101
          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)
102 103
        end
      end
104 105 106 107 108 109 110 111 112 113

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

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

131 132
        admin = attrs.delete(:admin)
        user.admin = admin unless admin.nil?
J
jubianchi 已提交
133 134 135 136 137 138 139 140 141

        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

142 143 144 145 146 147 148 149 150 151 152
        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

153
        if user.update_attributes(attrs)
154
          present user, with: Entities::UserFull
155
        else
J
jubianchi 已提交
156
          render_validation_error!(user)
157 158 159
        end
      end

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

A
Angus MacArthur 已提交
172 173 174 175 176 177
        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 已提交
178
          render_validation_error!(key)
A
Angus MacArthur 已提交
179 180 181
        end
      end

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

        present user.keys, with: Entities::SSHKey
194 195 196 197 198 199 200 201 202 203 204 205 206
      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 已提交
207 208 209 210 211 212 213
        not_found!('User') unless user

        begin
          key = user.keys.find params[:id]
          key.destroy
        rescue ActiveRecord::RecordNotFound
          not_found!('Key')
214 215 216
        end
      end

217 218 219
      # Add email to a specified user. Only available to admin users.
      #
      # Parameters:
D
Douwe Maan 已提交
220 221
      #   id (required) - The ID of a user
      #   email (required) - Email address
222
      # Example Request:
D
Douwe Maan 已提交
223
      #   POST /users/:id/emails
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
      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 已提交
242
      #   uid (required) - The ID of a user
243
      # Example Request:
D
Douwe Maan 已提交
244
      #   GET /users/:uid/emails
245 246 247 248 249 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
      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

276 277 278 279 280 281
      # Delete user. Available only for admin
      #
      # Example Request:
      #   DELETE /users/:id
      delete ":id" do
        authenticated_as_admin!
S
skv 已提交
282
        user = User.find_by(id: params[:id])
283 284

        if user
285
          DeleteUserService.new(current_user).execute(user)
286
        else
J
jubianchi 已提交
287
          not_found!('User')
288 289
        end
      end
290 291 292 293 294 295 296 297 298

      # 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])

299 300 301
        if !user
          not_found!('User')
        elsif !user.ldap_blocked?
302 303
          user.block
        else
304
          forbidden!('LDAP blocked users cannot be modified by the API')
305 306 307 308 309 310 311 312 313 314 315
        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])

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

      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

336
        events = user.events.
337 338 339
          merge(ProjectsFinder.new.execute(current_user)).
          references(:project).
          with_associations.
340
          recent.
341 342 343 344
          page(params[:page])

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

347 348 349 350 351 352
    resource :user do
      # Get currently authenticated user
      #
      # Example Request:
      #   GET /user
      get do
353
        present @current_user, with: Entities::UserFull
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
      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
381
        required_attributes! [:title, :key]
382

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

392
      # Delete existing ssh key of currently authenticated user
393 394 395 396 397 398
      #
      # Parameters:
      #   id (required) - SSH Key ID
      # Example Request:
      #   DELETE /user/keys/:id
      delete "keys/:id" do
399 400
        begin
          key = current_user.keys.find params[:id]
401
          key.destroy
402 403
        rescue
        end
404
      end
405 406 407 408 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

      # 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 已提交
457 458 459
    end
  end
end