module SecondStep::Models::ApplicationUserLink

Public Class Methods

check_entropy!() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 43
def check_entropy!
  raise NotEnoughEntropyForPhraseError unless enough_entropy?
end
config_reader(name, config_property=name) click to toggle source

ORM implementation:

Attributes: secret, uuid Belongs to: application_user

# File lib/second_step/models/application_user_link.rb, line 15
def self.config_reader(name, config_property=name)
  instance_eval { define_method name do
    SecondStep.config.send config_property
  end }
  module_function name
end
enough_entropy?() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 38
def enough_entropy?
  entropy > min_entropy
end

Public Instance Methods

checksum_valid?(secret = self.secret) click to toggle source

A simple check to see if the secret's checksum is correct. This prevents a large amount of typos, but doesn't do anything else.

# File lib/second_step/models/application_user_link.rb, line 50
def checksum_valid?(secret = self.secret)
  Digest::MD5.base64digest(secret.chop)[0] == secret[-1]
end
decode_token(token) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 98
def decode_token(token)
  rsa_data = decode_and_verify_rsa_token! token
  hmac_data = decode_and_verify_hmac_token! rsa_data[:token]
  return rsa_data, hmac_data
end
random_delimiter() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 67
def random_delimiter
  delimiters[SecureRandom.random_number(delimiters.length)]
end
random_word() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 71
def random_word
  word_number = SecureRandom.random_number word_list_count
  File.open(word_list_path, 'r') do |list|
    word = nil
    # This iterates through the entire file to pre
    list.each_line.each_with_index do |w, i|
      w = w.chomp
      word = w if word_number == i
    end
    word
  end
end
rsa_token(*args, **opts) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 93
def rsa_token(*args, **opts)
  JWT.encode self.rsa_token_payload(*args, **opts), private_key, jwt_rsa_algorithm
end
Also aliased as: token
secret=(t) click to toggle source
Calls superclass method
# File lib/second_step/models/application_user_link.rb, line 54
def secret=(t)
  super t ? t << Digest::MD5.base64digest(t)[0] : t
end
secret_phrase() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 62
def secret_phrase
  check_entropy!
  self.secret = phrase_length.times.map{ random_word }.join(random_delimiter) + ' '
end
secret_qr() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 84
def secret_qr
  self.secret = SecureRandom.base64 qr_length - 1
  RQRCode::QRCode.new self.secret
end
secret_string() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 58
def secret_string
  self.secret = SecureRandom.base64 secret_string_length - 1
end
token(*args, **opts)
Alias for: rsa_token
uuid() click to toggle source
Calls superclass method
# File lib/second_step/models/application_user_link.rb, line 89
def uuid
  super || self.uuid = SecureRandom.uuid
end

Protected Instance Methods

decode_and_verify_hmac_token!(token) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 170
def decode_and_verify_hmac_token!(token)
  verify_hmac_token! decode_hmac_token(token)
end
decode_and_verify_rsa_token!(token) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 150
def decode_and_verify_rsa_token!(token)
  verify_token! decode_rsa_token(token)
end
decode_hmac_token(token) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 174
def decode_hmac_token(token)
  payload, _ = JWT.decode token, secret, true, {
    algorithm: jwt_hmac_algorithm,
    iss: application_id, verify_iss: true,
    aud: secondstep_aud
  }
  payload.with_indifferent_access[:data]
end
decode_rsa_token(token) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 154
def decode_rsa_token(token)
  payload, _ = JWT.decode token, public_key, true, {
    algorithm: jwt_rsa_algorithm,
    iss: application_id, verify_iss: true,
    aud: secondstep_aud
  }
  payload = payload.with_indifferent_access
  payload[:data]
end
hmac_token(payload: self.hmac_token_payload, secret: self.secret) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 130
def hmac_token(payload: self.hmac_token_payload, secret: self.secret)
  JWT.encode payload, secret, jwt_hmac_algorithm
end
hmac_token_payload() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 134
def hmac_token_payload
  payload = {
    data: {
      public_key: public_key,
      uuid: uuid,
      app_user_id: application_user.uuid
    },
    exp: 3.days.from_now.to_i,
    aud: secondstep_aud,
    iat: Time.now.to_i,
    jti: SecureRandom.uuid,
    iss: application_id
  }
  payload
end
rsa_token_payload(ip, meta_text: nil, action_url: nil, user_agent: nil, username: nil, email: nil) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 106
def rsa_token_payload(ip, meta_text: nil, action_url: nil, user_agent: nil,
                          username: nil, email: nil)
  payload = {
    data: {
      token: self.hmac_token,
      uuid: uuid,
      app_user_id: application_user.uuid,
      meta: {
        ip: ip,
        meta_text: meta_text,
        user_agent: user_agent,
        username: username,
        email: email
      }
    },
    exp: 3.days.from_now.to_i,
    aud: secondstep_aud,
    iat: Time.now.to_i,
    jti: SecureRandom.uuid,
    iss: application_id
  }
  payload
end
verify_hmac_token!(data) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 183
def verify_hmac_token!(data)
  raise SecondStep::PublicKeyMismatch unless data[:public_key] == public_key.to_s
  verify_token! data
end
verify_token!(data) click to toggle source
# File lib/second_step/models/application_user_link.rb, line 164
def verify_token!(data)
  raise SecondStep::AppUserMismatch unless data[:app_user_id] == application_user.uuid
  raise SecondStep::UserLinkMismatch unless data[:uuid] == uuid
  data
end

Private Instance Methods

check_entropy!() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 43
def check_entropy!
  raise NotEnoughEntropyForPhraseError unless enough_entropy?
end
enough_entropy?() click to toggle source
# File lib/second_step/models/application_user_link.rb, line 38
def enough_entropy?
  entropy > min_entropy
end