users_spec.rb 68.2 KB
Newer Older
Nihad Abbasov's avatar
Nihad Abbasov committed
1 2
require 'spec_helper'

3 4
describe API::Users do
  let(:user)  { create(:user) }
5
  let(:admin) { create(:admin) }
6
  let(:key) { create(:key, user: user) }
7
  let(:gpg_key) { create(:gpg_key, user: user) }
8
  let(:email) { create(:email, user: user) }
9
  let(:omniauth_user) { create(:omniauth_user) }
10 11
  let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') }
  let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
12
  let(:not_existing_user_id) { (User.maximum('id') || 0 ) + 10 }
13
  let(:not_existing_pat_id) { (PersonalAccessToken.maximum('id') || 0 ) + 10 }
14
  let(:private_user) { create(:user, private_profile: true) }
Nihad Abbasov's avatar
Nihad Abbasov committed
15

16 17 18 19 20 21 22 23
  shared_examples 'rendering user status' do
    it 'returns the status if there was one' do
      create(:user_status, user: user)

      get api(path, user)

      expect(response).to have_gitlab_http_status(:success)
      expect(json_response['message']).to be_present
24
      expect(json_response['message_html']).to be_present
25 26 27 28 29 30 31 32 33 34 35 36
      expect(json_response['emoji']).to be_present
    end

    it 'returns an empty response if there was no status' do
      get api(path, user)

      expect(response).to have_gitlab_http_status(:success)
      expect(json_response['message']).to be_nil
      expect(json_response['emoji']).to be_nil
    end
  end

37
  describe 'GET /users' do
38
    context "when unauthenticated" do
39
      it "returns authorization error when the `username` parameter is not passed" do
40
        get api("/users")
41

42
        expect(response).to have_gitlab_http_status(403)
43 44 45
      end

      it "returns the user when a valid `username` parameter is passed" do
blackst0ne's avatar
blackst0ne committed
46
        get api("/users"), params: { username: user.username }
47

48
        expect(response).to match_response_schema('public_api/v4/user/basics')
49 50 51 52 53
        expect(json_response.size).to eq(1)
        expect(json_response[0]['id']).to eq(user.id)
        expect(json_response[0]['username']).to eq(user.username)
      end

54
      it "returns the user when a valid `username` parameter is passed (case insensitive)" do
blackst0ne's avatar
blackst0ne committed
55
        get api("/users"), params: { username: user.username.upcase }
56 57 58 59 60 61 62

        expect(response).to match_response_schema('public_api/v4/user/basics')
        expect(json_response.size).to eq(1)
        expect(json_response[0]['id']).to eq(user.id)
        expect(json_response[0]['username']).to eq(user.username)
      end

63
      it "returns an empty response when an invalid `username` parameter is passed" do
blackst0ne's avatar
blackst0ne committed
64
        get api("/users"), params: { username: 'invalid' }
65

66
        expect(response).to have_gitlab_http_status(200)
67 68
        expect(json_response).to be_an Array
        expect(json_response.size).to eq(0)
69
      end
70 71 72 73 74 75 76

      context "when public level is restricted" do
        before do
          stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
        end

        it "returns authorization error when the `username` parameter refers to an inaccessible user" do
blackst0ne's avatar
blackst0ne committed
77
          get api("/users"), params: { username: user.username }
78 79 80 81 82 83 84 85 86 87

          expect(response).to have_gitlab_http_status(403)
        end

        it "returns authorization error when the `username` parameter is not passed" do
          get api("/users")

          expect(response).to have_gitlab_http_status(403)
        end
      end
Nihad Abbasov's avatar
Nihad Abbasov committed
88 89
    end

90
    context "when authenticated" do
91
      # These specs are written just in case API authentication is not required anymore
Felipe Artur's avatar
Felipe Artur committed
92 93 94 95 96
      context "when public level is restricted" do
        before do
          stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
        end

97
        context 'when authenticate as a regular user' do
98
          it "renders 200" do
99 100
            get api("/users", user)

101
            expect(response).to match_response_schema('public_api/v4/user/basics')
102
          end
Felipe Artur's avatar
Felipe Artur committed
103 104
        end

105 106 107 108
        context 'when authenticate as an admin' do
          it "renders 200" do
            get api("/users", admin)

109
            expect(response).to match_response_schema('public_api/v4/user/basics')
110
          end
Felipe Artur's avatar
Felipe Artur committed
111 112 113
        end
      end

114
      it "returns an array of users" do
Robert Speicher's avatar
Robert Speicher committed
115
        get api("/users", user)
116

117
        expect(response).to match_response_schema('public_api/v4/user/basics')
118
        expect(response).to include_pagination_headers
Marin Jankovski's avatar
Marin Jankovski committed
119
        username = user.username
120 121 122
        expect(json_response.detect do |user|
          user['username'] == username
        end['username']).to eq(username)
Nihad Abbasov's avatar
Nihad Abbasov committed
123
      end
124

125 126 127 128 129 130
      it "returns an array of blocked users" do
        ldap_blocked_user
        create(:user, state: 'blocked')

        get api("/users?blocked=true", user)

131
        expect(response).to match_response_schema('public_api/v4/user/basics')
132
        expect(response).to include_pagination_headers
133 134 135
        expect(json_response).to all(include('state' => /(blocked|ldap_blocked)/))
      end

136
      it "returns one user" do
137
        get api("/users?username=#{omniauth_user.username}", user)
138

139
        expect(response).to match_response_schema('public_api/v4/user/basics')
140
        expect(response).to include_pagination_headers
141 142
        expect(json_response.first['username']).to eq(omniauth_user.username)
      end
143

144 145 146 147 148 149 150 151
      it "returns one user (case insensitive)" do
        get api("/users?username=#{omniauth_user.username.upcase}", user)

        expect(response).to match_response_schema('public_api/v4/user/basics')
        expect(response).to include_pagination_headers
        expect(json_response.first['username']).to eq(omniauth_user.username)
      end

152 153 154
      it "returns a 403 when non-admin user searches by external UID" do
        get api("/users?extern_uid=#{omniauth_user.identities.first.extern_uid}&provider=#{omniauth_user.identities.first.provider}", user)

155
        expect(response).to have_gitlab_http_status(403)
156
      end
157 158 159 160

      it 'does not reveal the `is_admin` flag of the user' do
        get api('/users', user)

161
        expect(response).to match_response_schema('public_api/v4/user/basics')
162 163
        expect(json_response.first.keys).not_to include 'is_admin'
      end
Nihad Abbasov's avatar
Nihad Abbasov committed
164
    end
165 166

    context "when admin" do
167 168
      context 'when sudo is defined' do
        it 'does not return 500' do
Douwe Maan's avatar
Douwe Maan committed
169 170
          admin_personal_access_token = create(:personal_access_token, user: admin, scopes: [:sudo])
          get api("/users?sudo=#{user.id}", admin, personal_access_token: admin_personal_access_token)
171

172
          expect(response).to have_gitlab_http_status(:success)
173 174 175
        end
      end

176
      it "returns an array of users" do
177
        get api("/users", admin)
178

179
        expect(response).to match_response_schema('public_api/v4/user/admins')
180
        expect(response).to include_pagination_headers
181
      end
182 183 184 185 186 187

      it "returns an array of external users" do
        create(:user, external: true)

        get api("/users?external=true", admin)

188
        expect(response).to match_response_schema('public_api/v4/user/admins')
189
        expect(response).to include_pagination_headers
190 191
        expect(json_response).to all(include('external' => true))
      end
192 193 194 195

      it "returns one user by external UID" do
        get api("/users?extern_uid=#{omniauth_user.identities.first.extern_uid}&provider=#{omniauth_user.identities.first.provider}", admin)

196
        expect(response).to match_response_schema('public_api/v4/user/admins')
197 198 199 200 201 202 203
        expect(json_response.size).to eq(1)
        expect(json_response.first['username']).to eq(omniauth_user.username)
      end

      it "returns 400 error if provider with no extern_uid" do
        get api("/users?extern_uid=#{omniauth_user.identities.first.extern_uid}", admin)

204
        expect(response).to have_gitlab_http_status(400)
205 206 207 208 209
      end

      it "returns 400 error if provider with no extern_uid" do
        get api("/users?provider=#{omniauth_user.identities.first.provider}", admin)

210
        expect(response).to have_gitlab_http_status(400)
211
      end
212

James Lopez's avatar
James Lopez committed
213
      it "returns a user created before a specific date" do
James Lopez's avatar
James Lopez committed
214
        user = create(:user, created_at: Date.new(2000, 1, 1))
215 216 217

        get api("/users?created_before=2000-01-02T00:00:00.060Z", admin)

218
        expect(response).to match_response_schema('public_api/v4/user/admins')
219 220 221 222 223
        expect(json_response.size).to eq(1)
        expect(json_response.first['username']).to eq(user.username)
      end

      it "returns no users created before a specific date" do
James Lopez's avatar
James Lopez committed
224
        create(:user, created_at: Date.new(2001, 1, 1))
225 226 227

        get api("/users?created_before=2000-01-02T00:00:00.060Z", admin)

228
        expect(response).to match_response_schema('public_api/v4/user/admins')
229 230 231 232
        expect(json_response.size).to eq(0)
      end

      it "returns users created before and after a specific date" do
James Lopez's avatar
James Lopez committed
233
        user = create(:user, created_at: Date.new(2001, 1, 1))
234 235 236

        get api("/users?created_before=2001-01-02T00:00:00.060Z&created_after=1999-01-02T00:00:00.060", admin)

237
        expect(response).to match_response_schema('public_api/v4/user/admins')
238 239 240
        expect(json_response.size).to eq(1)
        expect(json_response.first['username']).to eq(user.username)
      end
241 242 243 244 245

      it 'returns the correct order when sorted by id' do
        admin
        user

blackst0ne's avatar
blackst0ne committed
246
        get api('/users', admin), params: { order_by: 'id', sort: 'asc' }
247 248 249 250 251 252 253

        expect(response).to match_response_schema('public_api/v4/user/admins')
        expect(json_response.size).to eq(2)
        expect(json_response.first['id']).to eq(admin.id)
        expect(json_response.last['id']).to eq(user.id)
      end

254 255 256 257 258
      it 'returns users with 2fa enabled' do
        admin
        user
        user_with_2fa = create(:user, :two_factor_via_otp)

