Skip to content

Allow a U2F Device to be the Second Factor for Authentication

username-removed-407765 requested to merge 15337-yubikey-support into master

Parent Issue: #15337 (moved)

TODO

  • #15337 (moved) (!3905 (merged)) FIDO/U2F 2FA using Yubikey
    • Order a Yubikey?
    • Do some reading to figure out what all this stuff means
    • Look through the existing MR
    • Browser support?
    • Implementation
      • User can register 2FA using their U2H device instead of authenticator
        • Barebones flow
        • Save the registration in the database
        • Authentication flow
        • First try after login/server start doesn't work
      • User can log in using their U2F device
      • Allow setting up authenticator if U2F is already set up (or vice versa)
      • Change two_factor_auths/new to show
      • sign_requests during registration? (Registering a device that has already been registered)
      • 2FA skippable flow?
      • Enforced 2FA flow (grace period?)
      • Move the "Configure it Later" button to the right place
      • Don't allow registration when the yubikey isn't plugged in
      • Polish authentication flow
      • Login should only show the 2FA method that's enabled
        • Message to say that u2f only works on chrome, and it's recommended to enable otp as well.
      • Index for key_handle
      • Server-side errors while registering/logging in
      • Handle non-chrome browsers
      • Try to authenticate with a key that hasn't been registered (shouldn't work)
      • Try the same key for multiple user accounts (should work)
      • Fix existing tests
      • Make sure CI is green
      • Add tests
        • Figure out how to fake the Yubikey
        • Teaspoon tests for the React components
          • Each device can only be registered once per user
        • Feature specs
          • Regular flows
          • Test error cases
      • Refactoring
        • Refactor App ID
        • Clean up the show action
      • Annotate methods with definition of U2F
      • Changelog
      • Fix merge conflicts
      • Verify flows
        • Authenticator + no U2F
        • U2F + no authenticator
        • U2F + authenticator
        • U2F + authenticator -> disable 2FA
        • 2FA required with different grace periods
      • Screenshots for MR
    • Augment the help docs
    • Assign to endboss
    • Ask for feedback on UI/UX
    • Ask for feedback on copy
    • Wait for review/merge
    • Fix merge conflicts
    • Wait for CI to pass
    • Implement review comments/suggestions
      • Move TwoFactorAuthController#create_u2f to a service
      • Extra space before Base64 in u2f_registration model
      • Move with/without_two_factor scopes to class methods
      • In profiles/accounts/show, add spaces at { and }
      • Remove blank lines in profiles/two_factor_auths/show
      • Fix typo in doc. "(universal 2nd factor )"
      • Add "Added in 8.8" to doc
      • In the doc, use 'Enable 2FA via mobile application' instead of 'Via Mobile Application'
      • In the doc, use 'Enable 2FA via U2F device' instead of 'Via U2F Device
      • Use "Two-Factor Authentication" everywhere
      • Use #icon wrapper instead of fa_stacked_icon
      • Check if string is enough for key_handle and public_key
      • Separate exercise and verify phases of test (u2f_spec)
      • Assert that user_without_2fa is not in results (with_two_factor)
        • Remove rubocop exception
      • Refactor call to User.with_two_factor.count to not include .length
      • Add a note that makes the "Disable" button/feature obvious
      • Remove i18n
      • Test in Firefox with addon (+ create new issue for support)
      • Remove React
        • Rewrite registration
        • Switch underscore template to default style
        • Rewrite authentication
        • Move register haml to u2f dir
        • Remove instance variables
        • Fix tests
        • Read SCSS guidelines
        • Address @connorshea's comments regarding text style
        • Make sure all classes and IDs are in line (add js- prefixes)
          • Register
          • Authenticate
        • Refactoring?
      • Include non-minifed version of bowser
      • Audit log
      • Look at the browser gem (and don't use bowser)
      • Error message when on HTTP?
    • Test on Mobile
    • Fix merge conflicts
    • Retest all flows
    • Back to Rémy for review
    • Make sure CI is green
    • Wait for merge / more feedback
    • Implement @rymai's changes
      • JS/Coffeescript variables should be lowerCamelCase
      • Spaces before/after } and { in HAML (and elsewhere)
      • Rails view helpers in u2f HAML
      • %div.row.append-bottom-10
      • Wrap line in without_two_factor scope
      • Exception-less flow in U2F::CreateService
    • Fix merge conflicts
    • Move service to model class method
    • Fix teaspoon specs
    • Address @rymai's suggestions about error handing
    • Javascript error constants
    • Fix merge conflicts
    • One final review
      • Test "registration with errors" flow
    • Assign to Remy
    • Wait for replies from @jschatz1
    • Address @rymai's comments
      • Omit %div
      • Scope $.find globally
      • Replace find('#element-id).click with `click_on('Element Text')
    • Rebase master + conflicts
    • Look at https://news.ycombinator.com/item?id=11690774
    • Address @connorshea's comment regarding HTTPS on localhost
    • Final sanity check
    • Wait for CI to pass
    • Address @rymai's next round of comments
      • Interpolate true and false in DB scopes
      • Why have Gon::Base.render_data thrice?
      • user_spec should have correct spacing
      • Use arel_table[:id] instead of users.id
      • URL helper in app/views/profiles/two_factor_auths/show.html.haml
      • Remove polyfill change
    • Wait for CI to pass
    • Address @jschatz1's comments
      • Use on('click', ...) instead of click(...)
      • Use is and isnt in coffeescript
      • Use and and or in coffeescript
    • Add Gon::Base.render_data to devise_empty (and other base layouts)
    • Wait for CI to pass
    • Wait for build to pass
    • Fix merge conflicts
    • Inspect diff / workflow
    • Assign back to @rymai
    • Make sure ci has passed
    • Fix merge conflicts (probably introduced by devise upgrade
    • Wait for CI to pass
    • Respond to @rymai's comments
      • Use elsif
      • Check if we need and return
      • Only fetch key handles from the DB
      • No annotations to models?
      • Align hash keys in model
    • Wait for build to pass
    • Wait for merge

Screenshots

Screenshot_2016-05-03_09.53.04 Screenshot_2016-05-03_10.19.53 Screenshot_2016-05-03_10.19.56 Screenshot_2016-05-03_10.20.04 Screenshot_2016-05-03_10.31.15 Screenshot_2016-05-03_10.31.22 Screenshot_2016-05-03_10.31.37 Screenshot_2016-05-03_10.36.48

Merge request reports