A row of macaw_auth_users, the native backend's users, in the host's
repo (mix macaw_auth.gen.migration writes the table's migration).
usernameis stored normalized (normalize_username/1: trimmed, lower case), with a unique index, soAliceandaliceare one user on every database without a case-insensitive collation.hashed_passwordis nil for a directory user: the directory checks their password, and thePasswordsource does not know them.sourcenames where the identity came from:"local"(thePasswordsource) or an LDAP source's name, which owns the row and re-derives its roles at each sign-in.rolesis{:array, :string}: a native array on Postgres, and on SQLite a JSON text column, which ecto_sqlite3 encodes and decodes for an array field itself. One migration serves both; no query needs to look inside the list.disabled_atset means refused, whatever the password.extraholds what a source knows beyond these (an LDAP DN, its id attribute, email) and the host's own fields.totp_secret_sealed,totp_enabled_at,totp_last_step: the second factor (Macaw.Auth.Native.Totp), added by their own migration. The secret is sealed (Macaw.Auth.Native.Seal), never stored as it is; an enrollment is pending whiletotp_enabled_atis nil; the last accepted step is what makes a code single-use. None of them is cast bychangeset/2: onlyTotpwrites them, each by a conditional update.
Summary
Functions
A changeset for a new or changed user; the username is normalized.
A username trimmed and lower-cased: {:ok, name}, or
{:error, :invalid_username} unless it is 1–64 characters of
[a-z0-9._@+-], starting with a letter or digit. Nothing else is
rewritten, so two distinct inputs never become one user.
Types
@type t() :: %Macaw.Auth.Native.UserRecord{ __meta__: term(), disabled_at: term(), display_name: term(), extra: term(), hashed_password: term(), id: term(), inserted_at: term(), must_change_password: term(), roles: term(), source: term(), totp_enabled_at: term(), totp_last_step: term(), totp_secret_sealed: term(), updated_at: term(), username: term() }
Functions
@spec changeset(t(), map()) :: Ecto.Changeset.t()
A changeset for a new or changed user; the username is normalized.
A username trimmed and lower-cased: {:ok, name}, or
{:error, :invalid_username} unless it is 1–64 characters of
[a-z0-9._@+-], starting with a letter or digit. Nothing else is
rewritten, so two distinct inputs never become one user.