blackst0ne's avatar
blackst0ne committed
259
        get api('/users', admin), params: { two_factor: 'enabled' }
260 261 262 263 264 265

        expect(response).to match_response_schema('public_api/v4/user/admins')
        expect(json_response.size).to eq(1)
        expect(json_response.first['id']).to eq(user_with_2fa.id)
      end

266
      it 'returns 400 when provided incorrect sort params' do
blackst0ne's avatar
blackst0ne committed
267
        get api('/users', admin), params: { order_by: 'magic', sort: 'asc' }
268 269 270

        expect(response).to have_gitlab_http_status(400)
      end
271
    end
272 273

    context "when authenticated and ldap is enabled" do
Valery Sizov's avatar
Valery Sizov committed
274
      it "returns non-ldap user" do
275
        create :omniauth_user, provider: "ldapserver1"
blackst0ne's avatar
blackst0ne committed
276
        get api("/users", user), params: { skip_ldap: "true" }
277
        expect(response).to have_gitlab_http_status(200)
Robert Speicher's avatar
Robert Speicher committed
278
        expect(json_response).to be_an Array
279
        username = user.username
Robert Speicher's avatar
Robert Speicher committed
280
        expect(json_response.first["username"]).to eq username
281 282
      end
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
283 284 285
  end

  describe "GET /users/:id" do
286
    it "returns a user by id" do
Robert Speicher's avatar
Robert Speicher committed
287
      get api("/users/#{user.id}", user)
288

289
      expect(response).to match_response_schema('public_api/v4/user/basic')
290
      expect(json_response['username']).to eq(user.username)
Nihad Abbasov's avatar
Nihad Abbasov committed
291 292
    end

293 294 295
    it "does not return the user's `is_admin` flag" do
      get api("/users/#{user.id}", user)

296 297
      expect(response).to match_response_schema('public_api/v4/user/basic')
      expect(json_response.keys).not_to include 'is_admin'
298 299
    end

300 301 302 303
    context 'when authenticated as admin' do
      it 'includes the `is_admin` field' do
        get api("/users/#{user.id}", admin)

304
        expect(response).to match_response_schema('public_api/v4/user/admin')
305 306
        expect(json_response['is_admin']).to be(false)
      end
307 308 309 310 311 312 313

      it "includes the `created_at` field for private users" do
        get api("/users/#{private_user.id}", admin)

        expect(response).to match_response_schema('public_api/v4/user/admin')
        expect(json_response.keys).to include 'created_at'
      end
314 315
    end

316 317 318 319
    context 'for an anonymous user' do
      it "returns a user by id" do
        get api("/users/#{user.id}")

320
        expect(response).to match_response_schema('public_api/v4/user/basic')
321 322 323 324 325 326 327 328 329
        expect(json_response['username']).to eq(user.username)
      end

      it "returns a 404 if the target user is present but inaccessible" do
        allow(Ability).to receive(:allowed?).and_call_original
        allow(Ability).to receive(:allowed?).with(nil, :read_user, user).and_return(false)

        get api("/users/#{user.id}")

330
        expect(response).to have_gitlab_http_status(404)
331
      end
332 333 334 335 336 337 338 339 340 341 342 343 344 345

      it "returns the `created_at` field for public users" do
        get api("/users/#{user.id}")

        expect(response).to match_response_schema('public_api/v4/user/basic')
        expect(json_response.keys).to include 'created_at'
      end

      it "does not return the `created_at` field for private users" do
        get api("/users/#{private_user.id}")

        expect(response).to match_response_schema('public_api/v4/user/basic')
        expect(json_response.keys).not_to include 'created_at'
      end
346
    end
347

348
    it "returns a 404 error if user id not found" do
349
      get api("/users/9999", user)
350

351
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
352
      expect(json_response['message']).to eq('404 User Not Found')
353
    end
354

355
    it "returns a 404 for invalid ID" do
356
      get api("/users/1ASDF", user)
357

358
      expect(response).to have_gitlab_http_status(404)
359
    end
360 361
  end

362 363 364 365 366 367 368 369 370 371 372 373
  describe 'GET /users/:id_or_username/status' do
    context 'when finding the user by id' do
      it_behaves_like 'rendering user status' do
        let(:path) { "/users/#{user.id}/status" }
      end
    end

    context 'when finding the user by username' do
      it_behaves_like 'rendering user status' do
        let(:path) { "/users/#{user.username}/status" }
      end
    end
374 375 376 377 378 379

    context 'when finding the user by username (case insensitive)' do
      it_behaves_like 'rendering user status' do
        let(:path) { "/users/#{user.username.upcase}/status" }
      end
    end
380 381
  end

382
  describe "POST /users" do
383 384 385
    before do
      admin
    end
386

387
    it "creates user" do
388
      expect do
blackst0ne's avatar
blackst0ne committed
389
        post api("/users", admin), params: attributes_for(:user, projects_limit: 3)
390
      end.to change { User.count }.by(1)
391 392
    end

393
    it "creates user with correct attributes" do
blackst0ne's avatar
blackst0ne committed
394
      post api('/users', admin), params: attributes_for(:user, admin: true, can_create_group: true)
395
      expect(response).to have_gitlab_http_status(201)
396 397
      user_id = json_response['id']
      new_user = User.find(user_id)
398 399 400
      expect(new_user).not_to eq(nil)
      expect(new_user.admin).to eq(true)
      expect(new_user.can_create_group).to eq(true)
401 402
    end

403 404 405 406
    it "creates user with optional attributes" do
      optional_attributes = { confirm: true }
      attributes = attributes_for(:user).merge(optional_attributes)

blackst0ne's avatar
blackst0ne committed
407
      post api('/users', admin), params: attributes
408

409
      expect(response).to have_gitlab_http_status(201)
410 411
    end

412
    it "creates non-admin user" do
blackst0ne's avatar
blackst0ne committed
413
      post api('/users', admin), params: attributes_for(:user, admin: false, can_create_group: false)
414
      expect(response).to have_gitlab_http_status(201)
415 416
      user_id = json_response['id']
      new_user = User.find(user_id)
417 418 419
      expect(new_user).not_to eq(nil)
      expect(new_user.admin).to eq(false)
      expect(new_user.can_create_group).to eq(false)
420 421
    end

422
    it "creates non-admin users by default" do
blackst0ne's avatar
blackst0ne committed
423
      post api('/users', admin), params: attributes_for(:user)
424
      expect(response).to have_gitlab_http_status(201)
425 426
      user_id = json_response['id']
      new_user = User.find(user_id)
427 428
      expect(new_user).not_to eq(nil)
      expect(new_user.admin).to eq(false)
429 430
    end

431
    it "returns 201 Created on success" do
blackst0ne's avatar
blackst0ne committed
432
      post api("/users", admin), params: attributes_for(:user, projects_limit: 3)
433
      expect(response).to have_gitlab_http_status(201)
434 435
    end

Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
436
    it 'creates non-external users by default' do
blackst0ne's avatar
blackst0ne committed
437
      post api("/users", admin), params: attributes_for(:user)
438
      expect(response).to have_gitlab_http_status(201)
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
439 440 441 442 443 444 445

      user_id = json_response['id']
      new_user = User.find(user_id)
      expect(new_user).not_to eq nil
      expect(new_user.external).to be_falsy
    end

446
    it 'allows an external user to be created' do
blackst0ne's avatar
blackst0ne committed
447
      post api("/users", admin), params: attributes_for(:user, external: true)
448
      expect(response).to have_gitlab_http_status(201)
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
449 450 451 452 453 454 455

      user_id = json_response['id']
      new_user = User.find(user_id)
      expect(new_user).not_to eq nil
      expect(new_user.external).to be_truthy
    end

456
    it "creates user with reset password" do
blackst0ne's avatar
blackst0ne committed
457
      post api('/users', admin), params: attributes_for(:user, reset_password: true).except(:password)
458

459
      expect(response).to have_gitlab_http_status(201)
460 461 462 463 464 465 466 467

      user_id = json_response['id']
      new_user = User.find(user_id)

      expect(new_user).not_to eq(nil)
      expect(new_user.recently_sent_password_reset?).to eq(true)
    end

468
    it "creates user with private profile" do
blackst0ne's avatar
blackst0ne committed
469
      post api('/users', admin), params: attributes_for(:user, private_profile: true)
470 471 472 473 474 475 476 477 478 479

      expect(response).to have_gitlab_http_status(201)

      user_id = json_response['id']
      new_user = User.find(user_id)

      expect(new_user).not_to eq(nil)
      expect(new_user.private_profile?).to eq(true)
    end

480
    it "does not create user with invalid email" do
481
      post api('/users', admin),
blackst0ne's avatar
blackst0ne committed
482 483 484 485 486
           params: {
             email: 'invalid email',
             password: 'password',
             name: 'test'
           }
487
      expect(response).to have_gitlab_http_status(400)
488 489
    end

490
    it 'returns 400 error if name not given' do
blackst0ne's avatar
blackst0ne committed
491
      post api('/users', admin), params: attributes_for(:user).except(:name)
492
      expect(response).to have_gitlab_http_status(400)
493 494
    end

495
    it 'returns 400 error if password not given' do
blackst0ne's avatar
blackst0ne committed
496
      post api('/users', admin), params: attributes_for(:user).except(:password)
497
      expect(response).to have_gitlab_http_status(400)
498 499
    end

500
    it 'returns 400 error if email not given' do
blackst0ne's avatar
blackst0ne committed
501
      post api('/users', admin), params: attributes_for(:user).except(:email)
502
      expect(response).to have_gitlab_http_status(400)
503 504
    end

505
    it 'returns 400 error if username not given' do
blackst0ne's avatar
blackst0ne committed
506
      post api('/users', admin), params: attributes_for(:user).except(:username)
507
      expect(response).to have_gitlab_http_status(400)
508 509
    end

510
    it 'returns 400 error if user does not validate' do
511
      post api('/users', admin),
blackst0ne's avatar
blackst0ne committed
512 513 514 515 516 517 518 519
           params: {
             password: 'pass',
             email: 'test@example.com',
             username: 'test!',
             name: 'test',
             bio: 'g' * 256,
             projects_limit: -1
           }
520
      expect(response).to have_gitlab_http_status(400)
