summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/features/u2f_spec.rb119
-rw-r--r--spec/javascripts/u2f/authenticate_spec.js23
-rw-r--r--spec/support/fake_u2f_device.rb3
3 files changed, 90 insertions, 55 deletions
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index be21b403084..a8d00bb8e5a 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -45,12 +45,12 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
it 'allows registering a new device with a name' do
visit profile_account_path
manage_two_factor_authentication
- expect(page.body).to match("You've already enabled two-factor authentication using mobile")
+ expect(page).to have_content("You've already enabled two-factor authentication using mobile")
u2f_device = register_u2f_device
- expect(page.body).to match(u2f_device.name)
- expect(page.body).to match('Your U2F device was registered')
+ 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
@@ -59,30 +59,30 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
# First device
manage_two_factor_authentication
first_device = register_u2f_device
- expect(page.body).to match('Your U2F device was registered')
+ expect(page).to have_content('Your U2F device was registered')
# Second device
second_device = register_u2f_device
- expect(page.body).to match('Your U2F device was registered')
+ expect(page).to have_content('Your U2F device was registered')
- expect(page.body).to match(first_device.name)
- expect(page.body).to match(second_device.name)
+ expect(page).to have_content(first_device.name)
+ expect(page).to have_content(second_device.name)
expect(U2fRegistration.count).to eq(2)
end
it 'allows deleting a device' do
visit profile_account_path
manage_two_factor_authentication
- expect(page.body).to match("You've already enabled two-factor authentication using mobile")
+ expect(page).to have_content("You've already enabled two-factor authentication using mobile")
first_u2f_device = register_u2f_device
second_u2f_device = register_u2f_device
click_on "Delete", match: :first
- expect(page.body).to match('Successfully deleted')
+ expect(page).to have_content('Successfully deleted')
expect(page.body).not_to match(first_u2f_device.name)
- expect(page.body).to match(second_u2f_device.name)
+ expect(page).to have_content(second_u2f_device.name)
end
end
@@ -91,7 +91,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
visit profile_account_path
manage_two_factor_authentication
u2f_device = register_u2f_device
- expect(page.body).to match('Your U2F device was registered')
+ expect(page).to have_content('Your U2F device was registered')
logout
# Second user
@@ -100,7 +100,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
visit profile_account_path
manage_two_factor_authentication
register_u2f_device(u2f_device)
- expect(page.body).to match('Your U2F device was registered')
+ expect(page).to have_content('Your U2F device was registered')
expect(U2fRegistration.count).to eq(2)
end
@@ -117,8 +117,8 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
click_on 'Register U2F Device'
expect(U2fRegistration.count).to eq(0)
- expect(page.body).to match("The form contains the following error")
- expect(page.body).to match("did not send a valid JSON response")
+ 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
@@ -130,12 +130,12 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
click_on 'Setup New U2F Device'
expect(page).to have_content('Your device was successfully set up')
click_on 'Register U2F Device'
- expect(page.body).to match("The form contains the following error")
+ expect(page).to have_content("The form contains the following error")
# Successful registration
register_u2f_device
- expect(page.body).to match('Your U2F device was registered')
+ expect(page).to have_content('Your U2F device was registered')
expect(U2fRegistration.count).to eq(1)
end
end
@@ -160,10 +160,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
login_with(user)
@u2f_device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
- click_on "Authenticate via U2F Device"
- expect(page.body).to match('href="/users/sign_out"')
+
+ expect(page).to have_content('We heard back from your U2F device')
+ expect(page).to have_css('.sign-out-link', visible: false)
end
end
@@ -173,11 +172,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
login_with(user)
@u2f_device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
- click_on "Authenticate via U2F Device"
- expect(page.body).to match('href="/users/sign_out"')
+ expect(page).to have_content('We heard back from your U2F device')
+ expect(page).to have_css('.sign-out-link', visible: false)
end
end
@@ -185,8 +182,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
login_with(user, remember: true)
@u2f_device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
+ expect(page).to have_content('We heard back from your U2F device')
within 'div#js-authenticate-u2f' do
field = first('input#user_remember_me', visible: false)
@@ -208,11 +204,8 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
# Try authenticating user with the old U2F device
login_as(current_user)
@u2f_device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
- click_on "Authenticate via U2F Device"
-
- expect(page.body).to match('Authentication via U2F device failed')
+ expect(page).to have_content('We heard back from your U2F device')
+ expect(page).to have_content('Authentication via U2F device failed')
end
end
@@ -229,11 +222,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
# Try authenticating user with the same U2F device
login_as(current_user)
@u2f_device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
- click_on "Authenticate via U2F Device"
+ expect(page).to have_content('We heard back from your U2F device')
- expect(page.body).to match('href="/users/sign_out"')
+ expect(page).to have_css('.sign-out-link', visible: false)
end
end
end
@@ -243,11 +234,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
unregistered_device = FakeU2fDevice.new(page, FFaker::Name.first_name)
login_as(user)
unregistered_device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
- click_on "Authenticate via U2F Device"
+ expect(page).to have_content('We heard back from your U2F device')
- expect(page.body).to match('Authentication via U2F device failed')
+ expect(page).to have_content('Authentication via U2F device failed')
end
end
@@ -270,11 +259,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
[first_device, second_device].each do |device|
login_as(user)
device.respond_to_u2f_authentication
- click_on "Sign in via U2F device"
- expect(page.body).to match('We heard back from your U2F device')
- click_on "Authenticate via U2F Device"
+ expect(page).to have_content('We heard back from your U2F device')
- expect(page.body).to match('href="/users/sign_out"')
+ expect(page).to have_css('.sign-out-link', visible: false)
logout
end
@@ -299,4 +286,50 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
end
end
end
+
+ 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
+ login_as(user)
+ user.update_attribute(:otp_required_for_login, true)
+ visit profile_account_path
+ end
+
+ describe 'when no u2f device is registered' do
+ before do
+ logout
+ login_with(user)
+ 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
+ logout
+ login_with(user)
+ 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
diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js
index a8874ab12d3..064d18519ea 100644
--- a/spec/javascripts/u2f/authenticate_spec.js
+++ b/spec/javascripts/u2f/authenticate_spec.js
@@ -14,18 +14,19 @@
beforeEach(function() {
this.u2fDevice = new MockU2FDevice;
this.container = $("#js-authenticate-u2f");
- this.component = new U2FAuthenticate(this.container, {
- sign_requests: []
- }, "token");
+ this.component = new window.gl.U2FAuthenticate(
+ this.container,
+ '#js-login-u2f-form',
+ {
+ sign_requests: []
+ },
+ document.querySelector('#js-login-2fa-device'),
+ document.querySelector('.js-2fa-form')
+ );
return this.component.start();
});
it('allows authenticating via a U2F device', function() {
- var authenticatedMessage, deviceResponse, inProgressMessage, setupButton, setupMessage;
- setupButton = this.container.find("#js-login-u2f-device");
- setupMessage = this.container.find("p");
- expect(setupMessage.text()).toContain('Insert your security key');
- expect(setupButton.text()).toBe('Sign in via U2F device');
- setupButton.trigger('click');
+ var authenticatedMessage, deviceResponse, inProgressMessage;
inProgressMessage = this.container.find("p");
expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
this.u2fDevice.respondToAuthenticateRequest({
@@ -33,7 +34,7 @@
});
authenticatedMessage = this.container.find("p");
deviceResponse = this.container.find('#js-device-response');
- expect(authenticatedMessage.text()).toContain("Click this button to authenticate with the GitLab server");
+ expect(authenticatedMessage.text()).toContain('We heard back from your U2F device. You have been authenticated.');
return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
});
return describe("errors", function() {
@@ -62,7 +63,7 @@
deviceData: "this is data from the device"
});
authenticatedMessage = this.container.find("p");
- return expect(authenticatedMessage.text()).toContain("Click this button to authenticate with the GitLab server");
+ return expect(authenticatedMessage.text()).toContain("We heard back from your U2F device. You have been authenticated.");
});
});
});
diff --git a/spec/support/fake_u2f_device.rb b/spec/support/fake_u2f_device.rb
index 8c407b867fe..a7605cd483a 100644
--- a/spec/support/fake_u2f_device.rb
+++ b/spec/support/fake_u2f_device.rb
@@ -5,7 +5,7 @@ class FakeU2fDevice
@page = page
@name = name
end
-
+
def respond_to_u2f_registration
app_id = @page.evaluate_script('gon.u2f.app_id')
challenges = @page.evaluate_script('gon.u2f.challenges')
@@ -28,6 +28,7 @@ class FakeU2fDevice
u2f.sign = function(appId, challenges, signRequests, callback) {
callback(#{json_response});
};
+ window.gl.u2fAuthenticate.start();
")
end