user_spec.rb 12.8 KB
Newer Older
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
1 2
require 'spec_helper'

Douwe Maan's avatar
Douwe Maan committed
3
describe Gitlab::OAuth::User, lib: true do
4 5 6 7
  let(:oauth_user) { Gitlab::OAuth::User.new(auth_hash) }
  let(:gl_user) { oauth_user.gl_user }
  let(:uid) { 'my-uid' }
  let(:provider) { 'my-provider' }
8
  let(:auth_hash) { OmniAuth::AuthHash.new(uid: uid, provider: provider, info: info_hash) }
9 10
  let(:info_hash) do
    {
11
      nickname: '-john+gitlab-ETC%.git@gmail.com',
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
12 13
      name: 'John',
      email: 'john@mail.com'
14
    }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
15
  end
16
  let(:ldap_user) { Gitlab::LDAP::Person.new(Net::LDAP::Entry.new, 'ldapmain') }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
17

18
  describe '#persisted?' do
19
    let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') }
20 21

    it "finds an existing user based on uid and provider (facebook)" do
22
      expect( oauth_user.persisted? ).to be_truthy
23 24
    end

25
    it 'returns false if user is not found in database' do
26
      allow(auth_hash).to receive(:uid).and_return('non-existing')
27
      expect( oauth_user.persisted? ).to be_falsey
28 29 30
    end
  end

31
  describe '#save' do
32 33 34 35 36 37 38 39
    def stub_omniauth_config(messages)
      allow(Gitlab.config.omniauth).to receive_messages(messages)
    end

    def stub_ldap_config(messages)
      allow(Gitlab::LDAP::Config).to receive_messages(messages)
    end

40
    let(:provider) { 'twitter' }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
41

42
    describe 'signup' do
43 44 45 46 47 48 49 50 51 52 53 54 55 56
      context 'when signup is disabled' do
        before do
          stub_application_setting signup_enabled: false
        end

        it 'creates the user' do
          stub_omniauth_config(allow_single_sign_on: ['twitter'])

          oauth_user.save

          expect(gl_user).to be_persisted
        end
      end

57 58 59 60 61 62 63 64 65
      it 'marks user as having password_automatically_set' do
        stub_omniauth_config(allow_single_sign_on: ['twitter'], external_providers: ['twitter'])

        oauth_user.save

        expect(gl_user).to be_persisted
        expect(gl_user).to be_password_automatically_set
      end

66 67
      shared_examples 'to verify compliance with allow_single_sign_on' do
        context 'provider is marked as external' do
68
          it 'marks user as external' do
69 70 71 72 73 74 75 76
            stub_omniauth_config(allow_single_sign_on: ['twitter'], external_providers: ['twitter'])
            oauth_user.save
            expect(gl_user).to be_valid
            expect(gl_user.external).to be_truthy
          end
        end

        context 'provider was external, now has been removed' do
77
          it 'does not mark external user as internal' do
78 79 80 81
            create(:omniauth_user, extern_uid: 'my-uid', provider: 'twitter', external: true)
            stub_omniauth_config(allow_single_sign_on: ['twitter'], external_providers: ['facebook'])
            oauth_user.save
            expect(gl_user).to be_valid
82 83 84 85 86 87
            expect(gl_user.external).to be_truthy
          end
        end

        context 'provider is not external' do
          context 'when adding a new OAuth identity' do
88
            it 'does not promote an external user to internal' do
89 90 91 92 93 94 95
              user = create(:user, email: 'john@mail.com', external: true)
              user.identities.create(provider: provider, extern_uid: uid)

              oauth_user.save
              expect(gl_user).to be_valid
              expect(gl_user.external).to be_truthy
            end
96 97 98 99
          end
        end

        context 'with new allow_single_sign_on enabled syntax' do
100
          before { stub_omniauth_config(allow_single_sign_on: ['twitter']) }
101

102 103
          it "creates a user from Omniauth" do
            oauth_user.save
104