521 522 523 524 525 526 527 528
      expect(json_response['message']['password'])
        .to eq(['is too short (minimum is 8 characters)'])
      expect(json_response['message']['bio'])
        .to eq(['is too long (maximum is 255 characters)'])
      expect(json_response['message']['projects_limit'])
        .to eq(['must be greater than or equal to 0'])
      expect(json_response['message']['username'])
        .to eq([Gitlab::PathRegex.namespace_format_message])
529 530
    end

531
    it "is not available for non admin users" do
blackst0ne's avatar
blackst0ne committed
532
      post api("/users", user), params: attributes_for(:user)
533
      expect(response).to have_gitlab_http_status(403)
534
    end
535

536 537 538
    context 'with existing user' do
      before do
        post api('/users', admin),
blackst0ne's avatar
blackst0ne committed
539 540 541 542 543 544
             params: {
               email: 'test@example.com',
               password: 'password',
               username: 'test',
               name: 'foo'
             }
545
      end
546

547
      it 'returns 409 conflict error if user with same email exists' do
548
        expect do
549
          post api('/users', admin),
blackst0ne's avatar
blackst0ne committed
550 551 552 553 554 555
               params: {
                 name: 'foo',
                 email: 'test@example.com',
                 password: 'password',
                 username: 'foo'
               }
556
        end.to change { User.count }.by(0)
557
        expect(response).to have_gitlab_http_status(409)
558
        expect(json_response['message']).to eq('Email has already been taken')
559 560
      end

561
      it 'returns 409 conflict error if same username exists' do
562 563
        expect do
          post api('/users', admin),
blackst0ne's avatar
blackst0ne committed
564 565 566 567 568 569
               params: {
                 name: 'foo',
                 email: 'foo@example.com',
                 password: 'password',
                 username: 'test'
               }
570
        end.to change { User.count }.by(0)
571
        expect(response).to have_gitlab_http_status(409)
572
        expect(json_response['message']).to eq('Username has already been taken')
573
      end
574

575 576 577
      it 'returns 409 conflict error if same username exists (case insensitive)' do
        expect do
          post api('/users', admin),
blackst0ne's avatar
blackst0ne committed
578 579 580 581 582 583
               params: {
                 name: 'foo',
                 email: 'foo@example.com',
                 password: 'password',
                 username: 'TEST'
               }
584 585 586 587 588
        end.to change { User.count }.by(0)
        expect(response).to have_gitlab_http_status(409)
        expect(json_response['message']).to eq('Username has already been taken')
      end

589
      it 'creates user with new identity' do
blackst0ne's avatar
blackst0ne committed
590
        post api("/users", admin), params: attributes_for(:user, provider: 'github', extern_uid: '67890')
591

592
        expect(response).to have_gitlab_http_status(201)
593 594 595
        expect(json_response['identities'].first['extern_uid']).to eq('67890')
        expect(json_response['identities'].first['provider']).to eq('github')
      end
596
    end
597 598 599 600 601 602 603 604

    context "scopes" do
      let(:user) { admin }
      let(:path) { '/users' }
      let(:api_call) { method(:api) }

      include_examples 'does not allow the "read_user" scope'
    end
605 606
  end

Marin Jankovski's avatar
Marin Jankovski committed
607
  describe "GET /users/sign_up" do
608
    it "redirects to sign in page" do
609
      get "/users/sign_up"
610
      expect(response).to have_gitlab_http_status(302)
611
      expect(response).to redirect_to(new_user_session_path)
Marin Jankovski's avatar
Marin Jankovski committed
612 613 614
    end
  end

615
  describe "PUT /users/:id" do
616 617
    let!(:admin_user) { create(:admin) }

618
    it "updates user with new bio" do
blackst0ne's avatar
blackst0ne committed
619
      put api("/users/#{user.id}", admin), params: { bio: 'new test bio' }
James Lopez's avatar
James Lopez committed
620

621
      expect(response).to have_gitlab_http_status(200)
622 623
      expect(json_response['bio']).to eq('new test bio')
      expect(user.reload.bio).to eq('new test bio')
624 625
    end

626
    it "updates user with new password and forces reset on next login" do
James Lopez's avatar
James Lopez committed
627 628
      stub_licensed_features(extended_audit_events: true)

blackst0ne's avatar
blackst0ne committed
629
      put api("/users/#{user.id}", admin), params: { password: '12345678' }
630

631
      expect(response).to have_gitlab_http_status(200)
632
      expect(user.reload.password_expires_at).to be <= Time.now
633
      expect(AuditEvent.count).to eq(1)
634 635
    end

636
    it "updates user with organization" do
blackst0ne's avatar
blackst0ne committed
637
      put api("/users/#{user.id}", admin), params: { organization: 'GitLab' }
638

639
      expect(response).to have_gitlab_http_status(200)
640 641 642 643
      expect(json_response['organization']).to eq('GitLab')
      expect(user.reload.organization).to eq('GitLab')
    end

644
    it 'updates user with avatar' do
