pub struct AuthToken {
pub id: i64,
pub user_id: ForeignKey<AuthUser>,
pub key_hash: String,
pub name: String,
pub created_at: DateTime<Utc>,
pub last_used_at: Option<DateTime<Utc>>,
}Expand description
One row per active bearer token. A user can hold any number of
these (one per device / per environment / per CI runner). The
name column is the human label shown in admin / management
listings; it has no functional role.
The key_hash column carries base64(sha256(plaintext)) (43
chars, URL-safe, no padding) under a UNIQUE index so a digest
collision is forbidden. The plaintext lives only in memory at
creation time and in whatever client storage the caller chose.
last_used_at is updated best-effort on every successful lookup
(a failure to write does not fail the auth). Useful for “this
token has not been used in 90 days, prune it” cleanup jobs.
Fields§
§id: i64§user_id: ForeignKey<AuthUser>Owning user. FK against auth_user.id. ON DELETE CASCADE
— when a user row is deleted, every token they hold goes
with them. Otherwise revoking a user would leave orphan
tokens that no longer match any user via the auth lookup,
silently failing 401 instead of cleanly disappearing.
key_hash: Stringbase64(sha256(plaintext)) — 43 chars, URL-safe, no pad. The
UNIQUE constraint protects against the (cryptographically
negligible) chance of two random keys hashing to the same
digest, and lets the lookup path stop at the first match.
name: StringHuman label. Shown in admin listings and the management CLI; never used for lookup. Defaults to “default” when the caller does not name the token.
created_at: DateTime<Utc>§last_used_at: Option<DateTime<Utc>>Last time this token authenticated a request. NULL until the first successful lookup.
Implementations§
Source§impl AuthToken
impl AuthToken
pub const ID: IntCol<Self> = auth_token::ID
pub const USER_ID: ForeignKeyCol<Self> = auth_token::USER_ID
pub const KEY_HASH: StrCol<Self> = auth_token::KEY_HASH
pub const NAME: StrCol<Self> = auth_token::NAME
pub const CREATED_AT: DateTimeCol<Self> = auth_token::CREATED_AT
pub const LAST_USED_AT: NullableDateTimeCol<Self> = auth_token::LAST_USED_AT
Source§impl AuthToken
impl AuthToken
Sourcepub async fn create_for(
user: &AuthUser,
name: &str,
) -> Result<(Self, PlaintextToken), AuthError>
pub async fn create_for( user: &AuthUser, name: &str, ) -> Result<(Self, PlaintextToken), AuthError>
Mint a new bearer token for user. Returns the persisted
row plus the plaintext key — the caller is responsible for
surfacing the plaintext to whoever needs it (response body,
admin “copy this” UI). The plaintext is not recoverable from
the row alone after this call returns.
name is a free-form label shown in admin and management
listings. Pass "" to default to "default".
Trait Implementations§
Source§impl<'de> Deserialize<'de> for AuthToken
impl<'de> Deserialize<'de> for AuthToken
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<'a, R: Row> FromRow<'a, R> for AuthTokenwhere
&'a str: ColumnIndex<R>,
i64: Decode<'a, R::Database> + Type<R::Database>,
ForeignKey<AuthUser>: Decode<'a, R::Database> + Type<R::Database>,
String: Decode<'a, R::Database> + Type<R::Database>,
DateTime<Utc>: Decode<'a, R::Database> + Type<R::Database>,
Option<DateTime<Utc>>: Decode<'a, R::Database> + Type<R::Database>,
impl<'a, R: Row> FromRow<'a, R> for AuthTokenwhere
&'a str: ColumnIndex<R>,
i64: Decode<'a, R::Database> + Type<R::Database>,
ForeignKey<AuthUser>: Decode<'a, R::Database> + Type<R::Database>,
String: Decode<'a, R::Database> + Type<R::Database>,
DateTime<Utc>: Decode<'a, R::Database> + Type<R::Database>,
Option<DateTime<Utc>>: Decode<'a, R::Database> + Type<R::Database>,
Source§impl HydrateRelated for AuthToken
impl HydrateRelated for AuthToken
Source§fn fk_id_for(&self, field_name: &str) -> Option<Value>
fn fk_id_for(&self, field_name: &str) -> Option<Value>
field_name,
or None if the field doesn’t exist on this model or is not a FK. Read moreSource§fn hydrate_fk(&mut self, field_name: &str, row: &Value)
fn hydrate_fk(&mut self, field_name: &str, row: &Value)
ForeignKey<U>.resolved for the field named field_name by
deserialising row as the target model type. Read moreSource§fn set_m2m_parent_ids(&mut self)
fn set_m2m_parent_ids(&mut self)
parent_id cache on every M2M<U> field this model
owns. Closes the second BUG-16 gap: without this, m2m.add(&t)
silently writes a junction row with parent_id = 0 because the
macro skips M2M fields in the FromRow decode path. Read moreSource§fn pk_as_json(&self) -> Option<Value>
fn pk_as_json(&self) -> Option<Value>
serde_json::Value, whatever
the PK type — i64, String, uuid::Uuid, a custom newtype.
The relation-hydration paths (prefetch_related, reverse-FK and
reverse-OneToOne collection) bucket children by the parent’s PK,
and keying those buckets on a Value (canonicalised via
crate::orm::pk_key) lets UUID- and slug-PK models flow through
too, not just i64. Read moreSource§fn set_m2m_resolved_json(&mut self, field_name: &str, rows: Vec<Value>)
fn set_m2m_resolved_json(&mut self, field_name: &str, rows: Vec<Value>)
M2M<U>
field’s resolved slot. Called by QuerySet::prefetch_related
(gap #19) after a batched JOIN through the junction table
returns one Vec per parent. Read moreSource§fn set_reverse_fk_resolved_json(&mut self, field_name: &str, rows: Vec<Value>)
fn set_reverse_fk_resolved_json(&mut self, field_name: &str, rows: Vec<Value>)
ReverseSet<C> field’s resolved slot. Counterpart
to set_m2m_resolved_json but for reverse-FK collections
(one parent, many children pointing at it via a FK column). Read moreSource§fn set_one_to_one_resolved_json(&mut self, field_name: &str, row: Option<Value>)
fn set_one_to_one_resolved_json(&mut self, field_name: &str, row: Option<Value>)
set_reverse_fk_resolved_json. Called by prefetch_related
with Some(child_json) when the runtime FK lookup found
exactly one matching child, or None when no child matched
(the slot still flips is_loaded() to true). Read moreSource§fn take_pending_m2m_into(&mut self, _dest: &mut Self)
fn take_pending_m2m_into(&mut self, _dest: &mut Self)
self into dest,
field by field. The typed create() builds its INSERT from the
caller’s instance, then reads a fresh row back from the DB
(carrying the autoincremented PK) — the pending ids staged by the
Form derive live on the caller’s instance, not the readback row.
This hook transfers them across so write_pending_m2m on the
readback row (which has the real parent_id seeded) finds them.
Default: no-op for models with no M2M fields.Source§fn write_pending_m2m<'a>(
&'a mut self,
) -> Pin<Box<dyn Future<Output = Result<(), WriteError>> + Send + 'a>>
fn write_pending_m2m<'a>( &'a mut self, ) -> Pin<Box<dyn Future<Output = Result<(), WriteError>> + Send + 'a>>
parent_id + junction_table
(seeded by set_m2m_parent_ids) and the pending child ids, and
calls set_junction_dynamic. Default: no-op for models with no
M2M fields. Read moreSource§impl Model for AuthToken
impl Model for AuthToken
Source§const NAME: &'static str = "AuthToken"
const NAME: &'static str = "AuthToken"
Source§const TABLE: &'static str = "auth_token"
const TABLE: &'static str = "auth_token"
snake_case of the struct name unless #[umbral(table = "...")]
overrides it.Source§const APP_LABEL: &'static str = "app"
const APP_LABEL: &'static str = "app"
Source§const DISPLAY: &'static str = "AuthToken"
const DISPLAY: &'static str = "AuthToken"
Self::NAME. Read moreSource§const ICON: &'static str = "database"
const ICON: &'static str = "database"
"database". Any valid Lucide icon name works; unknown
names are silently ignored by Lucide at render time. Read moreSource§const DATABASE: Option<&'static str> = ::core::option::Option::None
const DATABASE: Option<&'static str> = ::core::option::Option::None
AppBuilder::database(...). None (the
default) means “use whatever the owning plugin chose via
Plugin::database(), or \"default\" if neither side
overrode.” Read moreSource§const SINGLETON: bool = false
const SINGLETON: bool = false
true, the admin auto-redirects the
list view to the (sole) row’s edit form, hides the “+ New”
button, and surfaces the model as a settings-style screen.
The single-row settings model pattern. Set via
#[umbral(singleton)] on the struct. Closes BUG-9 in
bugs/tests/testBugs.md. Read moreSource§const SOFT_DELETE: bool = false
const SOFT_DELETE: bool = false
#[umbral(soft_delete)] on the struct. When true, the
framework treats this model as having a deleted_at: Option<DateTime<Utc>> column (which the user MUST declare
— derive macros can’t add fields to the input struct), and: Read moreSource§const UNIQUE_TOGETHER: &'static [&'static [&'static str]]
const UNIQUE_TOGETHER: &'static [&'static [&'static str]]
#[umbral(unique_together = [["a", "b"]])]. Closes BUG-6 in
bugs/tests/testBugs.md. Default empty; the migration engine
emits one UNIQUE (col1, col2) clause per inner group on
CREATE TABLE.Source§const INDEXES: &'static [&'static [&'static str]]
const INDEXES: &'static [&'static [&'static str]]
#[umbral(indexes = [["tenant_id", "created_at"]])]. Closes
BUG-7. Default empty; the migration engine emits
CREATE INDEX IF NOT EXISTS idx_<table>_<col1>_<col2> after
the CREATE TABLE. Single-column indexes stay on the field
attribute (#[umbral(index)]).Source§const ORDERING: &'static [(&'static str, bool)]
const ORDERING: &'static [(&'static str, bool)]
ORDER BY clause, applied when a QuerySet terminates
without an explicit order_by. Each tuple is (column_name, is_descending). Set via
#[umbral(ordering = ["-published_at", "id"])] (leading -
flips to DESC). Closes BUG-8. Default empty.Source§const M2M_RELATIONS: &'static [M2MRelationSpec]
const M2M_RELATIONS: &'static [M2MRelationSpec]
Source§const REVERSE_FK_RELATIONS: &'static [ReverseFkRelationSpec]
const REVERSE_FK_RELATIONS: &'static [ReverseFkRelationSpec]
#[umbral(reverse_fk = "<fk_col>")] pub <name>: ReverseSet<C>.
Each entry tells prefetch_related how to fetch the children:
SELECT * FROM <target_table> WHERE <fk_column> IN (parent_pks)
then group by <fk_column> value, populate each parent’s
ReverseSet.resolved. Default empty; the macro emits one
entry per declared ReverseSet<C> field.Source§const ONE_TO_ONE_RELATIONS: &'static [OneToOneRelationSpec]
const ONE_TO_ONE_RELATIONS: &'static [OneToOneRelationSpec]
pub <name>: OneToOne<C> (no umbral attribute required).
Unlike REVERSE_FK_RELATIONS, the FK column on the child is
not named at macro time — prefetch_related looks it up at
runtime by scanning the child’s FIELDS for the UNIQUE FK
pointing back at this model’s table. Exactly one match
required; 0 or 2+ matches surface a loud error naming the
ambiguity.Source§type PrimaryKey = i64
type PrimaryKey = i64
i64 only; UUID lands later.Source§fn primary_key(&self) -> i64
fn primary_key(&self) -> i64
Auto Trait Implementations§
impl Freeze for AuthToken
impl RefUnwindSafe for AuthToken
impl Send for AuthToken
impl Sync for AuthToken
impl Unpin for AuthToken
impl UnsafeUnpin for AuthToken
impl UnwindSafe for AuthToken
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ReverseRelations for Twhere
T: Model + HydrateRelated,
impl<T> ReverseRelations for Twhere
T: Model + HydrateRelated,
Source§fn reverse<C>(&self) -> Result<QuerySet<C>, ReverseError>where
C: Model + HydrateRelated,
fn reverse<C>(&self) -> Result<QuerySet<C>, ReverseError>where
C: Model + HydrateRelated,
QuerySet<C> of the children of type C
whose foreign key points at THIS instance. The FK column is
discovered from C::FIELDS (the field whose fk_target == Self::TABLE): Read moreSource§fn reverse_via<C>(&self, fk_col: &str) -> Result<QuerySet<C>, ReverseError>where
C: Model + HydrateRelated,
fn reverse_via<C>(&self, fk_col: &str) -> Result<QuerySet<C>, ReverseError>where
C: Model + HydrateRelated,
reverse, but with the FK column on C named explicitly
— the escape hatch for when C has more than one FK to this
parent. The column is validated to exist AND to be an FK to
Self::TABLE.