105 106 107 108 109 110 111
            expect(gl_user).to be_valid
            identity = gl_user.identities.first
            expect(identity.extern_uid).to eql uid
            expect(identity.provider).to eql 'twitter'
          end
        end

112 113 114 115 116 117 118 119 120 121 122 123 124
        context "with old allow_single_sign_on enabled syntax" do
          before { stub_omniauth_config(allow_single_sign_on: true) }

          it "creates a user from Omniauth" do
            oauth_user.save

            expect(gl_user).to be_valid
            identity = gl_user.identities.first
            expect(identity.extern_uid).to eql uid
            expect(identity.provider).to eql 'twitter'
          end
        end

125
        context 'with new allow_single_sign_on disabled syntax' do
126
          before { stub_omniauth_config(allow_single_sign_on: []) }
127
          it 'throws an error' do
128 129
            expect{ oauth_user.save }.to raise_error StandardError
          end
130
        end
131

132
        context 'with old allow_single_sign_on disabled (Default)' do
133
          before { stub_omniauth_config(allow_single_sign_on: false) }
134
          it 'throws an error' do
135 136 137
            expect{ oauth_user.save }.to raise_error StandardError
          end
        end
138
      end
139

140
      context "with auto_link_ldap_user disabled (default)" do
141
        before { stub_omniauth_config(auto_link_ldap_user: false) }
142 143 144 145
        include_examples "to verify compliance with allow_single_sign_on"
      end

      context "with auto_link_ldap_user enabled" do
146 147
        before { stub_omniauth_config(auto_link_ldap_user: true) }

148
        context "and no LDAP provider defined" do
149 150
          before { stub_ldap_config(providers: []) }

151 152
          include_examples "to verify compliance with allow_single_sign_on"
        end
153

154
        context "and at least one LDAP provider is defined" do
155
          before { stub_ldap_config(providers: %w(ldapmain)) }
156 157 158

          context "and a corresponding LDAP person" do
            before do
159 160
              allow(ldap_user).to receive(:uid) { uid }
              allow(ldap_user).to receive(:username) { uid }
161
              allow(ldap_user).to receive(:email) { ['johndoe@example.com', 'john2@example.com'] }
162
              allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' }
163
            end
164

165 166
            context "and no account for the LDAP user" do
              it "creates a user with dual LDAP and omniauth identities" do
167 168
                allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(ldap_user)

169
                oauth_user.save
170

171 172 173
                expect(gl_user).to be_valid
                expect(gl_user.username).to eql uid
                expect(gl_user.email).to eql 'johndoe@example.com'
174
                expect(gl_user.identities.length).to be 2