blackst0ne's avatar
blackst0ne committed
645
      put api("/users/#{user.id}", admin), params: { avatar: fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif') }
646 647 648 649

      user.reload

      expect(user.avatar).to be_present
650
      expect(response).to have_gitlab_http_status(200)
651 652 653
      expect(json_response['avatar_url']).to include(user.avatar_path)
    end

James Lopez's avatar
James Lopez committed
654
    it 'updates user with a new email' do
655 656
      old_email = user.email
      old_notification_email = user.notification_email
blackst0ne's avatar
blackst0ne committed
657
      put api("/users/#{user.id}", admin), params: { email: 'new@email.com' }
James Lopez's avatar
James Lopez committed
658

659 660
      user.reload

661
      expect(response).to have_gitlab_http_status(200)
662 663 664 665
      expect(user).to be_confirmed
      expect(user.email).to eq(old_email)
      expect(user.notification_email).to eq(old_notification_email)
      expect(user.unconfirmed_email).to eq('new@email.com')
James Lopez's avatar
James Lopez committed
666 667
    end

Daniel Juarez's avatar
Daniel Juarez committed
668
    it 'skips reconfirmation when requested' do
blackst0ne's avatar
blackst0ne committed
669
      put api("/users/#{user.id}", admin), params: { email: 'new@email.com', skip_reconfirmation: true }
Daniel Juarez's avatar
Daniel Juarez committed
670 671 672

      user.reload

673 674 675
      expect(response).to have_gitlab_http_status(200)
      expect(user).to be_confirmed
      expect(user.email).to eq('new@email.com')
Daniel Juarez's avatar
Daniel Juarez committed
676 677
    end

678
    it 'updates user with his own username' do
blackst0ne's avatar
blackst0ne committed
679
      put api("/users/#{user.id}", admin), params: { username: user.username }
James Lopez's avatar
James Lopez committed
680

681
      expect(response).to have_gitlab_http_status(200)
682 683
      expect(json_response['username']).to eq(user.username)
      expect(user.reload.username).to eq(user.username)
684 685
    end

686
    it "updates user's existing identity" do
blackst0ne's avatar
blackst0ne committed
687
      put api("/users/#{omniauth_user.id}", admin), params: { provider: 'ldapmain', extern_uid: '654321' }
James Lopez's avatar
James Lopez committed
688

689
      expect(response).to have_gitlab_http_status(200)
690 691 692
      expect(omniauth_user.reload.identities.first.extern_uid).to eq('654321')
    end

693
    it 'updates user with new identity' do
blackst0ne's avatar
blackst0ne committed
694
      put api("/users/#{user.id}", admin), params: { provider: 'github', extern_uid: 'john' }
James Lopez's avatar
James Lopez committed
695

696
      expect(response).to have_gitlab_http_status(200)
697
      expect(user.reload.identities.first.extern_uid).to eq('john')
698 699 700
      expect(user.reload.identities.first.provider).to eq('github')
    end

701
    it "updates admin status" do
blackst0ne's avatar
blackst0ne committed
702
      put api("/users/#{user.id}", admin), params: { admin: true }
James Lopez's avatar
James Lopez committed
703

704
      expect(response).to have_gitlab_http_status(200)
705
      expect(user.reload.admin).to eq(true)
706 707
    end

708
    it "updates external status" do
blackst0ne's avatar
blackst0ne committed
709
      put api("/users/#{user.id}", admin), params: { external: true }
James Lopez's avatar
James Lopez committed
710

711 712 713 714 715
      expect(response.status).to eq 200
      expect(json_response['external']).to eq(true)
      expect(user.reload.external?).to be_truthy
    end

716
    it "updates private profile" do
blackst0ne's avatar
blackst0ne committed
717
      put api("/users/#{user.id}", admin), params: { private_profile: true }
718 719 720 721 722

      expect(response).to have_gitlab_http_status(200)
      expect(user.reload.private_profile).to eq(true)
    end

723
    # EE
724
    it "updates shared_runners_minutes_limit" do
725
      expect do
blackst0ne's avatar
blackst0ne committed
726
        put api("/users/#{user.id}", admin), params: { shared_runners_minutes_limit: 133 }
727 728
      end.to change { user.reload.shared_runners_minutes_limit }
        .from(nil).to(133)
729

730
      expect(response).to have_gitlab_http_status(200)
731
      expect(json_response['shared_runners_minutes_limit']).to eq(133)
732 733
    end

734
    it "does not update admin status" do
blackst0ne's avatar
blackst0ne committed
735
      put api("/users/#{admin_user.id}", admin), params: { can_create_group: false }
James Lopez's avatar
James Lopez committed
736

737
      expect(response).to have_gitlab_http_status(200)
738 739
      expect(admin_user.reload.admin).to eq(true)
      expect(admin_user.can_create_group).to eq(false)
740 741
    end

742
    it "does not allow invalid update" do
blackst0ne's avatar
blackst0ne committed
743
      put api("/users/#{user.id}", admin), params: { email: 'invalid email' }
James Lopez's avatar
James Lopez committed
744

745
      expect(response).to have_gitlab_http_status(400)
746
      expect(user.reload.email).not_to eq('invalid email')
747 748
    end

749 750
    context 'when the current user is not an admin' do
      it "is not available" do
751
        expect do
blackst0ne's avatar
blackst0ne committed
752
          put api("/users/#{user.id}", user), params: attributes_for(:user)
753 754
        end.not_to change { user.reload.attributes }

755
        expect(response).to have_gitlab_http_status(403)
756 757 758
      end

      it "cannot update their own shared_runners_minutes_limit" do
759
        expect do
blackst0ne's avatar
blackst0ne committed
760
          put api("/users/#{user.id}", user), params: { shared_runners_minutes_limit: 133 }
761 762
        end.not_to change { user.reload.shared_runners_minutes_limit }

763
        expect(response).to have_gitlab_http_status(403)
764
      end
765 766
    end

767
    it "returns 404 for non-existing user" do
blackst0ne's avatar
blackst0ne committed
768
      put api("/users/999999", admin), params: { bio: 'update should fail' }
James Lopez's avatar
James Lopez committed
769

770
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
771
      expect(json_response['message']).to eq('404 User Not Found')
772 773
    end

774
    it "returns a 404 if invalid ID" do
775 776
      put api("/users/ASDF", admin)

777
      expect(response).to have_gitlab_http_status(404)
778 779
    end

780
    it 'returns 400 error if user does not validate' do
781
      put api("/users/#{user.id}", admin),
blackst0ne's avatar
blackst0ne committed
782 783 784 785 786 787 788 789
          params: {
            password: 'pass',
            email: 'test@example.com',
            username: 'test!',
            name: 'test',
            bio: 'g' * 256,
            projects_limit: -1
          }
790
      expect(response).to have_gitlab_http_status(400)
791 792 793 794 795 796 797 798
      expect(json_response['message']['password'])
        .to eq(['is too short (minimum is 8 characters)'])
      expect(json_response['message']['bio'])
        .to eq(['is too long (maximum is 255 characters)'])
      expect(json_response['message']['projects_limit'])
        .to eq(['must be greater than or equal to 0'])
      expect(json_response['message']['username'])
        .to eq([Gitlab::PathRegex.namespace_format_message])
799
    end
800

Robert Schilling's avatar
Robert Schilling committed
801
    it 'returns 400 if provider is missing for identity update' do
blackst0ne's avatar
blackst0ne committed
802
      put api("/users/#{omniauth_user.id}", admin), params: { extern_uid: '654321' }
Robert Schilling's avatar
Robert Schilling committed
803

804
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
805 806 807
    end

    it 'returns 400 if external UID is missing for identity update' do
blackst0ne's avatar
blackst0ne committed
808
      put api("/users/#{omniauth_user.id}", admin), params: { provider: 'ldap' }
Robert Schilling's avatar
Robert Schilling committed
809

810
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
811 812
    end

813
    context "with existing user" do
814
      before do
blackst0ne's avatar
blackst0ne committed
815 816
        post api("/users", admin), params: { email: 'test@example.com', password: 'password', username: 'test', name: 'test' }
        post api("/users", admin), params: { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' }
817
        @user = User.all.last
818
      end
819

820
      it 'returns 409 conflict error if email address exists' do
blackst0ne's avatar
blackst0ne committed
821
        put api("/users/#{@user.id}", admin), params: { email: 'test@example.com' }
James Lopez's avatar
James Lopez committed
822

823
        expect(response).to have_gitlab_http_status(409)
824
        expect(@user.reload.email).to eq(@user.email)
825 826
      end

827
      it 'returns 409 conflict error if username taken' do
828
        @user_id = User.all.last.id
blackst0ne's avatar
blackst0ne committed
829
        put api("/users/#{@user.id}", admin), params: { username: 'test' }
James Lopez's avatar
James Lopez committed
830

831
        expect(response).to have_gitlab_http_status(409)
832
        expect(@user.reload.username).to eq(@user.username)
833
      end
834 835 836

      it 'returns 409 conflict error if username taken (case insensitive)' do
        @user_id = User.all.last.id
blackst0ne's avatar
blackst0ne committed
837
        put api("/users/#{@user.id}", admin), params: { username: 'TEST' }
838 839 840 841

        expect(response).to have_gitlab_http_status(409)
        expect(@user.reload.username).to eq(@user.username)
      end
842
    end
843 844
  end

Angus MacArthur's avatar
Angus MacArthur committed
845
  describe "POST /users/:id/keys" do
846 847 848
    before do
      admin
    end
Angus MacArthur's avatar
Angus MacArthur committed
849

850
    it "does not create invalid ssh key" do
blackst0ne's avatar
blackst0ne committed
851
      post api("/users/#{user.id}/keys", admin), params: { title: "invalid key" }
Robert Schilling's avatar
Robert Schilling committed
852

853
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
854
      expect(json_response['error']).to eq('key is missing')
855 856
    end

857
    it 'does not create key without title' do
blackst0ne's avatar
blackst0ne committed
858
      post api("/users/#{user.id}/keys", admin), params: { key: 'some key' }
Robert Schilling's avatar
Robert Schilling committed
859

860
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
861
      expect(json_response['error']).to eq('title is missing')
Angus MacArthur's avatar
Angus MacArthur committed
862 863
    end

864
    it "creates ssh key" do
Angus MacArthur's avatar
Angus MacArthur committed
865
      key_attrs = attributes_for :key
866
      expect do
blackst0ne's avatar
blackst0ne committed
867
        post api("/users/#{user.id}/keys", admin), params: key_attrs
868
      end.to change { user.keys.count }.by(1)
Angus MacArthur's avatar
Angus MacArthur committed
869
    end
870

Connor Shea's avatar
Connor Shea committed
871 872
    it "returns 400 for invalid ID" do
      post api("/users/999999/keys", admin)
873
      expect(response).to have_gitlab_http_status(400)
874
    end
Angus MacArthur's avatar
Angus MacArthur committed
875 876
  end

Robert Schilling's avatar
Robert Schilling committed
877
  describe 'GET /user/:id/keys' do
878 879
    it 'returns 404 for non-existing user' do
      user_id = not_existing_user_id
880

881
      get api("/users/#{user_id}/keys")
882

883 884 885
      expect(response).to have_gitlab_http_status(404)
      expect(json_response['message']).to eq('404 User Not Found')
    end
886

887 888 889
    it 'returns array of ssh keys' do
      user.keys << key
      user.save
890

891
      get api("/users/#{user.id}/keys")
892

893 894 895 896
      expect(response).to have_gitlab_http_status(200)
      expect(response).to include_pagination_headers
      expect(json_response).to be_an Array
      expect(json_response.first['title']).to eq(key.title)
897 898 899
    end
  end

Robert Schilling's avatar
Robert Schilling committed
900
  describe 'DELETE /user/:id/keys/:key_id' do
901 902 903
    before do
      admin
    end
904 905

    context 'when unauthenticated' do
906
      it 'returns authentication error' do
907
        delete api("/users/#{user.id}/keys/42")
908
        expect(response).to have_gitlab_http_status(401)
909 910 911 912
      end
    end

    context 'when authenticated' do
913
      it 'deletes existing key' do
914 915
        user.keys << key
        user.save
916

917
        expect do
918
          delete api("/users/#{user.id}/keys/#{key.id}", admin)
919

920
          expect(response).to have_gitlab_http_status(204)
921
        end.to change { user.keys.count }.by(-1)
922 923
      end

924 925 926 927
      it_behaves_like '412 response' do
        let(:request) { api("/users/#{user.id}/keys/#{key.id}", admin) }
      end

928
      it 'returns 404 error if user not found' do
929 930 931
        user.keys << key
        user.save
        delete api("/users/999999/keys/#{key.id}", admin)
932
        expect(response).to have_gitlab_http_status(404)
933
        expect(json_response['message']).to eq('404 User Not Found')
934 935
      end

936
      it 'returns 404 error if key not foud' do
937
        delete api("/users/#{user.id}/keys/42", admin)
938
        expect(response).to have_gitlab_http_status(404)
939
        expect(json_response['message']).to eq('404 Key Not Found')
940 941 942 943
      end
    end
  end

944 945 946 947 948 949 950 951
  describe 'POST /users/:id/keys' do
    before do
      admin
    end

    it 'does not create invalid GPG key' do
      post api("/users/#{user.id}/gpg_keys", admin)

952
      expect(response).to have_gitlab_http_status(400)
953 954 955 956 957 958
      expect(json_response['error']).to eq('key is missing')
    end

    it 'creates GPG key' do
      key_attrs = attributes_for :gpg_key
      expect do
blackst0ne's avatar
blackst0ne committed
959
        post api("/users/#{user.id}/gpg_keys", admin), params: key_attrs
960

961
        expect(response).to have_gitlab_http_status(201)
962 963 964 965 966 967
      end.to change { user.gpg_keys.count }.by(1)
    end

    it 'returns 400 for invalid ID' do
      post api('/users/999999/gpg_keys', admin)

968
      expect(response).to have_gitlab_http_status(400)
969 970 971 972 973 974 975 976 977 978 979 980
    end
  end

  describe 'GET /user/:id/gpg_keys' do
    before do
      admin
    end

    context 'when unauthenticated' do
      it 'returns authentication error' do
        get api("/users/#{user.id}/gpg_keys")

981
        expect(response).to have_gitlab_http_status(401)
982 983 984 985 986 987 988
      end
    end

    context 'when authenticated' do
      it 'returns 404 for non-existing user' do
        get api('/users/999999/gpg_keys', admin)

989
        expect(response).to have_gitlab_http_status(404)
990 991 992 993 994 995
        expect(json_response['message']).to eq('404 User Not Found')
      end

      it 'returns 404 error if key not foud' do
        delete api("/users/#{user.id}/gpg_keys/42", admin)

996
        expect(response).to have_gitlab_http_status(404)
997 998 999 1000 1001 1002 1003 1004 1005
        expect(json_response['message']).to eq('404 GPG Key Not Found')
      end

      it 'returns array of GPG keys' do
        user.gpg_keys << gpg_key
        user.save

        get api("/users/#{user.id}/gpg_keys", admin)

1006
        expect(response).to have_gitlab_http_status(200)
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.first['key']).to eq(gpg_key.key)
      end
    end
  end

  describe 'DELETE /user/:id/gpg_keys/:key_id' do
    before do
      admin
    end

    context 'when unauthenticated' do
      it 'returns authentication error' do
        delete api("/users/#{user.id}/keys/42")

1023
        expect(response).to have_gitlab_http_status(401)
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
      end
    end

    context 'when authenticated' do
      it 'deletes existing key' do
        user.gpg_keys << gpg_key
        user.save

        expect do
          delete api("/users/#{user.id}/gpg_keys/#{gpg_key.id}", admin)

1035
          expect(response).to have_gitlab_http_status(204)
1036 1037 1038 1039 1040 1041 1042 1043 1044
        end.to change { user.gpg_keys.count }.by(-1)
      end

      it 'returns 404 error if user not found' do
        user.keys << key
        user.save

        delete api("/users/999999/gpg_keys/#{gpg_key.id}", admin)

1045
        expect(response).to have_gitlab_http_status(404)
1046 1047 1048 1049 1050 1051
        expect(json_response['message']).to eq('404 User Not Found')
      end

      it 'returns 404 error if key not foud' do
        delete api("/users/#{user.id}/gpg_keys/42", admin)

1052
        expect(response).to have_gitlab_http_status(404)
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
        expect(json_response['message']).to eq('404 GPG Key Not Found')
      end
    end
  end

  describe 'POST /user/:id/gpg_keys/:key_id/revoke' do
    before do
      admin
    end

    context 'when unauthenticated' do
      it 'returns authentication error' do
        post api("/users/#{user.id}/gpg_keys/42/revoke")

1067
        expect(response).to have_gitlab_http_status(401)
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
      end
    end

    context 'when authenticated' do
      it 'revokes existing key' do
        user.gpg_keys << gpg_key
        user.save

        expect do
          post api("/users/#{user.id}/gpg_keys/#{gpg_key.id}/revoke", admin)

1079
          expect(response).to have_gitlab_http_status(:accepted)
1080 1081 1082 1083 1084 1085 1086 1087 1088
        end.to change { user.gpg_keys.count }.by(-1)
      end

      it 'returns 404 error if user not found' do
        user.gpg_keys << gpg_key
        user.save

        post api("/users/999999/gpg_keys/#{gpg_key.id}/revoke", admin)

1089
        expect(response).to have_gitlab_http_status(404)
1090 1091 1092 1093 1094 1095
        expect(json_response['message']).to eq('404 User Not Found')
      end

      it 'returns 404 error if key not foud' do
        post api("/users/#{user.id}/gpg_keys/42/revoke", admin)

1096
        expect(response).to have_gitlab_http_status(404)
1097 1098 1099 1100 1101
        expect(json_response['message']).to eq('404 GPG Key Not Found')
      end
    end
  end

1102
  describe "POST /users/:id/emails" do
1103 1104 1105
    before do
      admin
    end
1106

1107
    it "does not create invalid email" do
blackst0ne's avatar
blackst0ne committed
1108
      post api("/users/#{user.id}/emails", admin), params: {}
Robert Schilling's avatar
Robert Schilling committed
1109

1110
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
1111
      expect(json_response['error']).to eq('email is missing')
1112 1113
    end

1114
    it "creates unverified email" do
1115 1116
      email_attrs = attributes_for :email
      expect do
blackst0ne's avatar
blackst0ne committed
1117
        post api("/users/#{user.id}/emails", admin), params: email_attrs
1118
      end.to change { user.emails.count }.by(1)
1119 1120 1121

      email = Email.find_by(user_id: user.id, email: email_attrs[:email])
      expect(email).not_to be_confirmed
1122
    end
1123

1124
    it "returns a 400 for invalid ID" do
Connor Shea's avatar
Connor Shea committed
1125
      post api("/users/999999/emails", admin)
1126

1127
      expect(response).to have_gitlab_http_status(400)
1128
    end
1129 1130 1131 1132 1133

    it "creates verified email" do
      email_attrs = attributes_for :email
      email_attrs[:skip_confirmation] = true

blackst0ne's avatar
blackst0ne committed
1134
      post api("/users/#{user.id}/emails", admin), params: email_attrs
1135 1136 1137 1138 1139 1140

      expect(response).to have_gitlab_http_status(201)

      email = Email.find_by(user_id: user.id, email: email_attrs[:email])
      expect(email).to be_confirmed
    end
1141 1142
  end

Robert Schilling's avatar
Robert Schilling committed
1143
  describe 'GET /user/:id/emails' do
1144 1145 1146
    before do
      admin
    end
1147 1148

    context 'when unauthenticated' do
1149
      it 'returns authentication error' do
1150
        get api("/users/#{user.id}/emails")
1151
        expect(response).to have_gitlab_http_status(401)
1152 1153 1154 1155
      end
    end

    context 'when authenticated' do
1156
      it 'returns 404 for non-existing user' do
1157
        get api('/users/999999/emails', admin)
1158
        expect(response).to have_gitlab_http_status(404)
1159 1160 1161
        expect(json_response['message']).to eq('404 User Not Found')
      end

1162
      it 'returns array of emails' do
1163 1164
        user.emails << email
        user.save
1165

1166
        get api("/users/#{user.id}/emails", admin)
1167

1168
        expect(response).to have_gitlab_http_status(200)
1169
        expect(response).to include_pagination_headers
1170 1171 1172
        expect(json_response).to be_an Array
        expect(json_response.first['email']).to eq(email.email)
      end
1173

1174
      it "returns a 404 for invalid ID" do
1175
        get api("/users/ASDF/emails", admin)
1176

1177
        expect(response).to have_gitlab_http_status(404)
1178
      end
1179 1180 1181
    end
  end

Robert Schilling's avatar
Robert Schilling committed
1182
  describe 'DELETE /user/:id/emails/:email_id' do
1183 1184 1185
    before do
      admin
    end
1186 1187

    context 'when unauthenticated' do
1188
      it 'returns authentication error' do
1189
        delete api("/users/#{user.id}/emails/42")
1190
        expect(response).to have_gitlab_http_status(401)
1191 1192 1193 1194
      end
    end

    context 'when authenticated' do
1195
      it 'deletes existing email' do
1196 1197
        user.emails << email
        user.save
1198

1199 1200
        expect do
          delete api("/users/#{user.id}/emails/#{email.id}", admin)
1201

1202
          expect(response).to have_gitlab_http_status(204)
1203 1204 1205
        end.to change { user.emails.count }.by(-1)
      end

1206 1207 1208 1209
      it_behaves_like '412 response' do
        let(:request) { api("/users/#{user.id}/emails/#{email.id}", admin) }
      end

1210
      it 'returns 404 error if user not found' do
1211 1212 1213
        user.emails << email
        user.save
        delete api("/users/999999/emails/#{email.id}", admin)
1214
        expect(response).to have_gitlab_http_status(404)
1215 1216 1217
        expect(json_response['message']).to eq('404 User Not Found')
      end

1218
      it 'returns 404 error if email not foud' do
1219
        delete api("/users/#{user.id}/emails/42", admin)
1220
        expect(response).to have_gitlab_http_status(404)
1221 1222
        expect(json_response['message']).to eq('404 Email Not Found')
      end
1223

1224
      it "returns a 404 for invalid ID" do
1225 1226
        delete api("/users/ASDF/emails/bar", admin)

1227
        expect(response).to have_gitlab_http_status(404)
1228
      end
1229 1230 1231
    end
  end

1232
  describe "DELETE /users/:id" do
1233
    let!(:namespace) { user.namespace }
1234
    let!(:issue) { create(:issue, author: user) }
1235 1236 1237 1238

    before do
      admin
    end
1239

1240
    it "deletes user" do
1241
      perform_enqueued_jobs { delete api("/users/#{user.id}", admin) }
1242

1243
      expect(response).to have_gitlab_http_status(204)
1244
      expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound
1245
      expect { Namespace.find(namespace.id) }.to raise_error ActiveRecord::RecordNotFound
1246 1247
    end

1248 1249 1250 1251
    it_behaves_like '412 response' do
      let(:request) { api("/users/#{user.id}", admin) }
    end

1252
    it "does not delete for unauthenticated user" do
1253
      perform_enqueued_jobs { delete api("/users/#{user.id}") }
1254
      expect(response).to have_gitlab_http_status(401)
1255 1256
    end

1257
    it "is not available for non admin users" do
1258
      perform_enqueued_jobs { delete api("/users/#{user.id}", user) }
1259
      expect(response).to have_gitlab_http_status(403)
1260 1261
    end

1262
    it "returns 404 for non-existing user" do
1263
      perform_enqueued_jobs { delete api("/users/999999", admin) }
1264
      expect(response).to have_gitlab_http_status(404)
1265
      expect(json_response['message']).to eq('404 User Not Found')
1266
    end
1267

1268
    it "returns a 404 for invalid ID" do
1269
      perform_enqueued_jobs { delete api("/users/ASDF", admin) }
1270

1271
      expect(response).to have_gitlab_http_status(404)
1272
    end
1273 1274 1275

    context "hard delete disabled" do
      it "moves contributions to the ghost user" do
1276
        perform_enqueued_jobs { delete api("/users/#{user.id}", admin) }
1277

1278
        expect(response).to have_gitlab_http_status(204)
1279 1280 1281 1282 1283 1284 1285
        expect(issue.reload).to be_persisted
        expect(issue.author.ghost?).to be_truthy
      end
    end

    context "hard delete enabled" do
      it "removes contributions" do
1286
        perform_enqueued_jobs { delete api("/users/#{user.id}?hard_delete=true", admin) }
1287

1288
        expect(response).to have_gitlab_http_status(204)
1289 1290 1291
        expect(Issue.exists?(issue.id)).to be_falsy
      end
    end
1292 1293
  end

Nihad Abbasov's avatar
Nihad Abbasov committed
1294
  describe "GET /user" do
1295
    let(:personal_access_token) { create(:personal_access_token, user: user).token }
1296

1297 1298 1299 1300 1301
    shared_examples 'get user info' do |version|
      context 'with regular user' do
        context 'with personal access token' do
          it 'returns 403 without private token when sudo is defined' do
            get api("/user?private_token=#{personal_access_token}&sudo=123", version: version)
1302

1303 1304
            expect(response).to have_gitlab_http_status(403)
          end
1305 1306
        end

1307 1308
        it 'returns current user without private token when sudo not defined' do
          get api("/user", user, version: version)
1309

1310 1311 1312 1313
          expect(response).to have_gitlab_http_status(200)
          expect(response).to match_response_schema('public_api/v4/user/public')
          expect(json_response['id']).to eq(user.id)
        end
1314

1315 1316 1317
        context "scopes" do
          let(:path) { "/user" }
          let(:api_call) { method(:api) }
1318

1319 1320
          include_examples 'allows the "read_user" scope', version
        end
1321
      end
1322

1323 1324
      context 'with admin' do
        let(:admin_personal_access_token) { create(:personal_access_token, user: admin).token }
1325

1326 1327 1328
        context 'with personal access token' do
          it 'returns 403 without private token when sudo defined' do
            get api("/user?private_token=#{admin_personal_access_token}&sudo=#{user.id}", version: version)
1329

1330 1331
            expect(response).to have_gitlab_http_status(403)
          end
1332

1333 1334
          it 'returns initial current user without private token but with is_admin when sudo not defined' do
            get api("/user?private_token=#{admin_personal_access_token}", version: version)
1335

1336 1337 1338 1339
            expect(response).to have_gitlab_http_status(200)
            expect(response).to match_response_schema('public_api/v4/user/admin')
            expect(json_response['id']).to eq(admin.id)
          end
1340 1341 1342
        end
      end

1343 1344 1345
      context 'with unauthenticated user' do
        it "returns 401 error if user is unauthenticated" do
          get api("/user", version: version)
1346

1347 1348
          expect(response).to have_gitlab_http_status(401)
        end
1349
      end
1350
    end
1351 1352 1353

    it_behaves_like 'get user info', 'v3'
    it_behaves_like 'get user info', 'v4'
Nihad Abbasov's avatar
Nihad Abbasov committed
1354
  end
1355 1356 1357

  describe "GET /user/keys" do
    context "when unauthenticated" do
1358
      it "returns authentication error" do
1359
        get api("/user/keys")
1360
        expect(response).to have_gitlab_http_status(401)
1361 1362
      end
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
1363

1364
    context "when authenticated" do
1365
      it "returns array of ssh keys" do
1366 1367
        user.keys << key
        user.save
1368

1369
        get api("/user/keys", user)
1370

1371
        expect(response).to have_gitlab_http_status(200)
1372
        expect(response).to include_pagination_headers
1373 1374
        expect(json_response).to be_an Array
        expect(json_response.first["title"]).to eq(key.title)
1375
      end
1376 1377 1378 1379 1380 1381 1382

      context "scopes" do
        let(:path) { "/user/keys" }
        let(:api_call) { method(:api) }

        include_examples 'allows the "read_user" scope'
      end
1383 1384 1385
    end
  end

Robert Schilling's avatar
Robert Schilling committed
1386
  describe "GET /user/keys/:key_id" do
1387
    it "returns single key" do
1388 1389 1390
      user.keys << key
      user.save
      get api("/user/keys/#{key.id}", user)
1391
      expect(response).to have_gitlab_http_status(200)
1392
      expect(json_response["title"]).to eq(key.title)
1393
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
1394

1395
    it "returns 404 Not Found within invalid ID" do
1396
      get api("/user/keys/42", user)
1397

1398
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
1399
      expect(json_response['message']).to eq('404 Key Not Found')
1400 1401
    end

1402
    it "returns 404 error if admin accesses user's ssh key" do
1403 1404 1405 1406
      user.keys << key
      user.save
      admin
      get api("/user/keys/#{key.id}", admin)
1407
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
1408
      expect(json_response['message']).to eq('404 Key Not Found')
1409
    end
1410

1411
    it "returns 404 for invalid ID" do
1412
      get api("/users/keys/ASDF", admin)
1413

1414
      expect(response).to have_gitlab_http_status(404)
1415
    end
1416 1417 1418 1419 1420 1421 1422

    context "scopes" do
      let(:path) { "/user/keys/#{key.id}" }
      let(:api_call) { method(:api) }

      include_examples 'allows the "read_user" scope'
    end
1423
  end
Nihad Abbasov's avatar
Nihad Abbasov committed
1424

1425
  describe "POST /user/keys" do
1426
    it "creates ssh key" do
1427
      key_attrs = attributes_for :key
1428
      expect do
blackst0ne's avatar
blackst0ne committed
1429
        post api("/user/keys", user), params: key_attrs
1430
      end.to change { user.keys.count }.by(1)
1431
      expect(response).to have_gitlab_http_status(201)
1432 1433
    end

1434
    it "returns a 401 error if unauthorized" do
blackst0ne's avatar
blackst0ne committed
1435
      post api("/user/keys"), params: { title: 'some title', key: 'some key' }
1436
      expect(response).to have_gitlab_http_status(401)
1437 1438
    end

1439
    it "does not create ssh key without key" do
blackst0ne's avatar
blackst0ne committed
1440
      post api("/user/keys", user), params: { title: 'title' }
Robert Schilling's avatar
Robert Schilling committed
1441

1442
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
1443
      expect(json_response['error']).to eq('key is missing')
1444 1445
    end

1446
    it 'does not create ssh key without title' do
blackst0ne's avatar
blackst0ne committed
1447
      post api('/user/keys', user), params: { key: 'some key' }
Robert Schilling's avatar
Robert Schilling committed
1448

1449
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
1450
      expect(json_response['error']).to eq('title is missing')
1451 1452
    end

1453
    it "does not create ssh key without title" do
blackst0ne's avatar
blackst0ne committed
1454
      post api("/user/keys", user), params: { key: "somekey" }
1455
      expect(response).to have_gitlab_http_status(400)
1456 1457 1458
    end
  end

Robert Schilling's avatar
Robert Schilling committed
1459
  describe "DELETE /user/keys/:key_id" do
1460
    it "deletes existed key" do
1461 1462
      user.keys << key
      user.save
1463

1464
      expect do
1465
        delete api("/user/keys/#{key.id}", user)
1466

1467
        expect(response).to have_gitlab_http_status(204)
1468
      end.to change { user.keys.count}.by(-1)
1469
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
1470

1471 1472 1473 1474
    it_behaves_like '412 response' do
      let(:request) { api("/user/keys/#{key.id}", user) }
    end

Robert Schilling's avatar
Robert Schilling committed
1475
    it "returns 404 if key ID not found" do
1476
      delete api("/user/keys/42", user)
Robert Schilling's avatar
Robert Schilling committed
1477

1478
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
1479
      expect(json_response['message']).to eq('404 Key Not Found')
1480 1481
    end

1482
    it "returns 401 error if unauthorized" do
1483 1484 1485
      user.keys << key
      user.save
      delete api("/user/keys/#{key.id}")
1486
      expect(response).to have_gitlab_http_status(401)
1487
    end
1488

1489
    it "returns a 404 for invalid ID" do
1490 1491
      delete api("/users/keys/ASDF", admin)

1492
      expect(response).to have_gitlab_http_status(404)
1493
    end
1494
  end
1495

1496 1497 1498 1499 1500
  describe 'GET /user/gpg_keys' do
    context 'when unauthenticated' do
      it 'returns authentication error' do
        get api('/user/gpg_keys')

1501
        expect(response).to have_gitlab_http_status(401)
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
      end
    end

    context 'when authenticated' do
      it 'returns array of GPG keys' do
        user.gpg_keys << gpg_key
        user.save

        get api('/user/gpg_keys', user)

1512
        expect(response).to have_gitlab_http_status(200)
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.first['key']).to eq(gpg_key.key)
      end

      context 'scopes' do
        let(:path) { '/user/gpg_keys' }
        let(:api_call) { method(:api) }

        include_examples 'allows the "read_user" scope'
      end
    end
  end

  describe 'GET /user/gpg_keys/:key_id' do
    it 'returns a single key' do
      user.gpg_keys << gpg_key
      user.save

      get api("/user/gpg_keys/#{gpg_key.id}", user)

