Commit 9224f031 authored by DJ Mountney's avatar DJ Mountney

Pass the remember_me option into the u2f form and support it while authenticating

Matches the changes done for non-u2f two-factor auth
parent 33a367e8
...@@ -4,6 +4,7 @@ v 8.12.0 (unreleased) ...@@ -4,6 +4,7 @@ v 8.12.0 (unreleased)
- Filter tags by name !6121 - Filter tags by name !6121
- Make push events have equal vertical spacing. - Make push events have equal vertical spacing.
- Add two-factor recovery endpoint to internal API !5510 - Add two-factor recovery endpoint to internal API !5510
- Pass the "Remember me" value to the U2F authentication form
- Remove vendor prefixes for linear-gradient CSS (ClemMakesApps) - Remove vendor prefixes for linear-gradient CSS (ClemMakesApps)
- Add font color contrast to external label in admin area (ClemMakesApps) - Add font color contrast to external label in admin area (ClemMakesApps)
- Change logo animation to CSS (ClemMakesApps) - Change logo animation to CSS (ClemMakesApps)
......
...@@ -62,6 +62,7 @@ module AuthenticatesWithTwoFactor ...@@ -62,6 +62,7 @@ module AuthenticatesWithTwoFactor
session.delete(:otp_user_id) session.delete(:otp_user_id)
session.delete(:challenges) session.delete(:challenges)
remember_me(user) if user_params[:remember_me] == '1'
sign_in(user) sign_in(user)
else else
flash.now[:alert] = 'Authentication via U2F device failed.' flash.now[:alert] = 'Authentication via U2F device failed.'
......
...@@ -18,6 +18,5 @@ ...@@ -18,6 +18,5 @@
= f.submit "Verify code", class: "btn btn-save" = f.submit "Verify code", class: "btn btn-save"
- if @user.two_factor_u2f_enabled? - if @user.two_factor_u2f_enabled?
%hr %hr
= render "u2f/authenticate" = render "u2f/authenticate", locals: { params: params, resource: resource, resource_name: resource_name }
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
%div %div
%p We heard back from your U2F device. Click this button to authenticate with the GitLab server. %p We heard back from your U2F device. Click this button to authenticate with the GitLab server.
= form_tag(new_user_session_path, method: :post) do |f| = form_tag(new_user_session_path, method: :post) do |f|
- resource_params = params[resource_name].presence || params
= hidden_field_tag 'user[remember_me]', resource_params.fetch(:remember_me, 0)
= hidden_field_tag 'user[device_response]', nil, class: 'form-control', required: true, id: "js-device-response" = hidden_field_tag 'user[device_response]', nil, class: 'form-control', required: true, id: "js-device-response"
= submit_tag "Authenticate via U2F Device", class: "btn btn-success" = submit_tag "Authenticate via U2F Device", class: "btn btn-success"
......
...@@ -136,6 +136,29 @@ describe SessionsController do ...@@ -136,6 +136,29 @@ describe SessionsController do
post(:create, { user: user_params }, { otp_user_id: user.id }) post(:create, { user: user_params }, { otp_user_id: user.id })
end end
context 'remember_me field' do
it 'sets a remember_user_token cookie when enabled' do
allow(U2fRegistration).to receive(:authenticate).and_return(true)
allow(controller).to receive(:find_user).and_return(user)
expect(controller).
to receive(:remember_me).with(user).and_call_original
authenticate_2fa_u2f(remember_me: '1', login: user.username, device_response: "{}")
expect(response.cookies['remember_user_token']).to be_present
end
it 'does nothing when disabled' do
allow(U2fRegistration).to receive(:authenticate).and_return(true)
allow(controller).to receive(:find_user).and_return(user)
expect(controller).not_to receive(:remember_me)
authenticate_2fa_u2f(remember_me: '0', login: user.username, device_response: "{}")
expect(response.cookies['remember_user_token']).to be_nil
end
end
it "creates an audit log record" do it "creates an audit log record" do
allow(U2fRegistration).to receive(:authenticate).and_return(true) allow(U2fRegistration).to receive(:authenticate).and_return(true)
expect { authenticate_2fa_u2f(login: user.username, device_response: "{}") }.to change { SecurityEvent.count }.by(1) expect { authenticate_2fa_u2f(login: user.username, device_response: "{}") }.to change { SecurityEvent.count }.by(1)
......
...@@ -156,6 +156,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: ...@@ -156,6 +156,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
describe "when 2FA via OTP is disabled" do describe "when 2FA via OTP is disabled" do
it "allows logging in with the U2F device" do it "allows logging in with the U2F device" do
user.update_attribute(:otp_required_for_login, false)
login_with(user) login_with(user)
@u2f_device.respond_to_u2f_authentication @u2f_device.respond_to_u2f_authentication
...@@ -181,6 +182,19 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: ...@@ -181,6 +182,19 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
end end
end end
it 'persists remember_me value via hidden field' do
login_with(user, remember: true)
@u2f_device.respond_to_u2f_authentication
click_on "Login Via U2F Device"
expect(page.body).to match('We heard back from your U2F device')
within 'div#js-authenticate-u2f' do
field = first('input#user_remember_me', visible: false)
expect(field.value).to eq '1'
end
end
describe "when a given U2F device has already been registered by another user" do describe "when a given U2F device has already been registered by another user" do
describe "but not the current user" do describe "but not the current user" do
it "does not allow logging in with that particular device" do it "does not allow logging in with that particular device" do
......
= render partial: "u2f/authenticate", locals: { new_user_session_path: "/users/sign_in" } = render partial: "u2f/authenticate", locals: { new_user_session_path: "/users/sign_in", params: {}, resource_name: "user" }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment