Identity contract¶
An account's shape (which columns exist) is read from your model; IdentityConfig carries the
intent a schema can't express, the login resolution order and the recovery factor, validated
against the model when CRUDAuth is built so a config that contradicts the model fails at
startup rather than splitting into a second source of truth.
make_auth_identity(identifiers=, recovery=, oauth=)builds the user-column mixin for a shape;AuthUserMixinis its default output (email + username login, email recovery).IdentityConfig(login=, recovery=)declares the intent; pass it asCRUDAuth(identity=...).
See the account-shape recipes for end-to-end examples.
crudauth.identity.IdentityConfig
dataclass
¶
IdentityConfig(
login: list[str] = (lambda: ["email", "username"])(),
recovery: str | None = "email",
)
How an account's identity behaves, validated against the model at construction.
Attributes:
| Name | Type | Description |
|---|---|---|
login |
list[str]
|
Logical fields a login identifier is matched against, in order; first match wins. Each must be a unique column on the model (asserted at construction, which is what makes first-match-wins safe). |
recovery |
str | None
|
The single field verify/reset/change is delivered against, or
|
Example
crudauth.models.mixin.make_auth_identity
¶
make_auth_identity(
*,
identifiers: Iterable[str] = ("email", "username"),
recovery: str | None = "email",
oauth: bool = True,
) -> type[Any]
Build a declarative mixin carrying crudauth's user columns for one account shape.
The model is the source of truth for shape: this emits the columns, and
CRUDAuth reads them back at construction, so the
two can't disagree. username, hashed_password, the status flags,
token_version, and the timestamps are always emitted; email and the
oauth-linkage columns are conditional.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
identifiers
|
Iterable[str]
|
Logical fields a user may log in with. Each becomes a
|
('email', 'username')
|
recovery
|
str | None
|
The single field recovery (verify/reset) is delivered against,
or |
'email'
|
oauth
|
bool
|
Emit the oauth-linkage columns ( |
True
|
Returns:
| Type | Description |
|---|---|
type[Any]
|
A declarative mixin class. Inherit it on your model alongside |
Example
# the default - email + username login, email recovery (today's shape)
class User(Base, AuthUserMixin):
__tablename__ = "users"
# username-only login, phone recovery
Identity = make_auth_identity(identifiers=["username"], recovery="phone")
class User(Base, Identity):
__tablename__ = "users"
phone: Mapped[str | None] = mapped_column(unique=True, default=None)