1534
      expect(response).to have_gitlab_http_status(200)
1535 1536 1537 1538 1539 1540
      expect(json_response['key']).to eq(gpg_key.key)
    end

    it 'returns 404 Not Found within invalid ID' do
      get api('/user/gpg_keys/42', user)

1541
      expect(response).to have_gitlab_http_status(404)
1542 1543 1544 1545 1546 1547 1548 1549 1550
      expect(json_response['message']).to eq('404 GPG Key Not Found')
    end

    it "returns 404 error if admin accesses user's GPG key" do
      user.gpg_keys << gpg_key
      user.save

      get api("/user/gpg_keys/#{gpg_key.id}", admin)

1551
      expect(response).to have_gitlab_http_status(404)
1552 1553 1554 1555 1556 1557
      expect(json_response['message']).to eq('404 GPG Key Not Found')
    end

    it 'returns 404 for invalid ID' do
      get api('/users/gpg_keys/ASDF', admin)

1558
      expect(response).to have_gitlab_http_status(404)
1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572
    end

    context 'scopes' do
      let(:path) { "/user/gpg_keys/#{gpg_key.id}" }
      let(:api_call) { method(:api) }

      include_examples 'allows the "read_user" scope'
    end
  end

  describe 'POST /user/gpg_keys' do
    it 'creates a GPG key' do
      key_attrs = attributes_for :gpg_key
      expect do
