Skip to main content

User

Struct User 

Source
#[non_exhaustive]
pub struct User { pub id: i64, pub name: String, pub email: String, pub password: String, pub email_verified_at: Option<DateTime>, pub created_at: Option<DateTime>, pub updated_at: Option<DateTime>, pub extra: BTreeMap<String, Value>, }
Expand description

A row of the users table created by the Auth module.

Columns the app adds with its own migration (a role, a phone) are kept in extra: read them with user.get::<String>("role"), change them with user.set(&db, "role", "admin"), filter with User::where_eq("role", "admin"). Templates and JSON see them as the user’s own fields ({{ auth.user.role }}). A typed model on the same table (#[model(table = "users")] struct Member) works too.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§id: i64

The users row id; 0 before it is saved.

§name: String

The display name.

§email: String

The email address (Renox’s forms store it trimmed and lowercased).

§password: String

The Argon2 hash; never serialized, so it can’t leak into templates or JSON.

§email_verified_at: Option<DateTime>

When the email address was confirmed; None while unverified.

§created_at: Option<DateTime>

When the account was created.

§updated_at: Option<DateTime>

When the row was last saved.

§extra: BTreeMap<String, Value>

The app’s own columns, by name.

Implementations§

Source§

impl User

Source

pub async fn delete_account(&self, db: &Db) -> Result

Deletes the user (their tokens, notifications and sessions go with the row) and their data grid preferences. The account page’s “delete account” does this.

Source§

impl User

Source

pub async fn notifications( &self, db: &Db, limit: u32, ) -> Result<Vec<DatabaseNotification>>

The user’s notifications, newest first.

Source

pub async fn notifications_before( &self, db: &Db, before: i64, limit: u32, ) -> Result<Vec<DatabaseNotification>>

The user’s notifications older than the one with id before, newest first: the next page after a list ending at before.

Source

pub async fn notification( &self, db: &Db, id: i64, ) -> Result<Option<DatabaseNotification>>

One of the user’s notifications, or None if it isn’t theirs.

Source

pub async fn unread_notifications( &self, db: &Db, ) -> Result<Vec<DatabaseNotification>>

The user’s unread notifications, newest first.

Source

pub async fn unread_notification_count(&self, db: &Db) -> Result<i64>

How many of the user’s notifications are unread.

Source

pub async fn mark_notification_read(&self, db: &Db, id: i64) -> Result<bool>

Marks one of the user’s notifications read; returns whether it was theirs.

Source

pub async fn mark_notification_unread(&self, db: &Db, id: i64) -> Result<bool>

Marks one of the user’s notifications unread again; returns whether it was theirs.

Source

pub async fn delete_notification(&self, db: &Db, id: i64) -> Result<bool>

Deletes one of the user’s notifications; returns whether it was theirs.

Source

pub async fn delete_notifications(&self, db: &Db) -> Result<u64>

Deletes all the user’s notifications; returns how many there were.

Source

pub async fn mark_all_notifications_read(&self, db: &Db) -> Result<u64>

Marks all the user’s unread notifications read; returns how many there were.

Source§

impl User

Source

pub async fn assign_role(&self, db: &Db, role: &str) -> Result

Gives the user the existing role role (see permissions::define_role) everywhere and for good.

Source

pub fn assign_role_in<'a>( &self, db: &'a Db, role: &'a str, scope: &Scope, ) -> AssignRole<'a>

Gives the user the existing role role in scope (a store, a team), optionally from / until a date; .await it: user.assign_role_in(&db, "manager", &Scope::of(&store)).until(end).await?. It counts when that scope is the request’s (set_scope) and for User::has_permission_in on that scope. With Scope::global, it is a global role with dates.

Source

pub async fn remove_role(&self, db: &Db, role: &str) -> Result

Takes the global role role away from the user (roles given in a scope stay; see User::remove_role_in).

Source

pub async fn remove_role_in(&self, db: &Db, role: &str, scope: &Scope) -> Result

Takes the role role in scope away from the user.

Source

pub async fn sync_roles(&self, db: &Db, roles: &[&str]) -> Result

Makes the user’s global roles exactly roles (each must exist); roles given in a scope stay.

Source

pub async fn sync_roles_in( &self, db: &Db, roles: &[&str], scope: &Scope, ) -> Result

Makes the user’s roles in scope exactly roles (each must exist), with no dates; other scopes stay.

Source

pub async fn roles(&self, db: &Db) -> Result<Vec<String>>

The names of the user’s roles in effect now, sorted: the global ones plus those in the request’s scope (set_scope), within their dates.

Source

pub async fn permissions(&self, db: &Db) -> Result<Vec<String>>

The permissions the user’s roles in effect now grant, sorted (the same roles as User::roles).

Source

pub async fn assignments(&self, db: &Db) -> Result<Vec<Assignment>>

Every role the user was given, with where and when, ordered by role and scope; ended ones too until permissions:prune deletes them. For account and admin pages.

Source

pub fn has_role_in(&self, role: &str, scope: &Scope) -> bool

Whether this user has role globally or in scope, within its dates, from the roles loaded for the current request (like User::has_role); scope is the record’s, not the request’s.

Source

pub fn has_permission_in(&self, permission: &str, scope: &Scope) -> bool

Whether a global role of this user, or one given in scope, grants permission now: for policies, which check the record’s scope (Scope::of_id::<Store>(order.store_id)) rather than the request’s. Answered from the roles loaded for the current request (like User::has_permission): false for another user and outside a request.

Source

pub fn scopes_with<M: Model>(&self, permission: &str) -> Scopes<M::Key>

The records of model M in which this user holds permission now: Scopes::All when a global role grants it, else the keys of the records whose roles do. For filtering lists (Scopes::apply). Answered from the roles loaded for the current request; nothing for another user and outside a request.

Source§

impl User

Source

pub async fn create_token( &self, db: &Db, name: &str, expires_at: Option<DateTime>, ) -> Result<NewToken>

Creates an API token that may do everything the user may, optionally expiring at expires_at.

Source

pub async fn create_token_with( &self, db: &Db, name: &str, abilities: &[&str], expires_at: Option<DateTime>, ) -> Result<NewToken>

Creates an API token limited to abilities (checked with AuthUser::token_can or Routes::require_ability), e.g. a read-only token: create_token_with(&db, "reports", &["orders:read"], None). "*" allows everything.

Source

pub async fn tokens(&self, db: &Db) -> Result<Vec<AccessToken>>

The user’s API tokens, newest first.

Source

pub async fn revoke_token(&self, db: &Db, token_id: i64) -> Result<bool>

Revokes one of the user’s tokens; returns whether it existed.

Source

pub async fn revoke_tokens(&self, db: &Db) -> Result<u64>

Revokes all of the user’s tokens.

Source§

impl User

Source

pub fn find_by_email<'c, E: Executor<'c>>( db: E, email: &str, ) -> impl Future<Output = Result<Option<Self>>> + Send

Emails are matched case-insensitively.

Source

pub async fn register( db: &Db, name: &str, email: &str, password: &str, ) -> Result<Self>

Creates a user with a hashed password.

Source

pub async fn set_password(&mut self, db: &Db, password: &str) -> Result

Changes the password. Every session of the user ends, this one too (sessions hold a fingerprint of the password hash); in a handler use crate::auth::change_password, which logs this session in again.

Source

pub fn get<T: DeserializeOwned>(&self, column: &str) -> Option<T>

One of the app’s own columns (see extra), e.g. user.get::<String>("role"); None if missing, null or of another type. A BOOLEAN column reads as bool on SQLite too, where it is stored as 0 or 1.

Source

pub async fn set( &mut self, db: &Db, column: &str, value: impl ToDbValue, ) -> Result

Sets one of the app’s own columns in the database and in extra, e.g. user.set(&db, "role", "admin").

Source

pub async fn revoke_sessions(&self, db: &Db) -> Result

Ends every session of the user, e.g. on logout or when an account may be compromised. API tokens stay; see User::revoke_tokens.

Source

pub async fn attempt( db: &Db, email: &str, password: &str, ) -> Result<Option<Self>>

The user with this email and password, e.g. to issue an API token. Takes as long for an unknown email as for a wrong password, so the answer doesn’t reveal which emails have accounts.

Source

pub fn has_password(&self) -> bool

Whether the user has a password. Users made by a social login (auth::register_verified, the renox-oauth crate) don’t: their password is empty, which no typed password matches, until they choose one with “Forgot your password?”.

Source

pub async fn check_password(&self, password: &str) -> bool

Whether password matches the stored hash (Argon2id or an imported bcrypt one).

Source

pub fn can(&self, ability: &str, target: &impl Policy) -> bool

Whether target’s Policy allows this user ability.

Source

pub fn authorize(&self, ability: &str, target: &impl Policy) -> Result

Like User::can, but a refusal becomes a 403 error.

Source§

impl User

Source

pub fn has_role(&self, role: &str) -> bool

Whether this user has role (the Permissions module), answered from the roles loaded for the current request, so it works in Policy::allows and App::gate_before (“admins may do anything”). It is false for any other user, and outside a request (a job, a command): use the async user.roles(&db) there.

Global roles count, plus those given in the request’s scope (permissions::set_scope), within their dates.

Source

pub fn has_permission(&self, permission: &str) -> bool

Like User::has_role, for a permission granted by one of the user’s roles.

Trait Implementations§

Source§

impl Clone for User

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for User

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for User

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for User

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<&User> for Recipient

Source§

fn from(user: &User) -> Self

Converts to this type from the input type.
Source§

impl FromRow for User

Source§

fn from_row(row: &Row) -> Result<Self, DbError>

Decodes one row, by column name or position.
Source§

impl Model for User

Source§

const TABLE: &'static str = "users"

The table name (the snake_case struct name unless #[model(table = …)]).
Source§

const SELECT_ALL: bool = true

Select every column (*) instead of COLUMNS, so from_row also sees columns the struct doesn’t list, and queries may filter on them. The built-in User does this to keep the app’s own columns.
Source§

const COLUMNS: &'static [&'static str]

Every column, including id.
Source§

type Key = i64

The type of the id field.
Source§

fn id(&self) -> i64

The primary key.
Source§

const SOFT_DELETES: bool = false

delete() sets deleted_at instead of removing the row, and queries skip deleted rows unless asked with with_trashed() / only_trashed().
Source§

const SEARCHABLE: &'static [&'static str] = _