175 176
                identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } }
                expect(identities_as_hash).to match_array(
177 178 179 180 181
                  [
                    { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' },
                    { provider: 'twitter', extern_uid: uid }
                  ]
                )
182 183
              end
            end
184

185 186 187
            context "and LDAP user has an account already" do
              let!(:existing_user) { create(:omniauth_user, email: 'john@example.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'ldapmain', username: 'john') }
              it "adds the omniauth identity to the LDAP account" do
188 189
                allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(ldap_user)

190
                oauth_user.save
191

192 193 194
                expect(gl_user).to be_valid
                expect(gl_user.username).to eql 'john'
                expect(gl_user.email).to eql 'john@example.com'
195
                expect(gl_user.identities.length).to be 2
196 197
                identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } }
                expect(identities_as_hash).to match_array(
198 199 200 201 202
                  [
                    { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' },
                    { provider: 'twitter', extern_uid: uid }
                  ]
                )
203
              end
204
            end
205 206 207 208 209 210 211 212 213

            context 'when an LDAP person is not found by uid' do
              it 'tries to find an LDAP person by DN and adds the omniauth identity to the user' do
                allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(nil)
                allow(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(ldap_user)

                oauth_user.save

                identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } }
214 215
                expect(identities_as_hash)
                  .to match_array(
216 217 218 219 220 221 222
                    [
                      { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' },
                      { provider: 'twitter', extern_uid: uid }
                    ]
                  )
              end
            end
223
          end
224

225 226
          context "and no corresponding LDAP person" do
            before { allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(nil) }
227

228 229
            include_examples "to verify compliance with allow_single_sign_on"
          end
230
        end
231
      end
232
    end
233

234 235
    describe 'blocking' do
      let(:provider) { 'twitter' }
236
      before { stub_omniauth_config(allow_single_sign_on: ['twitter']) }
237

238
      context 'signup with omniauth only' do
239
        context 'dont block on create' do
240
          before { stub_omniauth_config(block_auto_created_users: false) }
241 242 243

          it do
            oauth_user.save
244 245
            expect(gl_user).to be_valid
            expect(gl_user).not_to be_blocked
246 247 248 249
          end
        end

        context 'block on create' do
250
          before { stub_omniauth_config(block_auto_created_users: true) }
251 252 253

          it do
            oauth_user.save
254 255
            expect(gl_user).to be_valid
            expect(gl_user).to be_blocked
256 257 258 259
          end
        end
      end

260 261
      context 'signup with linked omniauth and LDAP account' do
        before do
262 263 264
          stub_omniauth_config(auto_link_ldap_user: true)
          allow(ldap_user).to receive(:uid) { uid }
          allow(ldap_user).to receive(:username) { uid }
265
          allow(ldap_user).to receive(:email) { ['johndoe@example.com', 'john2@example.com'] }
266
          allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' }
267 268 269 270 271
          allow(oauth_user).to receive(:ldap_person).and_return(ldap_user)
        end

        context "and no account for the LDAP user" do
          context 'dont block on create (LDAP)' do
272
            before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) }
273 274 275 276 277 278 279 280 281

            it do
              oauth_user.save
              expect(gl_user).to be_valid
              expect(gl_user).not_to be_blocked
            end
          end

          context 'block on create (LDAP)' do
282
            before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) }
283 284 285 286 287 288 289 290 291 292 293 294 295

            it do
              oauth_user.save
              expect(gl_user).to be_valid
              expect(gl_user).to be_blocked
            end
          end
        end

        context 'and LDAP user has an account already' do
          let!(:existing_user) { create(:omniauth_user, email: 'john@example.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'ldapmain', username: 'john') }

          context 'dont block on create (LDAP)' do
296
            before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) }
297 298 299 300 301 302 303 304 305

            it do
              oauth_user.save
              expect(gl_user).to be_valid
              expect(gl_user).not_to be_blocked
            end
          end

          context 'block on create (LDAP)' do
306
            before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) }
307 308 309 310 311 312 313 314 315 316

            it do
              oauth_user.save
              expect(gl_user).to be_valid
              expect(gl_user).not_to be_blocked
            end
          end
        end
      end

317 318 319 320 321 322 323
      context 'sign-in' do
        before do
          oauth_user.save
          oauth_user.gl_user.activate
        end

        context 'dont block on create' do
324
          before { stub_omniauth_config(block_auto_created_users: false) }
325 326 327

          it do
            oauth_user.save
328 329
            expect(gl_user).to be_valid
            expect(gl_user).not_to be_blocked
330 331 332 333
          end
        end

        context 'block on create' do
334
          before { stub_omniauth_config(block_auto_created_users: true) }
335 336 337

          it do
            oauth_user.save
338 339
            expect(gl_user).to be_valid
            expect(gl_user).not_to be_blocked
340 341
          end
        end
342 343

        context 'dont block on create (LDAP)' do
344
          before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) }
345 346 347 348 349 350 351 352 353

          it do
            oauth_user.save
            expect(gl_user).to be_valid
            expect(gl_user).not_to be_blocked
          end
        end

        context 'block on create (LDAP)' do
354
          before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) }
355 356 357 358 359 360 361

          it do
            oauth_user.save
            expect(gl_user).to be_valid
            expect(gl_user).not_to be_blocked
          end
        end
362 363
      end
    end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
364 365
  end
end