omniauth_callbacks_controller_spec.rb 5.0 KB
Newer Older
1 2
require 'spec_helper'

3
describe OmniauthCallbacksController, type: :controller do
4 5
  include LoginHelpers

6 7
  describe 'omniauth' do
    let(:user) { create(:omniauth_user, extern_uid: extern_uid, provider: provider) }
8

T
Tiago Botelho 已提交
9
    before do
10 11
      mock_auth_hash(provider.to_s, extern_uid, user.email)
      stub_omniauth_provider(provider, context: request)
12
    end
13

14 15
    context 'when the user is on the last sign in attempt' do
      let(:extern_uid) { 'my-uid' }
16

17 18 19
      before do
        user.update(failed_attempts: User.maximum_attempts.pred)
        subject.response = ActionDispatch::Response.new
20
      end
21

22 23
      context 'when using a form based provider' do
        let(:provider) { :ldap }
24

25 26 27
        it 'locks the user when sign in fails' do
          allow(subject).to receive(:params).and_return(ActionController::Parameters.new(username: user.username))
          request.env['omniauth.error.strategy'] = OmniAuth::Strategies::LDAP.new(nil)
28

29
          subject.send(:failure)
T
Tiago Botelho 已提交
30

31 32
          expect(user.reload).to be_access_locked
        end
33
      end
34

35 36
      context 'when using a button based provider' do
        let(:provider) { :github }
37

38 39
        it 'does not lock the user when sign in fails' do
          request.env['omniauth.error.strategy'] = OmniAuth::Strategies::GitHub.new(nil)
40

41
          subject.send(:failure)
42

43
          expect(user.reload).not_to be_access_locked
T
Tiago Botelho 已提交
44
        end
45
      end
46
    end
47

48 49 50 51
    context 'strategies' do
      context 'github' do
        let(:extern_uid) { 'my-uid' }
        let(:provider) { :github }
T
Tiago Botelho 已提交
52

53
        it 'allows sign in' do
T
Tiago Botelho 已提交
54
          post provider
55

T
Tiago Botelho 已提交
56 57
          expect(request.env['warden']).to be_authenticated
        end
58

59 60
        shared_context 'sign_up' do
          let(:user) { double(email: 'new@example.com') }
61

62 63 64
          before do
            stub_omniauth_setting(block_auto_created_users: false)
          end
65
        end
T
Tiago Botelho 已提交
66

67 68
        context 'sign up' do
          include_context 'sign_up'
T
Tiago Botelho 已提交
69

70 71
          it 'is allowed' do
            post provider
T
Tiago Botelho 已提交
72

73 74
            expect(request.env['warden']).to be_authenticated
          end
T
Tiago Botelho 已提交
75 76
        end

77 78 79 80 81 82
        context 'when OAuth is disabled' do
          before do
            stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
            settings = Gitlab::CurrentSettings.current_application_settings
            settings.update(disabled_oauth_sign_in_sources: [provider.to_s])
          end
T
Tiago Botelho 已提交
83

84
          it 'prevents login via POST' do
T
Tiago Botelho 已提交
85 86 87 88
            post provider

            expect(request.env['warden']).not_to be_authenticated
          end
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

          it 'shows warning when attempting login' do
            post provider

            expect(response).to redirect_to new_user_session_path
            expect(flash[:alert]).to eq('Signing in using GitHub has been disabled')
          end

          it 'allows linking the disabled provider' do
            user.identities.destroy_all
            sign_in(user)

            expect { post provider }.to change { user.reload.identities.count }.by(1)
          end

          context 'sign up' do
            include_context 'sign_up'

            it 'is prevented' do
              post provider

              expect(request.env['warden']).not_to be_authenticated
            end
          end
        end
      end

      context 'auth0' do
        let(:extern_uid) { '' }
        let(:provider) { :auth0 }

        it 'does not allow sign in without extern_uid' do
          post 'auth0'

          expect(request.env['warden']).not_to be_authenticated
          expect(response.status).to eq(302)
          expect(controller).to set_flash[:alert].to('Wrong extern UID provided. Make sure Auth0 is configured correctly.')
T
Tiago Botelho 已提交
126
        end
127 128
      end
    end
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  end

  describe '#saml' do
    let(:user) { create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: 'saml') }
    let(:mock_saml_response) { File.read('spec/fixtures/authentication/saml_response.xml') }
    let(:saml_config) { mock_saml_config_with_upstream_two_factor_authn_contexts }

    before do
      stub_omniauth_saml_config({ enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'],
                                  providers: [saml_config] })
      mock_auth_hash('saml', 'my-uid', user.email, mock_saml_response)
      request.env["devise.mapping"] = Devise.mappings[:user]
      request.env['omniauth.auth'] = Rails.application.env_config['omniauth.auth']
      post :saml, params: { SAMLResponse: mock_saml_response }
    end
144

145 146 147 148 149
    context 'when worth two factors' do
      let(:mock_saml_response) do
        File.read('spec/fixtures/authentication/saml_response.xml')
            .gsub('urn:oasis:names:tc:SAML:2.0:ac:classes:Password', 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN')
      end
150

151 152 153 154
      it 'expects user to be signed_in' do
        expect(request.env['warden']).to be_authenticated
      end
    end
155

156 157 158
    context 'when not worth two factors' do
      it 'expects user to provide second factor' do
        expect(response).to render_template('devise/sessions/two_factor')
T
Tiago Botelho 已提交
159 160
        expect(request.env['warden']).not_to be_authenticated
      end
161 162
    end
  end
163
end