The text columns full-text search looks in, most important first (they weigh more in the ranking); empty: the model can’t be searched. Set it with #[model(search = "title, body")]; see renox::db::search.
Source§

const SEARCH_LANGUAGE: &'static str = "english"

The language full-text search stems words for: english (the default) or a PostgreSQL text search configuration such as simple (no stemming) or spanish. Set it with #[model(search_language = "simple")].
Source§

fn replicate(&self) -> Self
where Self: Clone,

A copy of the model that isn’t saved yet (Laravel’s replicate): the same values, with an unsaved id, no deleted_at and, when they are Options, no timestamps, so save inserts a new row. Change what must differ (a unique SKU, a name) before saving it, or show it in the “new” form for someone to finish (“Duplicate”). Read more
Source§

fn default_scope(query: Query<Self>) -> Query<Self>

Conditions every query of this model starts with, e.g. the current tenant, read from renox::context. query(), find, all, where_eq and the relation loaders apply it; Model::unscoped doesn’t. Saving, deleting and restoring a loaded model work by its id. Set it with #[model(default_scope = "…")]: Read more
Source§

fn saving(&mut self, _creating: bool) -> Result

Runs before the row is written; an error stops the save. Implement ModelHooks and add #[model(hooks)] rather than overriding it.
Source§

