Module: Devise::Models::DeviseXfactorAuthenticatable::InstanceMethodsOnActivation

Defined in:
lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb

Instance Method Summary collapse

Instance Method Details

#authenticate_direct_otp(code) ⇒ Object



32
33
34
35
36
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 32

def authenticate_direct_otp(code)
  return false if direct_otp.nil? || direct_otp != code || direct_otp_expired?
  clear_direct_otp
  true
end

#authenticate_otp(code, options = {}) ⇒ Object



26
27
28
29
30
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 26

def authenticate_otp(code, options = {})
  return true if direct_otp && authenticate_direct_otp(code)
  return true if totp_enabled? && authenticate_totp(code, options)
  false
end

#authenticate_totp(code, options = {}) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 38

def authenticate_totp(code, options = {})
  totp_secret = options[:otp_secret_key] || otp_secret_key
  digits = options[:otp_length] || self.class.otp_length
  drift = options[:drift] || self.class.allowed_otp_drift_seconds
  raise "authenticate_totp called with no otp_secret_key set" if totp_secret.nil?
  totp = ROTP::TOTP.new(totp_secret, digits: digits)
  new_timestamp = totp.verify(
    without_spaces(code), 
    drift_ahead: drift, drift_behind: drift, after: totp_timestamp
  )
  return false unless new_timestamp
  self.totp_timestamp = new_timestamp
  true
end

#confirm_totp_secret(secret, code, options = {}) ⇒ Object



90
91
92
93
94
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 90

def confirm_totp_secret(secret, code, options = {})
  return false unless authenticate_totp(code, {otp_secret_key: secret})
  self.otp_secret_key = secret
  true
end

#create_direct_otp(options = {}) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 100

def create_direct_otp(options = {})
  # Create a new random OTP and store it in the database
  digits = options[:length] || self.class.direct_otp_length || 6
  update(
    direct_otp: random_base10(digits),
    direct_otp_sent_at: Time.now.utc
  )
end

#direct_otp_expired?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 109

def direct_otp_expired?
  Time.now.utc > direct_otp_sent_at + self.class.direct_otp_valid_for
end

#generate_totp_secretObject



96
97
98
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 96

def generate_totp_secret
  ROTP::Base32.random_base32
end

#max_login_attemptsObject



82
83
84
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 82

def 
  self.class.
end

#max_login_attempts?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 78

def 
  second_factor_attempts_count.to_i >= .to_i
end

#need_devise_xfactor_authentication?(request) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 61

def need_devise_xfactor_authentication?(request)
  true
end

#provisioning_uri(account = nil, options = {}) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 53

def provisioning_uri( = nil, options = {})
  totp_secret = options[:otp_secret_key] || otp_secret_key
  options[:digits] ||= options[:otp_length] || self.class.otp_length
  raise "provisioning_uri called with no otp_secret_key set" if totp_secret.nil?
   ||= email if respond_to?(:email)
  ROTP::TOTP.new(totp_secret, options).provisioning_uri()
end

#send_devise_xfactor_authentication_code(code) ⇒ Object

Raises:

  • (NotImplementedError)


74
75
76
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 74

def send_devise_xfactor_authentication_code(code)
  raise NotImplementedError.new("No default implementation - please define in your class.")
end

#send_new_otp(options = {}) ⇒ Object



65
66
67
68
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 65

def send_new_otp(options = {})
  create_direct_otp options
  send_devise_xfactor_authentication_code(direct_otp)
end

#send_new_otp_after_login?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 70

def send_new_otp_after_login?
  !totp_enabled?
end

#totp_enabled?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/devise_xfactor_authentication/models/devise_xfactor_authenticatable.rb', line 86

def totp_enabled?
  respond_to?(:otp_secret_key) && !otp_secret_key.nil?
end