diff options
-rw-r--r-- | spec/controllers/sessions_controller_spec.rb | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb new file mode 100644 index 00000000000..e7dbc3bdad4 --- /dev/null +++ b/spec/controllers/sessions_controller_spec.rb @@ -0,0 +1,93 @@ +require 'spec_helper' + +describe SessionsController do + describe '#create' do + before do + @request.env['devise.mapping'] = Devise.mappings[:user] + end + + context 'standard authentications' do + context 'invalid password' do + it 'does not authenticate user' do + post(:create, user: { login: 'invalid', password: 'invalid' }) + + expect(response) + .to set_flash.now[:alert].to /Invalid login or password/ + end + end + + context 'valid password' do + let(:user) { create(:user) } + + it 'authenticates user correctly' do + post(:create, user: { login: user.username, password: user.password }) + + expect(response).to set_flash.to /Signed in successfully/ + expect(subject.current_user). to eq user + end + end + end + + context 'two-factor authentication' do + let(:user) { create(:user, :two_factor) } + + def authenticate_2fa(user_params) + post(:create, { user: user_params }, { otp_user_id: user.id }) + end + + ## + # See #14900 issue + # + context 'authenticating with login and OTP belonging to another user' do + let(:another_user) { create(:user, :two_factor) } + + + context 'OTP valid for another user' do + it 'does not authenticate' do + authenticate_2fa(login: another_user.username, + otp_attempt: another_user.current_otp) + + expect(subject.current_user).to_not eq another_user + end + end + + context 'OTP invalid for another user' do + before do + authenticate_2fa(login: another_user.username, + otp_attempt: 'invalid') + end + + it 'does not authenticate' do + expect(subject.current_user).to_not eq another_user + end + + it 'does not leak information about 2FA enabled' do + expect(response).to_not set_flash.now[:alert].to /Invalid two-factor code/ + end + end + + context 'authenticating with OTP' do + context 'valid OTP' do + it 'authenticates correctly' do + authenticate_2fa(otp_attempt: user.current_otp) + + expect(subject.current_user).to eq user + end + end + + context 'invalid OTP' do + before { authenticate_2fa(otp_attempt: 'invalid') } + + it 'does not authenticate' do + expect(subject.current_user).to_not eq user + end + + it 'warns about invalid OTP code' do + expect(response).to set_flash.now[:alert].to /Invalid two-factor code/ + end + end + end + end + end + end +end |