fn saved(&self, _created: bool) -> impl Future<Output = Result> + Send

Runs after the row is written (inside the caller’s transaction, if any); an error is returned by save. See ModelHooks.
Source§

fn deleting(&self) -> Result

Runs before delete/force_delete; an error stops it. See ModelHooks.
Source§

fn deleted(&self) -> impl Future<Output = Result> + Send

Runs after delete/force_delete. See ModelHooks.
Source§

fn query() -> Query<Self>

A query with the default scope applied (see Model::default_scope).
Source§

fn unscoped() -> Query<Self>

A query without the default scope, e.g. for an admin who sees every tenant. Soft-deleted rows stay hidden unless asked for.
Source§

fn refresh(&mut self, db: &Db) -> impl Future<Output = Result<()>> + Send

Reloads the model’s row (e.g. after an increment or another request changed it); a deleted row is a 404.
Source§

fn search(words: &str) -> Query<Self>

The rows matching a full-text search, best matches first: shorthand for query().search(words). The model needs #[model(search = "…")] and its index (see renox::db::search). Read more
Source§

fn where_eq(column: &str, value: impl ToDbValue) -> Query<Self>

Shorthand for query().where_eq(column, value).
Source§

fn all<'c, E: Executor<'c>>( db: E, ) -> impl Future<Output = Result<Vec<Self>>> + Send

