class CryptIdent::ResetPassword

Reset Password using previously-sent Reset Token for non-Authenticated User

This class *is not* part of the published API. @private

Constants

LogicError

Attributes

current_user[R]

rubocop:enable Naming/RescuedExceptionsVariableName

Public Class Methods

new() click to toggle source
# File lib/crypt_ident/reset_password.rb, line 128
def initialize
  @current_user = :unassigned
end

Public Instance Methods

call(token, new_password, current_user: nil) click to toggle source

rubocop:disable Naming/RescuedExceptionsVariableName

# File lib/crypt_ident/reset_password.rb, line 133
def call(token, new_password, current_user: nil)
  init_ivars(current_user)
  verify_no_current_user(token)
  user = verify_token(token)
  Success(user: update(user, new_password))
rescue LogicError => err
  report_failure(err)
end

Private Instance Methods

encrypted(password) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 147
def encrypted(password)
  BCrypt::Password.create(password)
end
expired_token?(entity) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 151
def expired_token?(entity)
  prea = entity.password_reset_expires_at
  # Calling this on a non-reset Entity is treated as expiring at the epoch
  Time.now > Hanami::Utils::Kernel.Time(prea.to_i)
end
init_ivars(current_user) click to toggle source

Reek sees a :reek:ControlParameter. Yep.

# File lib/crypt_ident/reset_password.rb, line 158
def init_ivars(current_user)
  guest_user = CryptIdent.config.guest_user
  current_user ||= guest_user
  @current_user = guest_user.class.new(current_user)
end
matching_record_for(token) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 164
def matching_record_for(token)
  Array(CryptIdent.config.repository.find_by_token(token)).first
end
new_attribs(password) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 168
def new_attribs(password)
  { password_hash: encrypted(password), password_reset_expires_at: nil,
    token: nil }
end
raise_logic_error(code, token) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 173
def raise_logic_error(code, token)
  payload = { code: code, token: token }
  raise LogicError, Marshal.dump(payload)
end
report_failure(error) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 178
def report_failure(error)
  # rubocop:disable Security/MarshalLoad
  error_data = Marshal.load(error.message)
  # rubocop:enable Security/MarshalLoad
  Failure(error_data)
end
update(user, password) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 185
def update(user, password)
  CryptIdent.config.repository.update(user.id, new_attribs(password))
end
validate_match_and_token(match, token) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 189
def validate_match_and_token(match, token)
  raise_logic_error(:token_not_found, token) unless match
  raise_logic_error(:expired_token, token) if expired_token?(match)
  match
end
verify_no_current_user(token) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 195
def verify_no_current_user(token)
  return if current_user.guest?

  payload = { code: :invalid_current_user, token: token }
  raise LogicError, Marshal.dump(payload)
end
verify_token(token) click to toggle source
# File lib/crypt_ident/reset_password.rb, line 202
def verify_token(token)
  match = matching_record_for(token)
  validate_match_and_token(match, token)
end