class CryptIdent::ChangePassword

Include and interact with `CryptIdent` to add authentication to a Hanami controller action.

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

Constants

LogicError

Attributes

repo[R]

rubocop:enable Naming/RescuedExceptionsVariableName

user[R]

rubocop:enable Naming/RescuedExceptionsVariableName

Public Class Methods

new(user:) click to toggle source
# File lib/crypt_ident/change_password.rb, line 119
def initialize(user:)
  @repo = CryptIdent.config.repository
  @user = user_from_param(user)
end

Public Instance Methods

call(current_password, new_password) click to toggle source

rubocop:disable Naming/RescuedExceptionsVariableName

# File lib/crypt_ident/change_password.rb, line 125
def call(current_password, new_password)
  verify_preconditions(current_password)

  success_result(new_password)
rescue LogicError => err
  failure_result(err.message)
end

Private Instance Methods

failure_result(error_message) click to toggle source
# File lib/crypt_ident/change_password.rb, line 141
def failure_result(error_message)
  Failure(code: error_message.to_sym)
end
raise_logic_error(code) click to toggle source
# File lib/crypt_ident/change_password.rb, line 145
def raise_logic_error(code)
  raise LogicError, code.to_s
end
success_result(new_password) click to toggle source
# File lib/crypt_ident/change_password.rb, line 149
def success_result(new_password)
  Success(user: update(new_password))
end
update(new_password) click to toggle source
# File lib/crypt_ident/change_password.rb, line 153
def update(new_password)
  updated_attribs = update_attribs(new_password)
  repo.update(user.id, updated_attribs)
end
update_attribs(new_password) click to toggle source
# File lib/crypt_ident/change_password.rb, line 170
def update_attribs(new_password)
  new_hash = ::BCrypt::Password.create(new_password)
  { password_hash: new_hash, updated_at: Time.now }
end
user_from_param(user) click to toggle source

The `user` param might have come from `Rack::Session` data, which doesn't support Ruby objects beyond native JSON types. Fortunately a) the definitions of equality and identity for two Entities compare

attribute values only; and

b) Hanami Entities can be freely *and implicitly* converted to and from

Hashes of their attributes.

So…this makes it all good. Except that Reek sees a :reek: ControlParameter for `user`. Pffft.

# File lib/crypt_ident/change_password.rb, line 166
def user_from_param(user)
  User.new(user || repo.guest_user)
end
valid_password?(password) click to toggle source
# File lib/crypt_ident/change_password.rb, line 175
def valid_password?(password)
  BCrypt::Password.new(user.password_hash) == password
end
verify_preconditions(current_password) click to toggle source
# File lib/crypt_ident/change_password.rb, line 179
def verify_preconditions(current_password)
  raise_logic_error :invalid_user if user.guest?
  raise_logic_error :bad_password unless valid_password?(current_password)
end