debian-mirror-gitlab/spec/features/u2f_spec.rb

299 lines
9.8 KiB
Ruby
Raw Normal View History

2019-10-12 21:52:04 +05:30
# frozen_string_literal: true
require 'spec_helper'
2018-11-08 19:23:39 +05:30
describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
2016-09-13 17:45:13 +05:30
def manage_two_factor_authentication
2017-08-17 22:00:37 +05:30
click_on 'Manage two-factor authentication'
2018-12-05 23:21:45 +05:30
expect(page).to have_content("Set up new U2F device")
2017-09-10 17:25:29 +05:30
wait_for_requests
2016-09-13 17:45:13 +05:30
end
2017-08-17 22:00:37 +05:30
def register_u2f_device(u2f_device = nil, name: 'My device')
2016-09-13 17:45:13 +05:30
u2f_device ||= FakeU2fDevice.new(page, name)
u2f_device.respond_to_u2f_registration
2018-12-05 23:21:45 +05:30
click_on 'Set up new U2F device'
expect(page).to have_content('Your device was successfully set up')
2016-09-13 17:45:13 +05:30
fill_in "Pick a name", with: name
2017-08-17 22:00:37 +05:30
click_on 'Register U2F device'
u2f_device
end
describe "registration" do
let(:user) { create(:user) }
before do
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
user.update_attribute(:otp_required_for_login, true)
end
describe 'when 2FA via OTP is disabled' do
2017-09-10 17:25:29 +05:30
before do
user.update_attribute(:otp_required_for_login, false)
end
it 'does not allow registering a new device' do
visit profile_account_path
2017-08-17 22:00:37 +05:30
click_on 'Enable two-factor authentication'
2018-12-05 23:21:45 +05:30
expect(page).to have_button('Set up new U2F device', disabled: true)
end
end
describe 'when 2FA via OTP is enabled' do
2016-09-13 17:45:13 +05:30
it 'allows registering a new device with a name' do
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
2018-12-05 23:21:45 +05:30
expect(page).to have_content("You've already enabled two-factor authentication using one time password authenticators")
2016-09-13 17:45:13 +05:30
u2f_device = register_u2f_device
2017-08-17 22:00:37 +05:30
expect(page).to have_content(u2f_device.name)
expect(page).to have_content('Your U2F device was registered')
end
it 'allows registering more than one device' do
visit profile_account_path
# First device
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
first_device = register_u2f_device
2017-08-17 22:00:37 +05:30
expect(page).to have_content('Your U2F device was registered')
# Second device
2017-08-17 22:00:37 +05:30
second_device = register_u2f_device(name: 'My other device')
expect(page).to have_content('Your U2F device was registered')
2016-09-13 17:45:13 +05:30
2017-08-17 22:00:37 +05:30
expect(page).to have_content(first_device.name)
expect(page).to have_content(second_device.name)
2016-09-13 17:45:13 +05:30
expect(U2fRegistration.count).to eq(2)
end
it 'allows deleting a device' do
visit profile_account_path
manage_two_factor_authentication
2018-12-05 23:21:45 +05:30
expect(page).to have_content("You've already enabled two-factor authentication using one time password authenticators")
2016-09-13 17:45:13 +05:30
first_u2f_device = register_u2f_device
2017-08-17 22:00:37 +05:30
second_u2f_device = register_u2f_device(name: 'My other device')
2016-09-13 17:45:13 +05:30
2018-03-17 18:26:18 +05:30
accept_confirm { click_on "Delete", match: :first }
2016-09-13 17:45:13 +05:30
2017-08-17 22:00:37 +05:30
expect(page).to have_content('Successfully deleted')
2016-09-13 17:45:13 +05:30
expect(page.body).not_to match(first_u2f_device.name)
2017-08-17 22:00:37 +05:30
expect(page).to have_content(second_u2f_device.name)
end
end
it 'allows the same device to be registered for multiple users' do
# First user
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
u2f_device = register_u2f_device
2017-08-17 22:00:37 +05:30
expect(page).to have_content('Your U2F device was registered')
2017-09-10 17:25:29 +05:30
gitlab_sign_out
# Second user
2017-09-10 17:25:29 +05:30
user = gitlab_sign_in(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
2017-08-17 22:00:37 +05:30
register_u2f_device(u2f_device, name: 'My other device')
expect(page).to have_content('Your U2F device was registered')
expect(U2fRegistration.count).to eq(2)
end
context "when there are form errors" do
it "doesn't register the device if there are errors" do
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
# Have the "u2f device" respond with bad data
page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };")
2018-12-05 23:21:45 +05:30
click_on 'Set up new U2F device'
expect(page).to have_content('Your device was successfully set up')
2017-08-17 22:00:37 +05:30
click_on 'Register U2F device'
expect(U2fRegistration.count).to eq(0)
2017-08-17 22:00:37 +05:30
expect(page).to have_content("The form contains the following error")
expect(page).to have_content("did not send a valid JSON response")
end
it "allows retrying registration" do
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
# Failed registration
page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };")
2018-12-05 23:21:45 +05:30
click_on 'Set up new U2F device'
expect(page).to have_content('Your device was successfully set up')
2017-08-17 22:00:37 +05:30
click_on 'Register U2F device'
expect(page).to have_content("The form contains the following error")
# Successful registration
register_u2f_device
2017-08-17 22:00:37 +05:30
expect(page).to have_content('Your U2F device was registered')
expect(U2fRegistration.count).to eq(1)
end
end
end
describe "authentication" do
let(:user) { create(:user) }
before do
# Register and logout
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
@u2f_device = register_u2f_device
2017-09-10 17:25:29 +05:30
gitlab_sign_out
end
describe "when 2FA via OTP is disabled" do
it "allows logging in with the U2F device" do
2016-09-29 09:46:39 +05:30
user.update_attribute(:otp_required_for_login, false)
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
@u2f_device.respond_to_u2f_authentication
2017-08-17 22:00:37 +05:30
expect(page).to have_css('.sign-out-link', visible: false)
end
end
describe "when 2FA via OTP is enabled" do
it "allows logging in with the U2F device" do
user.update_attribute(:otp_required_for_login, true)
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
@u2f_device.respond_to_u2f_authentication
2017-08-17 22:00:37 +05:30
expect(page).to have_css('.sign-out-link', visible: false)
end
end
describe "when a given U2F device has already been registered by another user" do
describe "but not the current user" do
it "does not allow logging in with that particular device" do
# Register current user with the different U2F device
2017-09-10 17:25:29 +05:30
current_user = gitlab_sign_in(:user)
current_user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
2017-08-17 22:00:37 +05:30
register_u2f_device(name: 'My other device')
2017-09-10 17:25:29 +05:30
gitlab_sign_out
# Try authenticating user with the old U2F device
2017-09-10 17:25:29 +05:30
gitlab_sign_in(current_user)
@u2f_device.respond_to_u2f_authentication
2017-08-17 22:00:37 +05:30
expect(page).to have_content('Authentication via U2F device failed')
end
end
describe "and also the current user" do
it "allows logging in with that particular device" do
# Register current user with the same U2F device
2017-09-10 17:25:29 +05:30
current_user = gitlab_sign_in(:user)
current_user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
2016-09-13 17:45:13 +05:30
manage_two_factor_authentication
register_u2f_device(@u2f_device)
2017-09-10 17:25:29 +05:30
gitlab_sign_out
# Try authenticating user with the same U2F device
2017-09-10 17:25:29 +05:30
gitlab_sign_in(current_user)
@u2f_device.respond_to_u2f_authentication
2017-08-17 22:00:37 +05:30
expect(page).to have_css('.sign-out-link', visible: false)
end
end
end
describe "when a given U2F device has not been registered" do
it "does not allow logging in with that particular device" do
2017-08-17 22:00:37 +05:30
unregistered_device = FakeU2fDevice.new(page, 'My device')
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
unregistered_device.respond_to_u2f_authentication
2017-08-17 22:00:37 +05:30
expect(page).to have_content('Authentication via U2F device failed')
end
end
2016-08-24 12:49:21 +05:30
describe "when more than one device has been registered by the same user" do
it "allows logging in with either device" do
# Register first device
2017-09-10 17:25:29 +05:30
user = gitlab_sign_in(:user)
2016-08-24 12:49:21 +05:30
user.update_attribute(:otp_required_for_login, true)
visit profile_two_factor_auth_path
expect(page).to have_content("Your U2F device needs to be set up.")
first_device = register_u2f_device
# Register second device
visit profile_two_factor_auth_path
expect(page).to have_content("Your U2F device needs to be set up.")
2017-08-17 22:00:37 +05:30
second_device = register_u2f_device(name: 'My other device')
2017-09-10 17:25:29 +05:30
gitlab_sign_out
2016-08-24 12:49:21 +05:30
# Authenticate as both devices
[first_device, second_device].each do |device|
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
2016-08-24 12:49:21 +05:30
device.respond_to_u2f_authentication
2017-08-17 22:00:37 +05:30
expect(page).to have_css('.sign-out-link', visible: false)
2016-08-24 12:49:21 +05:30
2017-09-10 17:25:29 +05:30
gitlab_sign_out
2016-08-24 12:49:21 +05:30
end
end
end
end
2017-08-17 22:00:37 +05:30
describe 'fallback code authentication' do
let(:user) { create(:user) }
def assert_fallback_ui(page)
expect(page).to have_button('Verify code')
expect(page).to have_css('#user_otp_attempt')
expect(page).not_to have_link('Sign in via 2FA code')
expect(page).not_to have_css('#js-authenticate-u2f')
end
before do
# Register and logout
2017-09-10 17:25:29 +05:30
gitlab_sign_in(user)
2017-08-17 22:00:37 +05:30
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
end
describe 'when no u2f device is registered' do
before do
2017-09-10 17:25:29 +05:30
gitlab_sign_out
gitlab_sign_in(user)
2017-08-17 22:00:37 +05:30
end
it 'shows the fallback otp code UI' do
assert_fallback_ui(page)
end
end
describe 'when a u2f device is registered' do
before do
manage_two_factor_authentication
@u2f_device = register_u2f_device
2017-09-10 17:25:29 +05:30
gitlab_sign_out
gitlab_sign_in(user)
2017-08-17 22:00:37 +05:30
end
it 'provides a button that shows the fallback otp code UI' do
expect(page).to have_link('Sign in via 2FA code')
click_link('Sign in via 2FA code')
assert_fallback_ui(page)
end
end
end
end