2019-07-25 01:24:42 -04:00
# frozen_string_literal: true
2015-05-05 22:16:45 -04:00
require 'spec_helper'
2021-09-16 14:11:32 -04:00
RSpec . describe 'Login' , :clean_gitlab_redis_shared_state do
2018-04-27 10:50:33 -04:00
include TermsHelper
2018-11-12 16:40:42 -05:00
include UserLoginHelper
2021-09-16 14:11:32 -04:00
include SessionHelpers
2018-04-27 10:50:33 -04:00
2018-07-20 09:06:11 -04:00
before do
2018-07-23 09:13:11 -04:00
stub_authentication_activity_metrics ( debug : true )
2018-07-20 09:06:11 -04:00
end
2018-07-23 09:13:11 -04:00
describe 'password reset token after successful sign in' do
it 'invalidates password reset token' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2018-02-22 06:44:14 -05:00
2018-07-23 09:13:11 -04:00
user = create ( :user )
2018-02-22 06:44:14 -05:00
2018-07-23 09:13:11 -04:00
expect ( user . reset_password_token ) . to be_nil
2018-02-22 06:44:14 -05:00
2018-07-23 09:13:11 -04:00
visit new_user_password_path
fill_in 'user_email' , with : user . email
click_button 'Reset password'
2018-02-22 06:44:14 -05:00
2018-07-23 09:13:11 -04:00
user . reload
expect ( user . reset_password_token ) . not_to be_nil
2018-02-22 06:44:14 -05:00
2018-07-23 09:13:11 -04:00
gitlab_sign_in ( user )
expect ( current_path ) . to eq root_path
user . reload
expect ( user . reset_password_token ) . to be_nil
end
2018-02-22 06:44:14 -05:00
end
2016-03-02 17:48:49 -05:00
describe 'initial login after setup' do
it 'allows the initial admin to create a password' do
2018-07-23 09:13:11 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2016-03-02 17:48:49 -05:00
# This behavior is dependent on there only being one user
User . delete_all
user = create ( :admin , password_automatically_set : true )
visit root_path
expect ( current_path ) . to eq edit_user_password_path
expect ( page ) . to have_content ( 'Please create a password for your new account.' )
fill_in 'user_password' , with : 'password'
fill_in 'user_password_confirmation' , with : 'password'
click_button 'Change your password'
expect ( current_path ) . to eq new_user_session_path
expect ( page ) . to have_content ( I18n . t ( 'devise.passwords.updated_not_active' ) )
fill_in 'user_login' , with : user . username
fill_in 'user_password' , with : 'password'
click_button 'Sign in'
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2016-03-02 17:48:49 -05:00
expect ( current_path ) . to eq root_path
end
2017-01-28 21:22:13 -05:00
it 'does not show flash messages when login page' do
visit root_path
expect ( page ) . not_to have_content ( 'You need to sign in or sign up before continuing.' )
end
2016-03-02 17:48:49 -05:00
end
2017-02-01 13:21:28 -05:00
describe 'with a blocked account' do
it 'prevents the user from logging in' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_blocked_counter )
. and increment ( :user_unauthenticated_counter )
. and increment ( :user_session_destroyed_counter ) . twice
2018-07-23 09:13:11 -04:00
2017-02-01 13:21:28 -05:00
user = create ( :user , :blocked )
2017-06-05 14:51:54 -04:00
gitlab_sign_in ( user )
2017-02-01 13:21:28 -05:00
expect ( page ) . to have_content ( 'Your account has been blocked.' )
end
2017-07-10 23:35:47 -04:00
it 'does not update Devise trackable attributes' , :clean_gitlab_redis_shared_state do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_blocked_counter )
. and increment ( :user_unauthenticated_counter )
. and increment ( :user_session_destroyed_counter ) . twice
2017-02-01 13:21:28 -05:00
user = create ( :user , :blocked )
2017-06-05 14:51:54 -04:00
expect { gitlab_sign_in ( user ) } . not_to change { user . reload . sign_in_count }
2017-02-01 13:21:28 -05:00
end
end
2019-08-14 17:33:39 -04:00
describe 'with an unconfirmed email address' do
let! ( :user ) { create ( :user , confirmed_at : nil ) }
let ( :grace_period ) { 2 . days }
2021-06-24 14:07:15 -04:00
let ( :alert_title ) { 'Please confirm your email address' }
let ( :alert_message ) { " To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select Resend confirmation email " }
2019-08-14 17:33:39 -04:00
before do
stub_application_setting ( send_user_confirmation_email : true )
allow ( User ) . to receive ( :allow_unconfirmed_access_for ) . and_return grace_period
end
context 'within the grace period' do
it 'allows to login' do
expect ( authentication_metrics ) . to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2021-06-24 14:07:15 -04:00
expect ( page ) . not_to have_content ( alert_title )
expect ( page ) . not_to have_content ( alert_message )
2019-08-14 17:33:39 -04:00
expect ( page ) . not_to have_link ( 'Resend confirmation email' , href : new_user_confirmation_path )
end
end
context 'when the confirmation grace period is expired' do
2021-06-24 14:07:15 -04:00
it 'prevents the user from logging in and renders a resend confirmation email link' , :js do
2019-08-14 17:33:39 -04:00
travel_to ( ( grace_period + 1 . day ) . from_now ) do
expect ( authentication_metrics )
. to increment ( :user_unauthenticated_counter )
. and increment ( :user_session_destroyed_counter ) . twice
gitlab_sign_in ( user )
2021-06-24 14:07:15 -04:00
expect ( page ) . to have_content ( alert_title )
expect ( page ) . to have_content ( alert_message )
2019-08-14 17:33:39 -04:00
expect ( page ) . to have_link ( 'Resend confirmation email' , href : new_user_confirmation_path )
end
end
end
2021-06-16 20:10:17 -04:00
context 'when resending the confirmation email' do
it 'redirects to the "almost there" page' do
stub_feature_flags ( soft_email_confirmation : false )
user = create ( :user )
visit new_user_confirmation_path
fill_in 'user_email' , with : user . email
click_button 'Resend'
expect ( current_path ) . to eq users_almost_there_path
end
end
2019-08-14 17:33:39 -04:00
end
2017-03-07 18:27:59 -05:00
describe 'with the ghost user' do
it 'disallows login' do
2018-07-23 09:13:11 -04:00
expect ( authentication_metrics )
. to increment ( :user_unauthenticated_counter )
2018-07-26 12:35:15 -04:00
. and increment ( :user_password_invalid_counter )
2018-07-23 09:13:11 -04:00
2017-06-05 14:51:54 -04:00
gitlab_sign_in ( User . ghost )
2017-03-07 18:27:59 -05:00
2021-03-17 17:11:29 -04:00
expect ( page ) . to have_content ( 'Invalid login or password.' )
2017-03-07 18:27:59 -05:00
end
2017-07-10 23:35:47 -04:00
it 'does not update Devise trackable attributes' , :clean_gitlab_redis_shared_state do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_unauthenticated_counter )
. and increment ( :user_password_invalid_counter )
expect { gitlab_sign_in ( User . ghost ) }
. not_to change { User . ghost . reload . sign_in_count }
2017-03-07 18:27:59 -05:00
end
end
2020-01-23 10:08:46 -05:00
describe 'with two-factor authentication' , :js do
2016-06-30 15:54:07 -04:00
def enter_code ( code )
2016-09-29 06:00:12 -04:00
fill_in 'user_otp_attempt' , with : code
2016-06-30 15:54:07 -04:00
click_button 'Verify code'
end
2015-05-05 22:16:45 -04:00
context 'with valid username/password' do
2015-05-09 15:46:18 -04:00
let ( :user ) { create ( :user , :two_factor ) }
2015-05-05 22:16:45 -04:00
before do
2017-06-05 14:51:54 -04:00
gitlab_sign_in ( user , remember : true )
2018-07-26 12:35:15 -04:00
2016-06-06 00:50:39 -04:00
expect ( page ) . to have_content ( 'Two-Factor Authentication' )
2015-05-05 22:16:45 -04:00
end
2015-05-09 17:04:02 -04:00
it 'does not show a "You are already signed in." error message' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2015-05-09 17:04:02 -04:00
enter_code ( user . current_otp )
2018-07-26 12:35:15 -04:00
2019-04-24 09:23:07 -04:00
expect ( page ) . not_to have_content ( I18n . t ( 'devise.failure.already_authenticated' ) )
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2015-05-09 17:04:02 -04:00
end
2020-09-02 11:10:54 -04:00
it 'does not allow sign-in if the user password is updated before entering a one-time code' do
user . update! ( password : 'new_password' )
enter_code ( user . current_otp )
expect ( page ) . to have_content ( 'An error occurred. Please sign in again.' )
end
2015-05-05 22:16:45 -04:00
context 'using one-time code' do
it 'allows login with valid code' do
2018-07-23 09:13:11 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2015-05-05 22:16:45 -04:00
enter_code ( user . current_otp )
2018-07-23 09:13:11 -04:00
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2015-05-05 22:16:45 -04:00
expect ( current_path ) . to eq root_path
end
2016-05-30 22:17:26 -04:00
it 'persists remember_me value via hidden field' do
field = first ( 'input#user_remember_me' , visible : false )
expect ( field . value ) . to eq '1'
end
2015-05-05 22:16:45 -04:00
it 'blocks login with invalid code' do
2018-07-26 12:35:15 -04:00
# TODO invalid 2FA code does not generate any events
2018-07-31 03:24:19 -04:00
# See gitlab-org/gitlab-ce#49785
2018-07-26 12:35:15 -04:00
2015-05-05 22:16:45 -04:00
enter_code ( 'foo' )
2018-07-26 12:35:15 -04:00
2015-05-05 22:16:45 -04:00
expect ( page ) . to have_content ( 'Invalid two-factor code' )
end
2015-05-08 20:41:53 -04:00
it 'allows login with invalid code, then valid code' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2015-05-08 20:41:53 -04:00
enter_code ( 'foo' )
expect ( page ) . to have_content ( 'Invalid two-factor code' )
enter_code ( user . current_otp )
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2015-05-08 20:41:53 -04:00
expect ( current_path ) . to eq root_path
end
2019-07-26 03:05:50 -04:00
it 'triggers ActiveSession.cleanup for the user' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
expect ( ActiveSession ) . to receive ( :cleanup ) . with ( user ) . once . and_call_original
enter_code ( user . current_otp )
end
2015-05-05 22:16:45 -04:00
end
context 'using backup code' do
let ( :codes ) { user . generate_otp_backup_codes! }
before do
2015-05-09 15:46:49 -04:00
expect ( codes . size ) . to eq 10
2015-05-05 22:16:45 -04:00
2015-05-09 15:45:22 -04:00
# Ensure the generated codes get saved
2021-03-31 08:08:55 -04:00
user . save! ( touch : false )
2015-05-05 22:16:45 -04:00
end
context 'with valid code' do
it 'allows login' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2015-05-05 22:16:45 -04:00
enter_code ( codes . sample )
2018-07-26 12:35:15 -04:00
2015-05-05 22:16:45 -04:00
expect ( current_path ) . to eq root_path
end
it 'invalidates the used code' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2017-06-21 09:48:12 -04:00
expect { enter_code ( codes . sample ) }
. to change { user . reload . otp_backup_codes . size } . by ( - 1 )
2015-05-05 22:16:45 -04:00
end
2018-02-09 10:02:11 -05:00
it 'invalidates backup codes twice in a row' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter ) . twice
. and increment ( :user_two_factor_authenticated_counter ) . twice
. and increment ( :user_session_destroyed_counter )
2018-02-09 10:02:11 -05:00
random_code = codes . delete ( codes . sample )
expect { enter_code ( random_code ) }
. to change { user . reload . otp_backup_codes . size } . by ( - 1 )
gitlab_sign_out
gitlab_sign_in ( user )
expect { enter_code ( codes . sample ) }
. to change { user . reload . otp_backup_codes . size } . by ( - 1 )
end
2019-07-26 03:05:50 -04:00
it 'triggers ActiveSession.cleanup for the user' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
expect ( ActiveSession ) . to receive ( :cleanup ) . with ( user ) . once . and_call_original
enter_code ( codes . sample )
end
2015-05-05 22:16:45 -04:00
end
context 'with invalid code' do
it 'blocks login' do
2018-07-26 12:35:15 -04:00
# TODO, invalid two factor authentication does not increment
2018-07-31 03:24:19 -04:00
# metrics / counters, see gitlab-org/gitlab-ce#49785
2018-07-26 12:35:15 -04:00
2015-05-05 22:16:45 -04:00
code = codes . sample
expect ( user . invalidate_otp_backup_code! ( code ) ) . to eq true
2015-05-09 15:45:22 -04:00
2020-09-02 11:10:54 -04:00
user . save! ( touch : false )
2015-05-09 15:46:49 -04:00
expect ( user . reload . otp_backup_codes . size ) . to eq 9
2015-05-05 22:16:45 -04:00
enter_code ( code )
2015-05-09 17:04:02 -04:00
expect ( page ) . to have_content ( 'Invalid two-factor code.' )
2015-05-05 22:16:45 -04:00
end
end
end
end
2016-06-30 15:54:07 -04:00
2018-07-26 12:35:15 -04:00
context 'when logging in via OAuth' do
2018-06-25 11:32:03 -04:00
let ( :user ) { create ( :omniauth_user , :two_factor , extern_uid : 'my-uid' , provider : 'saml' ) }
let ( :mock_saml_response ) do
File . read ( 'spec/fixtures/authentication/saml_response.xml' )
end
2016-06-30 15:54:07 -04:00
2018-06-25 11:32:03 -04:00
before do
stub_omniauth_saml_config ( enabled : true , auto_link_saml_user : true , allow_single_sign_on : [ 'saml' ] ,
providers : [ mock_saml_config_with_upstream_two_factor_authn_contexts ] )
end
context 'when authn_context is worth two factors' do
let ( :mock_saml_response ) do
File . read ( 'spec/fixtures/authentication/saml_response.xml' )
2018-07-26 12:35:15 -04:00
. gsub ( 'urn:oasis:names:tc:SAML:2.0:ac:classes:Password' ,
'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS' )
2018-06-25 11:32:03 -04:00
end
it 'signs user in without prompting for second factor' do
2018-07-31 03:24:19 -04:00
# TODO, OAuth authentication does not fire events,
# see gitlab-org/gitlab-ce#49786
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2019-07-26 03:05:50 -04:00
expect ( ActiveSession ) . to receive ( :cleanup ) . with ( user ) . once . and_call_original
2018-07-26 12:35:15 -04:00
sign_in_using_saml!
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2018-06-25 11:32:03 -04:00
expect ( page ) . not_to have_content ( 'Two-Factor Authentication' )
expect ( current_path ) . to eq root_path
end
end
2018-07-26 12:35:15 -04:00
context 'when two factor authentication is required' do
2018-06-25 11:32:03 -04:00
it 'shows 2FA prompt after OAuth login' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2019-07-26 03:05:50 -04:00
expect ( ActiveSession ) . to receive ( :cleanup ) . with ( user ) . once . and_call_original
2018-07-26 12:35:15 -04:00
sign_in_using_saml!
2018-06-25 11:32:03 -04:00
expect ( page ) . to have_content ( 'Two-Factor Authentication' )
2018-07-26 12:35:15 -04:00
2018-06-25 11:32:03 -04:00
enter_code ( user . current_otp )
2018-07-26 12:35:15 -04:00
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2018-06-25 11:32:03 -04:00
expect ( current_path ) . to eq root_path
end
2016-06-30 15:54:07 -04:00
end
2018-07-26 12:35:15 -04:00
def sign_in_using_saml!
gitlab_sign_in_via ( 'saml' , user , 'my-uid' , mock_saml_response )
end
2016-06-30 15:54:07 -04:00
end
2015-05-05 22:16:45 -04:00
end
2015-05-11 14:31:31 -04:00
describe 'without two-factor authentication' do
2018-07-26 12:35:15 -04:00
context 'with correct username and password' do
let ( :user ) { create ( :user ) }
2015-05-09 15:46:18 -04:00
2018-07-26 12:35:15 -04:00
it 'allows basic login' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2015-05-09 17:04:02 -04:00
2018-07-26 12:35:15 -04:00
gitlab_sign_in ( user )
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2018-07-26 12:35:15 -04:00
expect ( current_path ) . to eq root_path
2019-04-24 09:23:07 -04:00
expect ( page ) . not_to have_content ( I18n . t ( 'devise.failure.already_authenticated' ) )
end
it 'does not show already signed in message when opening sign in page after login' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
visit new_user_session_path
2021-09-16 14:11:32 -04:00
expect_single_session_with_authenticated_ttl
2019-04-24 09:23:07 -04:00
expect ( page ) . not_to have_content ( I18n . t ( 'devise.failure.already_authenticated' ) )
2018-07-26 12:35:15 -04:00
end
2019-07-26 03:05:50 -04:00
it 'triggers ActiveSession.cleanup for the user' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
expect ( ActiveSession ) . to receive ( :cleanup ) . with ( user ) . once . and_call_original
gitlab_sign_in ( user )
end
2021-06-01 17:10:06 -04:00
context 'when the users password is expired' do
before do
user . update! ( password_expires_at : Time . parse ( '2018-05-08 11:29:46 UTC' ) )
end
it 'asks for a new password' do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
visit new_user_session_path
fill_in 'user_login' , with : user . email
fill_in 'user_password' , with : '12345678'
click_button 'Sign in'
expect ( current_path ) . to eq ( new_profile_password_path )
end
end
2015-05-09 17:04:02 -04:00
end
2018-07-26 12:35:15 -04:00
context 'with invalid username and password' do
let ( :user ) { create ( :user , password : 'not-the-default' ) }
2015-05-09 17:04:02 -04:00
2018-07-26 12:35:15 -04:00
it 'blocks invalid login' do
expect ( authentication_metrics )
. to increment ( :user_unauthenticated_counter )
. and increment ( :user_password_invalid_counter )
gitlab_sign_in ( user )
2021-09-16 14:11:32 -04:00
expect_single_session_with_short_ttl
2021-03-17 17:11:29 -04:00
expect ( page ) . to have_content ( 'Invalid login or password.' )
2018-07-26 12:35:15 -04:00
end
2015-05-09 17:04:02 -04:00
end
2015-05-05 22:16:45 -04:00
end
2015-12-23 23:04:41 -05:00
describe 'with required two-factor authentication enabled' do
let ( :user ) { create ( :user ) }
2019-12-17 13:07:48 -05:00
2017-03-08 06:09:15 -05:00
# TODO: otp_grace_period_started_at
2015-12-23 23:04:41 -05:00
2017-03-08 06:09:15 -05:00
context 'global setting' do
2017-06-14 14:18:56 -04:00
before do
stub_application_setting ( require_two_factor_authentication : true )
end
2015-12-23 23:04:41 -05:00
2017-03-08 06:09:15 -05:00
context 'with grace period defined' do
2017-06-14 14:18:56 -04:00
before do
2017-03-08 06:09:15 -05:00
stub_application_setting ( two_factor_grace_period : 48 )
2015-12-23 23:04:41 -05:00
end
2017-03-08 06:09:15 -05:00
context 'within the grace period' do
it 'redirects to two-factor configuration page' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . to have_content ( 'The global settings require you to enable Two-Factor Authentication for your account. You need to do this before ' )
end
2015-12-23 23:04:41 -05:00
2017-10-03 04:35:01 -04:00
it 'allows skipping two-factor configuration' , :js do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2017-03-08 06:09:15 -05:00
2018-07-26 12:35:15 -04:00
gitlab_sign_in ( user )
expect ( current_path ) . to eq profile_two_factor_auth_path
2017-03-08 06:09:15 -05:00
click_link 'Configure it later'
expect ( current_path ) . to eq root_path
end
2015-12-23 23:04:41 -05:00
end
2017-03-08 06:09:15 -05:00
context 'after the grace period' do
let ( :user ) { create ( :user , otp_grace_period_started_at : 9999 . hours . ago ) }
2015-12-23 23:04:41 -05:00
2017-03-08 06:09:15 -05:00
it 'redirects to two-factor configuration page' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . to have_content (
'The global settings require you to enable Two-Factor Authentication for your account.'
)
end
2017-10-03 04:35:01 -04:00
it 'disallows skipping two-factor configuration' , :js do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . not_to have_link ( 'Configure it later' )
end
end
end
context 'without grace period defined' do
2017-06-14 14:18:56 -04:00
before do
2017-03-08 06:09:15 -05:00
stub_application_setting ( two_factor_grace_period : 0 )
2015-12-23 23:04:41 -05:00
end
2017-03-08 06:09:15 -05:00
it 'redirects to two-factor configuration page' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2016-06-06 00:50:39 -04:00
expect ( current_path ) . to eq profile_two_factor_auth_path
2017-03-08 06:09:15 -05:00
expect ( page ) . to have_content (
'The global settings require you to enable Two-Factor Authentication for your account.'
)
2015-12-23 23:04:41 -05:00
end
end
end
2017-03-08 06:09:15 -05:00
context 'group setting' do
before do
group1 = create :group , name : 'Group 1' , require_two_factor_authentication : true
group1 . add_user ( user , GroupMember :: DEVELOPER )
group2 = create :group , name : 'Group 2' , require_two_factor_authentication : true
group2 . add_user ( user , GroupMember :: DEVELOPER )
2015-12-23 23:04:41 -05:00
end
2017-03-08 06:09:15 -05:00
context 'with grace period defined' do
2017-06-14 14:18:56 -04:00
before do
2017-03-08 06:09:15 -05:00
stub_application_setting ( two_factor_grace_period : 48 )
end
context 'within the grace period' do
it 'redirects to two-factor configuration page' do
2020-08-31 11:10:41 -04:00
freeze_time do
2019-03-20 04:17:11 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . to have_content (
'The group settings for Group 1 and Group 2 require you to enable ' \
'Two-Factor Authentication for your account. ' \
'You can leave Group 1 and leave Group 2. ' \
'You need to do this ' \
'before ' \
2019-03-29 23:57:45 -04:00
" #{ ( Time . zone . now + 2 . days ) . strftime ( " %a, %d %b %Y %H:%M:%S %z " ) } "
2019-03-20 04:17:11 -04:00
)
end
2017-03-08 06:09:15 -05:00
end
2017-10-03 04:35:01 -04:00
it 'allows skipping two-factor configuration' , :js do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
2018-07-26 12:35:15 -04:00
expect ( current_path ) . to eq profile_two_factor_auth_path
2017-03-08 06:09:15 -05:00
click_link 'Configure it later'
expect ( current_path ) . to eq root_path
end
end
context 'after the grace period' do
let ( :user ) { create ( :user , otp_grace_period_started_at : 9999 . hours . ago ) }
it 'redirects to two-factor configuration page' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . to have_content (
'The group settings for Group 1 and Group 2 require you to enable ' \
'Two-Factor Authentication for your account.'
)
end
2017-10-03 04:35:01 -04:00
it 'disallows skipping two-factor configuration' , :js do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . not_to have_link ( 'Configure it later' )
end
end
end
context 'without grace period defined' do
2017-06-14 14:18:56 -04:00
before do
2017-03-08 06:09:15 -05:00
stub_application_setting ( two_factor_grace_period : 0 )
end
it 'redirects to two-factor configuration page' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
2017-03-08 06:09:15 -05:00
expect ( current_path ) . to eq profile_two_factor_auth_path
expect ( page ) . to have_content (
'The group settings for Group 1 and Group 2 require you to enable ' \
2019-03-20 04:17:11 -04:00
'Two-Factor Authentication for your account. ' \
'You can leave Group 1 and leave Group 2.'
2017-03-08 06:09:15 -05:00
)
end
2015-12-23 23:04:41 -05:00
end
end
end
2016-10-24 07:26:48 -04:00
describe 'UI tabs and panes' do
context 'when no defaults are changed' do
2020-11-02 22:08:56 -05:00
it 'does not render any tabs' do
visit new_user_session_path
ensure_no_tabs
end
it 'renders link to sign up path' do
2020-10-28 08:08:40 -04:00
visit new_user_session_path
2020-11-02 22:08:56 -05:00
expect ( page . body ) . to have_link ( 'Register now' , href : new_user_registration_path )
2016-10-24 07:26:48 -04:00
end
end
context 'when signup is disabled' do
before do
stub_application_setting ( signup_enabled : false )
2020-10-28 08:08:40 -04:00
visit new_user_session_path
2016-10-24 07:26:48 -04:00
end
2016-10-24 11:53:32 -04:00
2020-11-02 22:08:56 -05:00
it 'does not render any tabs' do
ensure_no_tabs
end
it 'does not render link to sign up path' do
visit new_user_session_path
expect ( page . body ) . not_to have_link ( 'Register now' , href : new_user_registration_path )
2016-10-24 07:26:48 -04:00
end
end
context 'when ldap is enabled' do
2020-10-28 08:08:40 -04:00
include LdapHelpers
let ( :provider ) { 'ldapmain' }
let ( :ldap_server_config ) do
{
'label' = > 'Main LDAP' ,
'provider_name' = > provider ,
'attributes' = > { } ,
'encryption' = > 'plain' ,
'uid' = > 'uid' ,
'base' = > 'dc=example,dc=com'
}
end
2016-10-24 07:26:48 -04:00
before do
2020-10-28 08:08:40 -04:00
stub_ldap_setting ( enabled : true )
allow ( :: Gitlab :: Auth :: Ldap :: Config ) . to receive_messages ( enabled : true , servers : [ ldap_server_config ] )
allow ( Gitlab :: Auth :: OAuth :: Provider ) . to receive_messages ( providers : [ provider . to_sym ] )
Ldap :: OmniauthCallbacksController . define_providers!
Rails . application . reload_routes!
allow_next_instance_of ( ActionDispatch :: Routing :: RoutesProxy ) do | instance |
allow ( instance ) . to receive ( :" user_ #{ provider } _omniauth_callback_path " )
. and_return ( " /users/auth/ #{ provider } /callback " )
end
2016-10-24 07:26:48 -04:00
visit new_user_session_path
end
2016-10-24 11:53:32 -04:00
it 'correctly renders tabs and panes' do
2020-11-02 22:08:56 -05:00
ensure_tab_pane_correctness ( [ 'Main LDAP' , 'Standard' ] )
end
it 'renders link to sign up path' do
expect ( page . body ) . to have_link ( 'Register now' , href : new_user_registration_path )
2016-10-24 07:26:48 -04:00
end
end
context 'when crowd is enabled' do
before do
2020-10-28 08:08:40 -04:00
allow ( Gitlab :: Auth :: OAuth :: Provider ) . to receive_messages ( providers : [ :crowd ] )
stub_application_setting ( crowd_enabled : true )
Ldap :: OmniauthCallbacksController . define_providers!
Rails . application . reload_routes!
allow_next_instance_of ( ActionDispatch :: Routing :: RoutesProxy ) do | instance |
allow ( instance ) . to receive ( :user_crowd_omniauth_authorize_path )
. and_return ( " /users/auth/crowd/callback " )
end
2016-10-24 07:26:48 -04:00
visit new_user_session_path
end
2016-10-24 11:53:32 -04:00
it 'correctly renders tabs and panes' do
2020-11-02 22:08:56 -05:00
ensure_tab_pane_correctness ( %w( Crowd Standard ) )
2016-10-24 07:26:48 -04:00
end
end
end
2018-04-27 10:50:33 -04:00
2019-09-02 03:14:13 -04:00
describe 'Client helper classes and flags' do
it 'adds client browser and platform classes to page body' do
visit root_path
expect ( find ( 'body' ) [ :class ] ) . to include ( 'gl-browser-generic' )
expect ( find ( 'body' ) [ :class ] ) . to include ( 'gl-platform-other' )
end
end
2018-04-27 10:50:33 -04:00
context 'when terms are enforced' do
let ( :user ) { create ( :user ) }
before do
enforce_terms
end
it 'asks to accept the terms on first login' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2018-04-27 10:50:33 -04:00
visit new_user_session_path
fill_in 'user_login' , with : user . email
fill_in 'user_password' , with : '12345678'
click_button 'Sign in'
expect_to_be_on_terms_page
click_button 'Accept terms'
expect ( current_path ) . to eq ( root_path )
2019-04-24 09:23:07 -04:00
expect ( page ) . not_to have_content ( I18n . t ( 'devise.failure.already_authenticated' ) )
2018-04-27 10:50:33 -04:00
end
it 'does not ask for terms when the user already accepted them' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2018-04-27 10:50:33 -04:00
accept_terms ( user )
visit new_user_session_path
fill_in 'user_login' , with : user . email
fill_in 'user_password' , with : '12345678'
click_button 'Sign in'
expect ( current_path ) . to eq ( root_path )
end
2018-05-11 03:35:27 -04:00
context 'when 2FA is required for the user' do
before do
group = create ( :group , require_two_factor_authentication : true )
group . add_developer ( user )
end
context 'when the user did not enable 2FA' do
2021-01-13 07:10:27 -05:00
it 'asks to set 2FA before asking to accept the terms' , :js do
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2020-12-08 10:09:45 -05:00
2021-01-13 07:10:27 -05:00
visit new_user_session_path
2018-05-11 03:35:27 -04:00
2021-01-13 07:10:27 -05:00
fill_in 'user_login' , with : user . email
fill_in 'user_password' , with : '12345678'
2018-05-11 03:35:27 -04:00
2021-01-13 07:10:27 -05:00
click_button 'Sign in'
2018-05-11 03:35:27 -04:00
2021-01-13 07:10:27 -05:00
expect_to_be_on_terms_page
click_button 'Accept terms'
2020-12-08 10:09:45 -05:00
2021-01-13 07:10:27 -05:00
expect ( current_path ) . to eq ( profile_two_factor_auth_path )
2020-12-08 10:09:45 -05:00
2021-01-13 07:10:27 -05:00
fill_in 'pin_code' , with : user . reload . current_otp
2020-12-08 10:09:45 -05:00
2021-01-13 07:10:27 -05:00
click_button 'Register with two-factor app'
click_button 'Copy codes'
click_link 'Proceed'
2020-12-08 10:09:45 -05:00
2021-01-13 07:10:27 -05:00
expect ( current_path ) . to eq ( profile_account_path )
2021-02-10 10:11:19 -05:00
expect ( page ) . to have_content ( 'You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can use that key to generate additional recovery codes.' )
2018-05-11 03:35:27 -04:00
end
end
context 'when the user already enabled 2FA' do
before do
user . update! ( otp_required_for_login : true ,
otp_secret : User . generate_otp_secret ( 32 ) )
end
it 'asks the user to accept the terms' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
. and increment ( :user_two_factor_authenticated_counter )
2018-05-11 03:35:27 -04:00
visit new_user_session_path
fill_in 'user_login' , with : user . email
fill_in 'user_password' , with : '12345678'
click_button 'Sign in'
fill_in 'user_otp_attempt' , with : user . reload . current_otp
click_button 'Verify code'
expect_to_be_on_terms_page
click_button 'Accept terms'
expect ( current_path ) . to eq ( root_path )
end
end
end
context 'when the users password is expired' do
before do
user . update! ( password_expires_at : Time . parse ( '2018-05-08 11:29:46 UTC' ) )
end
it 'asks the user to accept the terms before setting a new password' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2018-05-11 03:35:27 -04:00
visit new_user_session_path
fill_in 'user_login' , with : user . email
fill_in 'user_password' , with : '12345678'
click_button 'Sign in'
expect_to_be_on_terms_page
click_button 'Accept terms'
expect ( current_path ) . to eq ( new_profile_password_path )
fill_in 'user_current_password' , with : '12345678'
fill_in 'user_password' , with : 'new password'
fill_in 'user_password_confirmation' , with : 'new password'
click_button 'Set new password'
expect ( page ) . to have_content ( 'Password successfully changed' )
end
end
context 'when the user does not have an email configured' do
let ( :user ) { create ( :omniauth_user , extern_uid : 'my-uid' , provider : 'saml' , email : 'temp-email-for-oauth-user@gitlab.localhost' ) }
before do
stub_omniauth_saml_config ( enabled : true , auto_link_saml_user : true , allow_single_sign_on : [ 'saml' ] , providers : [ mock_saml_config ] )
end
it 'asks the user to accept the terms before setting an email' do
2018-07-26 12:35:15 -04:00
expect ( authentication_metrics )
. to increment ( :user_authenticated_counter )
2018-05-11 03:35:27 -04:00
gitlab_sign_in_via ( 'saml' , user , 'my-uid' )
expect_to_be_on_terms_page
click_button 'Accept terms'
expect ( current_path ) . to eq ( profile_path )
fill_in 'Email' , with : 'hello@world.com'
click_button 'Update profile settings'
expect ( page ) . to have_content ( 'Profile was successfully updated' )
end
end
2018-04-27 10:50:33 -04:00
end
2019-07-31 10:53:37 -04:00
context 'when sending confirmation email and not yet confirmed' do
let! ( :user ) { create ( :user , confirmed_at : nil ) }
let ( :grace_period ) { 2 . days }
2021-06-24 14:07:15 -04:00
let ( :alert_title ) { 'Please confirm your email address' }
let ( :alert_message ) { " To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select Resend confirmation email " }
2019-07-31 10:53:37 -04:00
before do
stub_application_setting ( send_user_confirmation_email : true )
2020-03-11 20:09:34 -04:00
stub_feature_flags ( soft_email_confirmation : true )
2019-07-31 10:53:37 -04:00
allow ( User ) . to receive ( :allow_unconfirmed_access_for ) . and_return grace_period
end
it 'allows login and shows a flash warning to confirm the email address' do
expect ( authentication_metrics ) . to increment ( :user_authenticated_counter )
gitlab_sign_in ( user )
expect ( current_path ) . to eq root_path
2019-11-07 19:05:58 -05:00
expect ( page ) . to have_content ( " Please check your email ( #{ user . email } ) to verify that you own this address and unlock the power of CI/CD. " )
2019-07-31 10:53:37 -04:00
end
context " when not having confirmed within Devise's allow_unconfirmed_access_for time " do
2021-06-24 14:07:15 -04:00
it 'does not allow login and shows a flash alert to confirm the email address' , :js do
2019-07-31 10:53:37 -04:00
travel_to ( ( grace_period + 1 . day ) . from_now ) do
expect ( authentication_metrics )
. to increment ( :user_unauthenticated_counter )
. and increment ( :user_session_destroyed_counter ) . twice
gitlab_sign_in ( user )
expect ( current_path ) . to eq new_user_session_path
2021-06-24 14:07:15 -04:00
expect ( page ) . to have_content ( alert_title )
expect ( page ) . to have_content ( alert_message )
expect ( page ) . to have_link ( 'Resend confirmation email' , href : new_user_confirmation_path )
2019-07-31 10:53:37 -04:00
end
end
end
end
2015-05-05 22:16:45 -04:00
end