UserRepository¶
The adapter between crudauth's logical field names and your user model's actual columns.
Configure the mapping with column_map= on CRUDAuth.
crudauth.repository.UserRepository
¶
UserRepository(
model: type[Any],
column_map: dict[str, str] | None = None,
register_extra_fields: Iterable[str] | None = None,
)
get
¶
Read a logical field off user, or default if the column is absent.
set_field
¶
Set a logical field on user by its resolved column name.
get_by_id
async
¶
Fetch the user by primary key, or None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db
|
AsyncSession
|
Active async session. |
required |
user_id
|
Any
|
PK value; coerced to the column's Python type first (so a
string |
required |
Returns:
| Type | Description |
|---|---|
Any | None
|
The user row, or |
get_by_email
async
¶
Fetch the user by (canonicalized) email, or None.
get_by_username
async
¶
Fetch the user by username, or None.
get_by_identifier
async
¶
Look up by email when the identifier contains @, else by username.
get_by_oauth
async
¶
Look up by {provider}_id.
Note
Assumes provider is a validated/registered provider name (the
OAuth router checks it before this is reached) - it builds an
attribute name from the argument, so an unvalidated value would
probe arbitrary columns (it returns None for any column the
model lacks, so the blast radius is a missed lookup, not a leak).
gated_register_fields
¶
Which of schema_fields are crudauth privileged fields (always dropped).
droppable_register_fields
¶
Which of schema_fields map to a real model column but are not
privileged and not opted in, so registration silently drops them.
These are the fields a developer most likely expects to persist (e.g. a
full_name column they added to register_schema) and won't, until
they add the name to register_extra_fields.
filter_registration_data
¶
Keep only the allowlisted registration fields; drop everything else.
A field survives only if it is in :data:REGISTRATION_ALLOWED_FIELDS or
was opted in via register_extra_fields (matched by logical or mapped
column name) - and is never one of crudauth's privileged logical fields
(is_superuser, email_verified, hashed_password, the oauth
linkage, the PK), which stay gated even if mistakenly opted in. Unknown
app columns (role, credits, ...) are dropped unless explicitly
opted in, so a custom register_schema can't turn /register into a
privilege-escalation or mass-assignment endpoint.
create
async
¶
Insert a user from logical-field data and return the row.
Note
Owns the transaction boundary - commits and refreshes on the passed-in session. Apps using a request-scoped "commit at the end" pattern should know auth writes commit eagerly.
Note
Email is canonicalized off the resolved column: kwargs is keyed
by actual column names, so a column_map that renames email
would otherwise be stored un-normalized.
update
async
¶
Apply logical-field data to user and return it.
Note
Commits and refreshes eagerly on the passed-in session (see create).
token_version
¶
The user's credential epoch (0 if the model has no such column).
increment_token_version
async
¶
Bump the credential epoch, revoking outstanding bearer tokens.
A no-op when the model has no token_version column (bearer tokens
then simply aren't epoch-revocable; the limitation is documented).
to_dict
¶
Project a user row onto the logical contract (for hooks).
Note
Contract-only by design - the dict holds the crudauth logical fields
(id, email, ...), not your app's own columns. A hook that
needs full_name should re-load the row via db using the
id, not expect it in this dict.