BigW Consortium Gitlab

users.rb 13.2 KB
Newer Older
1
module API
2 3 4 5
  # Users API
  class Users < Grape::API
    before { authenticate! }

6
    resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do
7 8 9 10
      # Get a users list
      #
      # Example Request:
      #  GET /users
11 12
      #  GET /users?search=Admin
      #  GET /users?username=root
13
      get do
14
        unless can?(current_user, :read_users_list, nil)
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
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

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

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

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

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

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

125
        attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :bio, :location, :can_create_group, :admin, :external]
126
        user = User.find(params[:id])
127
        not_found!('User') unless user
128

129 130
        admin = attrs.delete(:admin)
        user.admin = admin unless admin.nil?
131 132 133 134 135 136 137 138 139

        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

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

151
        if user.update_attributes(attrs)
152
          present user, with: Entities::UserFull
153
        else
154
          render_validation_error!(user)
155 156 157
        end
      end

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

Angus MacArthur committed
170 171 172 173 174 175
        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
176
          render_validation_error!(key)
Angus MacArthur committed
177 178 179
        end
      end

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

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

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

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

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

        if user
283
          DeleteUserService.new(current_user).execute(user)
284
        else
285
          not_found!('User')
286 287
        end
      end
288 289 290 291 292 293 294 295 296

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

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

314 315
        if !user
          not_found!('User')
Gabriel Mazetto committed
316
        elsif user.ldap_blocked?
317
          forbidden!('LDAP blocked users cannot be unblocked by the API')
Gabriel Mazetto committed
318 319
        else
          user.activate
320 321
        end
      end
322 323
    end

324 325 326 327 328 329
    resource :user do
      # Get currently authenticated user
      #
      # Example Request:
      #   GET /user
      get do
330
        present @current_user, with: Entities::UserLogin
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
      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
358
        required_attributes! [:title, :key]
359

360 361 362 363 364
        attrs = attributes_for_keys [:title, :key]
        key = current_user.keys.new attrs
        if key.save
          present key, with: Entities::SSHKey
        else
365
          render_validation_error!(key)
366 367 368
        end
      end

369
      # Delete existing ssh key of currently authenticated user
370 371 372 373 374 375
      #
      # Parameters:
      #   id (required) - SSH Key ID
      # Example Request:
      #   DELETE /user/keys/:id
      delete "keys/:id" do
376 377
        begin
          key = current_user.keys.find params[:id]
378
          key.destroy
379 380
        rescue
        end
381
      end
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 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

      # 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
434 435 436
    end
  end
end