blackst0ne's avatar
blackst0ne committed
1573
        post api('/user/gpg_keys', user), params: key_attrs
1574

1575
        expect(response).to have_gitlab_http_status(201)
1576 1577 1578 1579
      end.to change { user.gpg_keys.count }.by(1)
    end

    it 'returns a 401 error if unauthorized' do
blackst0ne's avatar
blackst0ne committed
1580
      post api('/user/gpg_keys'), params: { key: 'some key' }
1581

1582
      expect(response).to have_gitlab_http_status(401)
1583 1584 1585 1586 1587
    end

    it 'does not create GPG key without key' do
      post api('/user/gpg_keys', user)

1588
      expect(response).to have_gitlab_http_status(400)
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600
      expect(json_response['error']).to eq('key is missing')
    end
  end

  describe 'POST /user/gpg_keys/:key_id/revoke' do
    it 'revokes existing GPG key' do
      user.gpg_keys << gpg_key
      user.save

      expect do
        post api("/user/gpg_keys/#{gpg_key.id}/revoke", user)

1601
        expect(response).to have_gitlab_http_status(:accepted)
1602 1603 1604 1605 1606 1607
      end.to change { user.gpg_keys.count}.by(-1)
    end

    it 'returns 404 if key ID not found' do
      post api('/user/gpg_keys/42/revoke', user)

1608
      expect(response).to have_gitlab_http_status(404)
