Browse Source

Allows otp_length to be configurable

Adds otp_length to options in README

Sets default length to 6
master
amoose 10 years ago
parent
commit
3076c6053b
  1. 7
      README.md
  2. 3
      lib/two_factor_authentication.rb
  3. 8
      lib/two_factor_authentication/models/two_factor_authenticatable.rb
  4. 8
      spec/lib/two_factor_authentication/models/two_factor_authenticatable_spec.rb
  5. 2
      spec/support/features_spec_helper.rb

7
README.md

@ -38,11 +38,12 @@ Add the following line to your model to fully enable two-factor auth:
has_one_time_password has_one_time_password
Set config values if desired for maximum second factor attempts count and allowed time drift for one-time passwords: Set config values, if desired, for maximum second factor attempts count, allowed time drift, and OTP length.
```ruby ```ruby
config.max_login_attempts = 3 config.max_login_attempts = 3
config.allowed_otp_drift_seconds = 30 config.allowed_otp_drift_seconds = 30
config.otp_length = 6
``` ```
Override the method to send one-time passwords in your model, this is automatically called when a user logs in: Override the method to send one-time passwords in your model, this is automatically called when a user logs in:
@ -66,11 +67,12 @@ Add the following line to your model to fully enable two-factor auth:
has_one_time_password has_one_time_password
Set config values if desired for maximum second factor attempts count and allowed time drift for one-time passwords: Set config values, if desired, for maximum second factor attempts count, allowed time drift, and OTP length.
```ruby ```ruby
config.max_login_attempts = 3 config.max_login_attempts = 3
config.allowed_otp_drift_seconds = 30 config.allowed_otp_drift_seconds = 30
config.otp_length = 6
``` ```
Override the method to send one-time passwords in your model, this is automatically called when a user logs in: Override the method to send one-time passwords in your model, this is automatically called when a user logs in:
@ -81,6 +83,7 @@ def send_two_factor_authentication_code
end end
``` ```
### Customisation and Usage ### Customisation and Usage
By default second factor authentication enabled for each user, you can change it with this method in your User model: By default second factor authentication enabled for each user, you can change it with this method in your User model:

3
lib/two_factor_authentication.rb

@ -13,6 +13,9 @@ module Devise
mattr_accessor :allowed_otp_drift_seconds mattr_accessor :allowed_otp_drift_seconds
@@allowed_otp_drift_seconds = 30 @@allowed_otp_drift_seconds = 30
mattr_accessor :otp_length
@@otp_length = 6
end end
module TwoFactorAuthentication module TwoFactorAuthentication

8
lib/two_factor_authentication/models/two_factor_authenticatable.rb

@ -20,19 +20,19 @@ module Devise
end end
end end
end end
::Devise::Models.config(self, :max_login_attempts, :allowed_otp_drift_seconds) ::Devise::Models.config(self, :max_login_attempts, :allowed_otp_drift_seconds, :otp_length)
end end
module InstanceMethodsOnActivation module InstanceMethodsOnActivation
def authenticate_otp(code, options = {}) def authenticate_otp(code, options = {})
totp = ROTP::TOTP.new(self.otp_column) totp = ROTP::TOTP.new(self.otp_column, { digits: options[:otp_length] || self.class.otp_length })
drift = options[:drift] || self.class.allowed_otp_drift_seconds drift = options[:drift] || self.class.allowed_otp_drift_seconds
totp.verify_with_drift(code, drift) totp.verify_with_drift(code, drift)
end end
def otp_code(time = Time.now) def otp_code(time = Time.now, options = {})
ROTP::TOTP.new(self.otp_column).at(time, true) ROTP::TOTP.new(self.otp_column, { digits: options[:otp_length] || self.class.otp_length }).at(time, true)
end end
def provisioning_uri(account = nil, options = {}) def provisioning_uri(account = nil, options = {})

8
spec/lib/two_factor_authentication/models/two_factor_authenticatable_spec.rb

@ -21,11 +21,15 @@ describe Devise::Models::TwoFactorAuthenticatable, '#otp_code' do
subject subject
end end
it "should be configured length" do
expect(subject.length).to eq(Devise.otp_length)
end
context "with a known time" do context "with a known time" do
let(:time) { 1392852756 } let(:time) { 1392852756 }
it "should return a known result" do it "should return a known result" do
expect(subject).to eq('562202') expect(subject).to eq("0000000524562202".split(//).last(Devise.otp_length).join)
end end
end end
@ -33,7 +37,7 @@ describe Devise::Models::TwoFactorAuthenticatable, '#otp_code' do
let(:time) { 1393065856 } let(:time) { 1393065856 }
it "should return a known result padded with zeroes" do it "should return a known result padded with zeroes" do
expect(subject).to eq('007672') expect(subject).to eq("0000001608007672".split(//).last(Devise.otp_length).join)
end end
end end
end end

2
spec/support/features_spec_helper.rb

@ -8,7 +8,7 @@ module FeaturesSpecHelper
def complete_sign_in_form_for(user) def complete_sign_in_form_for(user)
fill_in "Email", with: user.email fill_in "Email", with: user.email
fill_in "Password", with: 'password' fill_in "Password", with: 'password'
click_button "Sign in" click_button "Log in"
end end
end end

Loading…
Cancel
Save