Commit 341d8bc3 authored by Timothy Andrew's avatar Timothy Andrew

Add a U2F feature spec for multiple devices owned by the same user.

1. This scenario was previously tested for the registration flow, but
   not authentication.
parent 3572582d
...@@ -8,14 +8,17 @@ class @U2FAuthenticate ...@@ -8,14 +8,17 @@ class @U2FAuthenticate
@appId = u2fParams.app_id @appId = u2fParams.app_id
@challenge = u2fParams.challenge @challenge = u2fParams.challenge
# The U2F Javascript API v1.1 requires a single challenge, with _no # The U2F Javascript API v1.1 requires a single challenge, with
# challenges per-request_. # _no challenges per-request_. The U2F Javascript API v1.0 requires a
# # challenge per-request, which is done by copying the single challenge
# The U2F Javascript API v1.0 requires a challenge per-request, which # into every request.
# is done by copying the single challenge into every request.
# #
# In either case, we don't need the per-request challenges that the server # In either case, we don't need the per-request challenges that the server
# has generated, so we can remove them. # has generated, so we can remove them.
#
# Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
# This can be removed once we upgrade.
# https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
@signRequests = u2fParams.sign_requests.map (request) -> _(request).omit('challenge') @signRequests = u2fParams.sign_requests.map (request) -> _(request).omit('challenge')
start: () => start: () =>
......
class @U2FUtil class @U2FUtil
@isU2FSupported: -> @isU2FSupported: ->
window.u2f window.u2f
- content_for :page_specific_javascripts do - if inject_u2f_api?
- if inject_u2f_api? - content_for :page_specific_javascripts do
= page_specific_javascript_tag('u2f.js') = page_specific_javascript_tag('u2f.js')
%div %div
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
- header_title "Two-Factor Authentication", profile_two_factor_auth_path - header_title "Two-Factor Authentication", profile_two_factor_auth_path
= render 'profiles/head' = render 'profiles/head'
- content_for :page_specific_javascripts do - if inject_u2f_api?
- if inject_u2f_api? - content_for :page_specific_javascripts do
= page_specific_javascript_tag('u2f.js') = page_specific_javascript_tag('u2f.js')
.row.prepend-top-default .row.prepend-top-default
......
require 'spec_helper' require 'spec_helper'
feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: true, js: true do feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: true, js: true do
before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) }
def register_u2f_device(u2f_device = nil) def register_u2f_device(u2f_device = nil)
u2f_device ||= FakeU2fDevice.new(page) u2f_device ||= FakeU2fDevice.new(page)
u2f_device.respond_to_u2f_registration u2f_device.respond_to_u2f_registration
...@@ -208,21 +210,52 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: ...@@ -208,21 +210,52 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
expect(page.body).to match('Authentication via U2F device failed') expect(page.body).to match('Authentication via U2F device failed')
end end
end end
end
describe "when two-factor authentication is disabled" do describe "when more than one device has been registered by the same user" do
let(:user) { create(:user) } it "allows logging in with either device" do
# Register first device
user = login_as(:user)
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.")
second_device = register_u2f_device
logout
# Authenticate as both devices
[first_device, second_device].each do |device|
login_as(user)
device.respond_to_u2f_authentication
click_on "Login Via U2F Device"
expect(page.body).to match('We heard back from your U2F device')
click_on "Authenticate via U2F Device"
before do expect(page.body).to match('Signed in successfully')
login_as(user)
user.update_attribute(:otp_required_for_login, true) logout
visit profile_account_path end
click_on 'Manage Two-Factor Authentication' end
register_u2f_device
end end
it "deletes u2f registrations" do describe "when two-factor authentication is disabled" do
expect { click_on "Disable" }.to change { U2fRegistration.count }.from(1).to(0) let(:user) { create(:user) }
before do
user = login_as(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
click_on 'Manage Two-Factor Authentication'
expect(page).to have_content("Your U2F device needs to be set up.")
register_u2f_device
end
it "deletes u2f registrations" do
expect { click_on "Disable" }.to change { U2fRegistration.count }.by(-1)
end
end end
end end
end end
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