refactor: split if/else in Accounts.User password helpers

- do_hash_password/3: move the changeset.valid? branch out of the
  `if` into apply_hash/3, dispatched on the boolean. The bcrypt 72-byte
  cap and plaintext-scrubbing steps now live in one clear function head.
- validate_current_password/2: dispatch on valid_password?/2 via
  check_current_password/2 so the add_error branch is its own clause.

No behavior change; all 24 Accounts tests still pass and dialyzer stays
clean.
This commit is contained in:
Graham McIntire 2026-04-23 14:24:24 -05:00
parent edd5a8b30c
commit c910f9a432
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -84,19 +84,22 @@ defmodule Aprsme.Accounts.User do
end
defp do_hash_password(changeset, true, password) when is_binary(password) do
if changeset.valid? do
changeset
# If using Bcrypt, then further validate it is at most 72 bytes long
|> validate_length(:password, max: 72, count: :bytes)
|> put_change(:hashed_password, Bcrypt.hash_pwd_salt(password))
|> delete_change(:password)
else
changeset
end
apply_hash(changeset.valid?, changeset, password)
end
defp do_hash_password(changeset, _, _), do: changeset
# Bcrypt has a 72-byte key cap, so we enforce that before hashing and
# drop the plaintext from the changeset so it can't accidentally leak.
defp apply_hash(true, changeset, password) do
changeset
|> validate_length(:password, max: 72, count: :bytes)
|> put_change(:hashed_password, Bcrypt.hash_pwd_salt(password))
|> delete_change(:password)
end
defp apply_hash(false, changeset, _password), do: changeset
defp maybe_validate_unique_email(changeset, opts) do
validate_email? = Keyword.get(opts, :validate_email, true)
do_validate_unique_email(changeset, validate_email?)
@ -200,10 +203,9 @@ defmodule Aprsme.Accounts.User do
Validates the current password otherwise adds an error to the changeset.
"""
def validate_current_password(changeset, password) do
if valid_password?(changeset.data, password) do
changeset
else
add_error(changeset, :current_password, "is not valid")
end
check_current_password(valid_password?(changeset.data, password), changeset)
end
defp check_current_password(true, changeset), do: changeset
defp check_current_password(false, changeset), do: add_error(changeset, :current_password, "is not valid")
end