1609 1610 1611 1612 1613 1614 1615 1616 1617
      expect(json_response['message']).to eq('404 GPG Key Not Found')
    end

    it 'returns 401 error if unauthorized' do
      user.gpg_keys << gpg_key
      user.save

      post api("/user/gpg_keys/#{gpg_key.id}/revoke")

1618
      expect(response).to have_gitlab_http_status(401)
1619 1620 1621 1622 1623
    end

    it 'returns a 404 for invalid ID' do
      post api('/users/gpg_keys/ASDF/revoke', admin)

1624
      expect(response).to have_gitlab_http_status(404)
1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635
    end
  end

  describe 'DELETE /user/gpg_keys/:key_id' do
    it 'deletes existing GPG key' do
      user.gpg_keys << gpg_key
      user.save

      expect do
        delete api("/user/gpg_keys/#{gpg_key.id}", user)

1636
        expect(response).to have_gitlab_http_status(204)
1637 1638 1639 1640 1641 1642
      end.to change { user.gpg_keys.count}.by(-1)
    end

    it 'returns 404 if key ID not found' do
      delete api('/user/gpg_keys/42', user)

1643
      expect(response).to have_gitlab_http_status(404)
1644 1645 1646 1647 1648 1649 1650 1651 1652
      expect(json_response['message']).to eq('404 GPG Key Not Found')
    end

    it 'returns 401 error if unauthorized' do
      user.gpg_keys << gpg_key
      user.save

      delete api("/user/gpg_keys/#{gpg_key.id}")

1653
      expect(response).to have_gitlab_http_status(401)
1654 1655 1656 1657 1658
    end

    it 'returns a 404 for invalid ID' do
      delete api('/users/gpg_keys/ASDF', admin)

1659
      expect(response).to have_gitlab_http_status(404)
1660 1661 1662
    end
  end

1663 1664
  describe "GET /user/emails" do
    context "when unauthenticated" do
1665
      it "returns authentication error" do
1666
        get api("/user/emails")
1667
        expect(response).to have_gitlab_http_status(401)
1668 1669 1670 1671
      end
    end

    context "when authenticated" do
1672
      it "returns array of emails" do
1673 1674
        user.emails << email
        user.save
1675

1676
        get api("/user/emails", user)
1677

1678
        expect(response).to have_gitlab_http_status(200)
1679
        expect(response).to include_pagination_headers
1680 1681 1682
        expect(json_response).to be_an Array
        expect(json_response.first["email"]).to eq(email.email)
      end
1683 1684 1685 1686 1687 1688 1689

      context "scopes" do
        let(:path) { "/user/emails" }
        let(:api_call) { method(:api) }

        include_examples 'allows the "read_user" scope'
      end
1690 1691 1692
    end
  end

Robert Schilling's avatar
Robert Schilling committed
1693
  describe "GET /user/emails/:email_id" do
1694
    it "returns single email" do
1695 1696 1697
      user.emails << email
      user.save
      get api("/user/emails/#{email.id}", user)
1698
      expect(response).to have_gitlab_http_status(200)
1699 1700 1701
      expect(json_response["email"]).to eq(email.email)
    end

1702
    it "returns 404 Not Found within invalid ID" do
1703
      get api("/user/emails/42", user)
1704
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
1705
      expect(json_response['message']).to eq('404 Email Not Found')
1706 1707
    end

1708
    it "returns 404 error if admin accesses user's email" do
1709 1710 1711 1712
      user.emails << email
      user.save
      admin
      get api("/user/emails/#{email.id}", admin)
1713
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
1714
      expect(json_response['message']).to eq('404 Email Not Found')
1715
    end
1716

1717
    it "returns 404 for invalid ID" do
1718
      get api("/users/emails/ASDF", admin)
1719

1720
      expect(response).to have_gitlab_http_status(404)
1721
    end
1722 1723 1724 1725 1726 1727 1728

    context "scopes" do
      let(:path) { "/user/emails/#{email.id}" }
      let(:api_call) { method(:api) }

      include_examples 'allows the "read_user" scope'
    end
1729 1730 1731
  end

  describe "POST /user/emails" do
1732
    it "creates email" do
1733 1734
      email_attrs = attributes_for :email
      expect do
blackst0ne's avatar
blackst0ne committed
1735
        post api("/user/emails", user), params: email_attrs
1736
      end.to change { user.emails.count }.by(1)
1737
      expect(response).to have_gitlab_http_status(201)
1738 1739
    end

1740
    it "returns a 401 error if unauthorized" do
blackst0ne's avatar
blackst0ne committed
1741
      post api("/user/emails"), params: { email: 'some email' }
1742
      expect(response).to have_gitlab_http_status(401)
1743 1744
    end

1745
    it "does not create email with invalid email" do
blackst0ne's avatar
blackst0ne committed
1746
      post api("/user/emails", user), params: {}
Robert Schilling's avatar
Robert Schilling committed
1747

1748
      expect(response).to have_gitlab_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
1749
      expect(json_response['error']).to eq('email is missing')
1750 1751 1752
    end
  end

Robert Schilling's avatar
Robert Schilling committed
1753
  describe "DELETE /user/emails/:email_id" do
1754
    it "deletes existed email" do
1755 1756
      user.emails << email
      user.save
1757

1758 1759
      expect do
        delete api("/user/emails/#{email.id}", user)
1760

1761
        expect(response).to have_gitlab_http_status(204)
1762
      end.to change { user.emails.count}.by(-1)
1763 1764
    end

1765 1766 1767 1768
    it_behaves_like '412 response' do
      let(:request) { api("/user/emails/#{email.id}", user) }
    end

Robert Schilling's avatar
Robert Schilling committed
1769
    it "returns 404 if email ID not found" do
1770
      delete api("/user/emails/42", user)
Robert Schilling's avatar
Robert Schilling committed
1771

1772
      expect(response).to have_gitlab_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
1773
      expect(json_response['message']).to eq('404 Email Not Found')
1774 1775
    end

1776
    it "returns 401 error if unauthorized" do
1777 1778 1779
      user.emails << email
      user.save
      delete api("/user/emails/#{email.id}")
1780
      expect(response).to have_gitlab_http_status(401)
1781
    end
1782

Robert Schilling's avatar
Robert Schilling committed
1783 1784
    it "returns 400 for invalid ID" do
      delete api("/user/emails/ASDF", admin)
1785

1786
      expect(response).to have_gitlab_http_status(400)
1787
    end
1788 1789
  end

1790
  describe 'POST /users/:id/block' do
1791 1792 1793 1794
    before do
      admin
    end

1795
    it 'blocks existing user' do
1796
      post api("/users/#{user.id}/block", admin)
1797
      expect(response).to have_gitlab_http_status(201)
1798 1799 1800
      expect(user.reload.state).to eq('blocked')
    end

1801
    it 'does not re-block ldap blocked users' do
1802
      post api("/users/#{ldap_blocked_user.id}/block", admin)
1803
      expect(response).to have_gitlab_http_status(403)
1804 1805 1806
      expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
    end

1807
    it 'does not be available for non admin users' do
1808
      post api("/users/#{user.id}/block", user)
1809
      expect(response).to have_gitlab_http_status(403)
1810 1811 1812
      expect(user.reload.state).to eq('active')
    end

1813
    it 'returns a 404 error if user id not found' do
1814
      post api('/users/9999/block', admin)
1815
      expect(response).to have_gitlab_http_status(404)
1816 1817 1818 1819
      expect(json_response['message']).to eq('404 User Not Found')
    end
  end

1820
  describe 'POST /users/:id/unblock' do
1821
    let(:blocked_user) { create(:user, state: 'blocked') }
1822 1823 1824 1825

    before do
      admin
    end
1826

1827
    it 'unblocks existing user' do
1828
      post api("/users/#{user.id}/unblock", admin)
1829
      expect(response).to have_gitlab_http_status(201)
1830 1831 1832
      expect(user.reload.state).to eq('active')
    end

1833
    it 'unblocks a blocked user' do
1834
      post api("/users/#{blocked_user.id}/unblock", admin)
1835
      expect(response).to have_gitlab_http_status(201)
1836 1837 1838
      expect(blocked_user.reload.state).to eq('active')
    end

1839
    it 'does not unblock ldap blocked users' do
1840
      post api("/users/#{ldap_blocked_user.id}/unblock", admin)
1841
      expect(response).to have_gitlab_http_status(403)
1842
      expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
1843 1844
    end

1845
    it 'does not be available for non admin users' do
1846
      post api("/users/#{user.id}/unblock", user)
1847
      expect(response).to have_gitlab_http_status(403)
1848 1849 1850
      expect(user.reload.state).to eq('active')
    end

1851
    it 'returns a 404 error if user id not found' do
1852
      post api('/users/9999/block', admin)
1853
      expect(response).to have_gitlab_http_status(404)
1854 1855
      expect(json_response['message']).to eq('404 User Not Found')
    end
1856

1857
    it "returns a 404 for invalid ID" do
1858
      post api("/users/ASDF/block", admin)
1859

1860
      expect(response).to have_gitlab_http_status(404)
1861
    end
1862
  end
1863

1864
  context "user activities", :clean_gitlab_redis_shared_state do
1865 1866 1867
    let!(:old_active_user) { create(:user, last_activity_on: Time.utc(2000, 1, 1)) }
    let!(:newly_active_user) { create(:user, last_activity_on: 2.days.ago.midday) }

1868 1869 1870 1871
    context 'last activity as normal user' do
      it 'has no permission' do
        get api("/user/activities", user)

1872
        expect(response).to have_gitlab_http_status(403)
1873 1874 1875
      end
    end

1876 1877
    context 'as admin' do
      it 'returns the activities from the last 6 months' do
1878
        get api("/user/activities", admin)
James Lopez's avatar
James Lopez committed
1879

1880
        expect(response).to include_pagination_headers
1881
        expect(json_response.size).to eq(1)
1882

1883
        activity = json_response.last
1884

1885 1886 1887
        expect(activity['username']).to eq(newly_active_user.username)
        expect(activity['last_activity_on']).to eq(2.days.ago.to_date.to_s)
        expect(activity['last_activity_at']).to eq(2.days.ago.to_date.to_s)
1888 1889
      end

1890 1891 1892
      context 'passing a :from parameter' do
        it 'returns the activities from the given date' do
          get api("/user/activities?from=2000-1-1", admin)
1893