Every row, in id order.
Source§

fn find<'c, E: Executor<'c>>( db: E, id: Self::Key, ) -> impl Future<Output = Result<Option<Self>>> + Send

The row with this id, or None.
Source§

fn find_many<'c, E: Executor<'c>>( db: E, ids: impl IntoIterator<Item = Self::Key>, ) -> impl Future<Output = Result<Vec<Self>>> + Send

The rows with these ids, in id order (missing ids are skipped).
Source§

fn insert_many<'c, E: Executor<'c>>( db: E, models: Vec<Self>, ) -> impl Future<Output = Result<u64>> + Send

Inserts many new models with a few statements (ids aren’t returned; use create when you need them). Timestamps are set; unsaved ULID and UUID keys are made, String keys must be set, i64 keys come from the database. Returns the number of rows inserted.
Source§

fn upsert<'c, E: Executor<'c>>( db: E, models: Vec<Self>, unique_by: &[&str], update: &[&str], ) -> impl Future<Output = Result<u64>> + Send

Inserts models, or updates the rows they clash with on the unique_by columns (which need a unique index), setting update columns (and updated_at when the model has it). Returns the rows written. Read more
Source§

fn find_or_404<'c, E: Executor<'c>>( db: E, id: Self::Key, ) -> impl Future<Output = Result<Self>> + Send

Like find, but a missing row becomes a 404 response.
Source§

fn create<'c, E: Executor<'c>>( db: E, model: Self, ) -> impl Future<Output = Result<Self>> + Send

Inserts a new model and returns it with its id and timestamps.
Source§

fn insert<'c, E: Executor<'c>>( &mut self, db: E, ) -> impl Future<Output = Result> + Send

Inserts the model as a new row, whatever its id: an unsaved id gets a new key (from the database for i64, a new ULID or UUID v7), a set one is written as it is (a String key must be set).
Source§

fn save<'c, E: Executor<'c>>( &mut self, db: E, ) -> impl Future<Output = Result> + Send

Inserts the model if its id is unsaved (0, an empty ULID…), otherwise updates its row.
Source§

fn save_only<'c, E: Executor<'c>>( &mut self, db: E, columns: &[&str], ) -> impl Future<Output = Result> + Send

Updates only columns (and updated_at, if the model has it) of a saved model, so a concurrent change to another column isn’t overwritten. A column the saving hook changes is saved only if it’s listed. Read more
Source§

fn save_changes<'c, E: Executor<'c>>( &mut self, db: E, original: &Self, ) -> impl Future<Output = Result<bool>> + Send

Saves the columns that differ from original (the model as it was loaded), including those the saving hook changes, and returns whether anything was written. When nothing changed there’s no query and no saved hook. Read more
Source§

fn delete<'c, E: Executor<'c>>( &mut self, db: E, ) -> impl Future<Output = Result> + Send

Deletes the row, or marks it deleted for models with soft deletes.
Source§

fn force_delete<'c, E: Executor<'c>>( &self, db: E, ) -> impl Future<Output = Result> + Send

Removes the row, even for models with soft deletes.
Source§

fn restore<'c, E: Executor<'c>>( &mut self, db: E, ) -> impl Future<Output = Result> + Send

Brings back a soft-deleted row.
Source§

impl Serialize for User

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Viewer for User

Source§

fn as_user(&self) -> &User

The user the policy is asked about.
Source§

fn before(&self, _ability: &str) -> Option<bool>

App::gate_before’s answer, if any.

Auto Trait Implementations§

§

impl Freeze for User

§

impl RefUnwindSafe for User

§

impl Send for User

§

impl Sync for User

§

impl Unpin for User

§

impl UnsafeUnpin for User

§

impl UnwindSafe for User

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> Fake for T

Source§

fn fake<U>(&self) -> U
where Self: FakeBase<U>,

Source§

fn fake_with_rng<U, R>(&self, rng: &mut R) -> U
where R: RngExt + ?Sized, Self: FakeBase<U>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more