diff options
author | James Edwards-Jones <jedwardsjones@gitlab.com> | 2018-04-18 15:03:27 +0100 |
---|---|---|
committer | James Edwards-Jones <jedwardsjones@gitlab.com> | 2018-04-22 23:50:55 +0100 |
commit | f10c999bca2b5b37b068ff3680a6e35a6707828d (patch) | |
tree | a517f86544c1544ee25d174652a003fff9b199a0 /spec | |
parent | c212908aad9b32352653dfe9ca966f148c8dfc1a (diff) | |
download | gitlab-ce-f10c999bca2b5b37b068ff3680a6e35a6707828d.tar.gz |
Refactor OmniauthCallbacksController to remove duplication
Moves LDAP to its own controller with tests
Provides path forward for implementing GroupSaml
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/ldap/omniauth_callbacks_controller_spec.rb | 58 | ||||
-rw-r--r-- | spec/features/oauth_login_spec.rb | 49 | ||||
-rw-r--r-- | spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb | 42 | ||||
-rw-r--r-- | spec/lib/gitlab/auth/saml/identity_linker_spec.rb | 48 | ||||
-rw-r--r-- | spec/support/controllers/ldap_omniauth_callbacks_controller_shared_context.rb | 33 | ||||
-rw-r--r-- | spec/support/ldap_helpers.rb | 4 | ||||
-rw-r--r-- | spec/support/login_helpers.rb | 4 |
7 files changed, 215 insertions, 23 deletions
diff --git a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb new file mode 100644 index 00000000000..87c10a86cdd --- /dev/null +++ b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe Ldap::OmniauthCallbacksController do + include_context 'Ldap::OmniauthCallbacksController' + + it 'allows sign in' do + post provider + + expect(request.env['warden']).to be_authenticated + end + + it 'respects remember me checkbox' do + expect do + post provider, remember_me: '1' + end.to change { user.reload.remember_created_at }.from(nil) + end + + context 'with 2FA' do + let(:user) { create(:omniauth_user, :two_factor_via_otp, extern_uid: uid, provider: provider) } + + it 'passes remember_me to the Devise view' do + post provider, remember_me: '1' + + expect(assigns[:user].remember_me).to eq '1' + end + end + + context 'access denied' do + let(:valid_login?) { false } + + it 'warns the user' do + post provider + + expect(flash[:alert]).to match(/Access denied for your LDAP account*/) + end + + it "doesn't authenticate user" do + post provider + + expect(request.env['warden']).not_to be_authenticated + expect(response).to redirect_to(new_user_session_path) + end + end + + context 'sign up' do + let(:user) { double(email: 'new@example.com') } + + before do + stub_omniauth_setting(block_auto_created_users: false) + end + + it 'is allowed' do + post provider + + expect(request.env['warden']).to be_authenticated + end + end +end diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb index a5e325ee2e3..013cdaa6479 100644 --- a/spec/features/oauth_login_spec.rb +++ b/spec/features/oauth_login_spec.rb @@ -28,35 +28,46 @@ feature 'OAuth Login', :js, :allow_forgery_protection do OmniAuth.config.full_host = @omniauth_config_full_host end + def login_with_provider(provider, enter_two_factor: false) + login_via(provider.to_s, user, uid, remember_me: remember_me) + enter_code(user.current_otp) if enter_two_factor + end + providers.each do |provider| context "when the user logs in using the #{provider} provider" do + let(:uid) { 'my-uid' } + let(:remember_me) { false } + let(:user) { create(:omniauth_user, extern_uid: uid, provider: provider.to_s) } + let(:two_factor_user) { create(:omniauth_user, :two_factor, extern_uid: uid, provider: provider.to_s) } + + before do + stub_omniauth_config(provider) + end + context 'when two-factor authentication is disabled' do it 'logs the user in' do - stub_omniauth_config(provider) - user = create(:omniauth_user, extern_uid: 'my-uid', provider: provider.to_s) - login_via(provider.to_s, user, 'my-uid') + login_with_provider(provider) expect(current_path).to eq root_path end end context 'when two-factor authentication is enabled' do + let(:user) { two_factor_user } + it 'logs the user in' do - stub_omniauth_config(provider) - user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: provider.to_s) - login_via(provider.to_s, user, 'my-uid') + login_with_provider(provider, enter_two_factor: true) - enter_code(user.current_otp) expect(current_path).to eq root_path end end context 'when "remember me" is checked' do + let(:remember_me) { true } + context 'when two-factor authentication is disabled' do it 'remembers the user after a browser restart' do - stub_omniauth_config(provider) - user = create(:omniauth_user, extern_uid: 'my-uid', provider: provider.to_s) - login_via(provider.to_s, user, 'my-uid', remember_me: true) + login_with_provider(provider) clear_browser_session @@ -66,11 +77,10 @@ feature 'OAuth Login', :js, :allow_forgery_protection do end context 'when two-factor authentication is enabled' do + let(:user) { two_factor_user } + it 'remembers the user after a browser restart' do - stub_omniauth_config(provider) - user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: provider.to_s) - login_via(provider.to_s, user, 'my-uid', remember_me: true) - enter_code(user.current_otp) + login_with_provider(provider, enter_two_factor: true) clear_browser_session @@ -83,9 +93,7 @@ feature 'OAuth Login', :js, :allow_forgery_protection do context 'when "remember me" is not checked' do context 'when two-factor authentication is disabled' do it 'does not remember the user after a browser restart' do - stub_omniauth_config(provider) - user = create(:omniauth_user, extern_uid: 'my-uid', provider: provider.to_s) - login_via(provider.to_s, user, 'my-uid', remember_me: false) + login_with_provider(provider) clear_browser_session @@ -95,11 +103,10 @@ feature 'OAuth Login', :js, :allow_forgery_protection do end context 'when two-factor authentication is enabled' do + let(:user) { two_factor_user } + it 'does not remember the user after a browser restart' do - stub_omniauth_config(provider) - user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: provider.to_s) - login_via(provider.to_s, user, 'my-uid', remember_me: false) - enter_code(user.current_otp) + login_with_provider(provider, enter_two_factor: true) clear_browser_session diff --git a/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb b/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb new file mode 100644 index 00000000000..dc6aa5de53a --- /dev/null +++ b/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe Gitlab::Auth::OAuth::IdentityLinker do + let(:user) { create(:user) } + let(:provider) { 'twitter' } + let(:uid) { user.email } + let(:oauth) { { 'provider' => provider, 'uid' => uid } } + + subject { described_class.new(user, oauth) } + + context 'linked identity exists' do + let!(:identity) { user.identities.create!(provider: provider, extern_uid: uid) } + + it "doesn't create new identity" do + expect { subject.create_or_update }.not_to change { Identity.count } + end + end + + context 'identity needs to be created' do + it 'creates linked identity' do + expect { subject.create_or_update }.to change { user.identities.count } + end + + it 'sets identity provider' do + subject.create_or_update + + expect(user.identities.last.provider).to eq provider + end + + it 'sets identity extern_uid' do + subject.create_or_update + + expect(user.identities.last.extern_uid).to eq uid + end + + it 'sets #created? to true' do + subject.create_or_update + + expect(subject).to be_created + end + end +end diff --git a/spec/lib/gitlab/auth/saml/identity_linker_spec.rb b/spec/lib/gitlab/auth/saml/identity_linker_spec.rb new file mode 100644 index 00000000000..11e8469e9f4 --- /dev/null +++ b/spec/lib/gitlab/auth/saml/identity_linker_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe Gitlab::Auth::Saml::IdentityLinker do + let(:user) { create(:user) } + let(:provider) { 'saml' } + let(:uid) { user.email } + let(:oauth) { { 'provider' => provider, 'uid' => uid } } + + subject { described_class.new(user, oauth) } + + context 'linked identity exists' do + let!(:identity) { user.identities.create!(provider: provider, extern_uid: uid) } + + it "doesn't create new identity" do + expect { subject.create_or_update }.not_to change { Identity.count } + end + + it 'sets #created? to false' do + subject.create_or_update + + expect(subject).not_to be_created + end + end + + context 'identity needs to be created' do + it 'creates linked identity' do + expect { subject.create_or_update }.to change { user.identities.count } + end + + it 'sets identity provider' do + subject.create_or_update + + expect(user.identities.last.provider).to eq provider + end + + it 'sets identity extern_uid' do + subject.create_or_update + + expect(user.identities.last.extern_uid).to eq uid + end + + it 'sets #created? to true' do + subject.create_or_update + + expect(subject).to be_created + end + end +end diff --git a/spec/support/controllers/ldap_omniauth_callbacks_controller_shared_context.rb b/spec/support/controllers/ldap_omniauth_callbacks_controller_shared_context.rb new file mode 100644 index 00000000000..72912ffb89d --- /dev/null +++ b/spec/support/controllers/ldap_omniauth_callbacks_controller_shared_context.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +shared_context 'Ldap::OmniauthCallbacksController' do + include LoginHelpers + include LdapHelpers + + let(:uid) { 'my-uid' } + let(:provider) { 'ldapmain' } + let(:valid_login?) { true } + let(:user) { create(:omniauth_user, extern_uid: uid, provider: provider) } + let(:ldap_server_config) do + { main: ldap_config_defaults(:main) } + end + + def ldap_config_defaults(key, hash = {}) + { + provider_name: "ldap#{key}", + attributes: {}, + encryption: 'plain' + }.merge(hash) + end + + before do + stub_ldap_setting(enabled: true, servers: ldap_server_config) + described_class.define_providers! + Rails.application.reload_routes! + + mock_auth_hash(provider.to_s, uid, user.email) + stub_omniauth_provider(provider, context: request) + + allow(Gitlab::Auth::LDAP::Access).to receive(:allowed?).and_return(valid_login?) + end +end diff --git a/spec/support/ldap_helpers.rb b/spec/support/ldap_helpers.rb index 0e87b3d359d..b90bbc4b106 100644 --- a/spec/support/ldap_helpers.rb +++ b/spec/support/ldap_helpers.rb @@ -18,6 +18,10 @@ module LdapHelpers allow_any_instance_of(::Gitlab::Auth::LDAP::Config).to receive_messages(messages) end + def stub_ldap_setting(messages) + allow(Gitlab.config.ldap).to receive_messages(to_settings(messages)) + end + # Stub an LDAP person search and provide the return entry. Specify `nil` for # `entry` to simulate when an LDAP person is not found # diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index db34090e971..72e5c2d66dd 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -112,7 +112,7 @@ module LoginHelpers } } }) - Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[:saml] + Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[provider.to_sym] end def mock_saml_config @@ -129,7 +129,7 @@ module LoginHelpers env = env_from_context(context) set_devise_mapping(context: context) - env['omniauth.auth'] = OmniAuth.config.mock_auth[provider] + env['omniauth.auth'] = OmniAuth.config.mock_auth[provider.to_sym] end def stub_omniauth_saml_config(messages) |