1894 1895
          expect(response).to include_pagination_headers
          expect(json_response.size).to eq(2)
1896

1897
          activity = json_response.first
James Lopez's avatar
James Lopez committed
1898

1899 1900 1901 1902
          expect(activity['username']).to eq(old_active_user.username)
          expect(activity['last_activity_on']).to eq(Time.utc(2000, 1, 1).to_date.to_s)
          expect(activity['last_activity_at']).to eq(Time.utc(2000, 1, 1).to_date.to_s)
        end
James Lopez's avatar
James Lopez committed
1903
      end
Nick Thomas's avatar
Nick Thomas committed
1904 1905 1906
    end
  end

1907 1908 1909 1910 1911 1912 1913
  describe 'GET /user/status' do
    let(:path) { '/user/status' }
    it_behaves_like 'rendering user status'
  end

  describe 'PUT /user/status' do
    it 'saves the status' do
blackst0ne's avatar
blackst0ne committed
1914
      put api('/user/status', user), params: { emoji: 'smirk', message: 'hello world' }
1915 1916 1917 1918 1919 1920

      expect(response).to have_gitlab_http_status(:success)
      expect(json_response['emoji']).to eq('smirk')
    end

    it 'renders errors when the status was invalid' do
blackst0ne's avatar
blackst0ne committed
1921
      put api('/user/status', user), params: { emoji: 'does not exist', message: 'hello world' }
1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934

      expect(response).to have_gitlab_http_status(400)
      expect(json_response['message']['emoji']).to be_present
    end

    it 'deletes the status when passing empty values' do
      put api('/user/status', user)

      expect(response).to have_gitlab_http_status(:success)
      expect(user.reload.status).to be_nil
    end
  end

1935
  describe 'GET /users/:user_id/impersonation_tokens' do
1936
    let!(:active_personal_access_token) { create(:personal_access_token, user: user) }
1937 1938 1939 1940
    let!(:revoked_personal_access_token) { create(:personal_access_token, :revoked, user: user) }
    let!(:expired_personal_access_token) { create(:personal_access_token, :expired, user: user) }
    let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
    let!(:revoked_impersonation_token) { create(:personal_access_token, :impersonation, :revoked, user: user) }
1941 1942

    it 'returns a 404 error if user not found' do
1943
      get api("/users/#{not_existing_user_id}/impersonation_tokens", admin)
1944

1945
      expect(response).to have_gitlab_http_status(404)
1946 1947 1948 1949
      expect(json_response['message']).to eq('404 User Not Found')
    end

    it 'returns a 403 error when authenticated as normal user' do
1950
      get api("/users/#{not_existing_user_id}/impersonation_tokens", user)
1951

1952
      expect(response).to have_gitlab_http_status(403)
1953 1954 1955
      expect(json_response['message']).to eq('403 Forbidden')
    end

1956 1957
    it 'returns an array of all impersonated tokens' do
      get api("/users/#{user.id}/impersonation_tokens", admin)
1958

1959
      expect(response).to have_gitlab_http_status(200)
1960
      expect(response).to include_pagination_headers
1961
      expect(json_response).to be_an Array
1962
      expect(json_response.size).to eq(2)
1963 1964
    end

1965 1966
    it 'returns an array of active impersonation tokens if state active' do
      get api("/users/#{user.id}/impersonation_tokens?state=active", admin)
1967

1968
      expect(response).to have_gitlab_http_status(200)
1969
      expect(response).to include_pagination_headers
1970
      expect(json_response).to be_an Array
1971
      expect(json_response.size).to eq(1)
1972 1973 1974 1975
      expect(json_response).to all(include('active' => true))
    end

    it 'returns an array of inactive personal access tokens if active is set to false' do
1976
      get api("/users/#{user.id}/impersonation_tokens?state=inactive", admin)
1977

1978
      expect(response).to have_gitlab_http_status(200)
1979
      expect(json_response).to be_an Array
1980
      expect(json_response.size).to eq(1)
1981 1982 1983 1984
      expect(json_response).to all(include('active' => false))
    end
  end

1985
  describe 'POST /users/:user_id/impersonation_tokens' do
1986 1987
    let(:name) { 'my new pat' }
    let(:expires_at) { '2016-12-28' }
1988
    let(:scopes) { %w(api read_user) }
Simon Vocella's avatar
Simon Vocella committed
1989
    let(:impersonation) { true }
1990

1991 1992
    it 'returns validation error if impersonation token misses some attributes' do
      post api("/users/#{user.id}/impersonation_tokens", admin)
1993

1994
      expect(response).to have_gitlab_http_status(400)
1995 1996 1997 1998
      expect(json_response['error']).to eq('name is missing')
    end

    it 'returns a 404 error if user not found' do
1999
      post api("/users/#{not_existing_user_id}/impersonation_tokens", admin),
blackst0ne's avatar
blackst0ne committed
2000 2001 2002 2003
        params: {
          name: name,
          expires_at: expires_at
        }
2004

2005
      expect(response).to have_gitlab_http_status(404)
2006 2007 2008 2009
      expect(json_response['message']).to eq('404 User Not Found')
    end

    it 'returns a 403 error when authenticated as normal user' do
2010
      post api("/users/#{user.id}/impersonation_tokens", user),
blackst0ne's avatar
blackst0ne committed
2011 2012 2013 2014
        params: {
          name: name,
          expires_at: expires_at
        }
2015

2016
      expect(response).to have_gitlab_http_status(403)
2017 2018 2019
      expect(json_response['message']).to eq('403 Forbidden')
    end

2020 2021
    it 'creates a impersonation token' do
      post api("/users/#{user.id}/impersonation_tokens", admin),
blackst0ne's avatar
blackst0ne committed
2022 2023 2024 2025 2026 2027
        params: {
          name: name,
          expires_at: expires_at,
          scopes: scopes,
          impersonation: impersonation
        }
2028

2029
      expect(response).to have_gitlab_http_status(201)
2030 2031 2032 2033 2034
      expect(json_response['name']).to eq(name)
      expect(json_response['scopes']).to eq(scopes)
      expect(json_response['expires_at']).to eq(expires_at)
      expect(json_response['id']).to be_present
      expect(json_response['created_at']).to be_present
2035 2036
      expect(json_response['active']).to be_falsey
      expect(json_response['revoked']).to be_falsey
2037
      expect(json_response['token']).to be_present
Simon Vocella's avatar
Simon Vocella committed
2038
      expect(json_response['impersonation']).to eq(impersonation)
2039 2040 2041
    end
  end

2042 2043 2044
  describe 'GET /users/:user_id/impersonation_tokens/:impersonation_token_id' do
    let!(:personal_access_token) { create(:personal_access_token, user: user) }
    let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
2045 2046

    it 'returns 404 error if user not found' do
2047
      get api("/users/#{not_existing_user_id}/impersonation_tokens/1", admin)
2048

2049
      expect(response).to have_gitlab_http_status(404)
2050 2051 2052
      expect(json_response['message']).to eq('404 User Not Found')
    end

2053 2054
    it 'returns a 404 error if impersonation token not found' do
      get api("/users/#{user.id}/impersonation_tokens/#{not_existing_pat_id}", admin)
2055

2056
      expect(response).to have_gitlab_http_status(404)
2057 2058 2059 2060 2061 2062
      expect(json_response['message']).to eq('404 Impersonation Token Not Found')
    end

    it 'returns a 404 error if token is not impersonation token' do
      get api("/users/#{user.id}/impersonation_tokens/#{personal_access_token.id}", admin)

2063
      expect(response).to have_gitlab_http_status(404)
2064
      expect(json_response['message']).to eq('404 Impersonation Token Not Found')
2065 2066 2067
    end

    it 'returns a 403 error when authenticated as normal user' do
2068
      get api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", user)
2069

2070
      expect(response).to have_gitlab_http_status(403)
2071 2072 2073
      expect(json_response['message']).to eq('403 Forbidden')
    end

2074
    it 'returns an impersonation token' do
2075
      get api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", admin)
2076

2077
      expect(response).to have_gitlab_http_status(200)
2078
      expect(json_response['token']).not_to be_present
2079
      expect(json_response['impersonation']).to be_truthy
2080 2081 2082
    end
  end

2083 2084 2085
  describe 'DELETE /users/:user_id/impersonation_tokens/:impersonation_token_id' do
    let!(:personal_access_token) { create(:personal_access_token, user: user) }
    let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
2086 2087

    it 'returns a 404 error if user not found' do
2088
      delete api("/users/#{not_existing_user_id}/impersonation_tokens/1", admin)
2089

2090
      expect(response).to have_gitlab_http_status(404)
2091 2092 2093
      expect(json_response['message']).to eq('404 User Not Found')
    end

2094 2095 2096
    it 'returns a 404 error if impersonation token not found' do
      delete api("/users/#{user.id}/impersonation_tokens/#{not_existing_pat_id}", admin)

2097
      expect(response).to have_gitlab_http_status(404)
2098 2099 2100 2101 2102
      expect(json_response['message']).to eq('404 Impersonation Token Not Found')
    end

    it 'returns a 404 error if token is not impersonation token' do
      delete api("/users/#{user.id}/impersonation_tokens/#{personal_access_token.id}", admin)
2103

2104
      expect(response).to have_gitlab_http_status(404)
2105
      expect(json_response['message']).to eq('404 Impersonation Token Not Found')
2106 2107 2108
    end

    it 'returns a 403 error when authenticated as normal user' do
2109
      delete api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", user)
2110

2111
      expect(response).to have_gitlab_http_status(403)
2112 2113 2114
      expect(json_response['message']).to eq('403 Forbidden')
    end

2115 2116 2117 2118
    it_behaves_like '412 response' do
      let(:request) { api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", admin) }
    end

2119 2120
    it 'revokes a impersonation token' do
      delete api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", admin)
2121

2122
      expect(response).to have_gitlab_http_status(204)
2123 2124
      expect(impersonation_token.revoked).to be_falsey
      expect(impersonation_token.reload.revoked).to be_truthy
James Lopez's avatar
James Lopez committed
2125 2126
    end
  end
2127

2128
  it_behaves_like 'custom attributes endpoints', 'users' do
2129
    let(:attributable) { user }
2130
    let(:other_attributable) { admin }
2131
  end
Nihad Abbasov's avatar
Nihad Abbasov committed
2132
end