Skip to main content

PanelUser

Trait PanelUser 

Source
pub trait PanelUser:
    Any
    + Send
    + Sync {
    // Required methods
    fn user_id(&self) -> String;
    fn display_name(&self) -> &str;
    fn can_access_panel(&self, panel: &str) -> bool;

    // Provided methods
    fn subtitle(&self) -> Option<&str> { ... }
    fn email(&self) -> Option<&str> { ... }
    fn tenants(&self) -> &[Membership] { ... }
    fn default_tenant(&self) -> Option<TenantId> { ... }
    fn time_zone(&self) -> Option<TimeZone> { ... }
    fn locale(&self) -> Option<Locale> { ... }
}
Expand description

A signed-in user, as the panel knows it (ADR-0013).

Implement it for the app’s own user type and return that type from an Authenticator; the shipped AdminUser implements it too. App code reads the user back with its own type through user.

impl PanelUser for Staff {
    fn user_id(&self) -> String {
        self.id.to_string()
    }
    fn display_name(&self) -> &str {
        &self.name
    }
    fn can_access_panel(&self, _panel: &str) -> bool {
        self.active
    }
    fn tenants(&self) -> &[Membership] {
        &self.memberships
    }
}

Required Methods§

Source

fn user_id(&self) -> String

The stable key the session stores and Authenticator::find_by_id receives. Any string fits.

Source

fn display_name(&self) -> &str

The name the user menu shows.

Source

fn can_access_panel(&self, panel: &str) -> bool

Whether the user may enter the panel at panel, its prefix with one leading slash and none trailing: /admin for Panel::new("admin"). A user who may not answers 403, indistinguishable from bad credentials at login. Every user type answers it: a sign-up on one panel writes an account every panel over the same user type looks up.

One user type can serve several panels, each with its own rule. Name each panel and refuse the rest, so that a panel added or renamed later admits nobody until it has a rule:

ⓘ
fn can_access_panel(&self, panel: &str) -> bool {
    match panel {
        "/admin" => self.active && self.is_staff,
        "/portal" => self.active,
        _ => false,
    }
}

Every check of a panel asks it with that panel’s prefix: the gate on each request, the login, the sign-up, a mailed link and a two-factor challenge. The link that cancels an email change does not ask: it only restores the old address and ends sessions.

Provided Methods§

Source

fn subtitle(&self) -> Option<&str>

The muted line under the name in the user menu, such as an email or a role. Defaults to none.

Source

fn email(&self) -> Option<&str>

The address the account stores, which mail meant for the account goes to: a reset link, a verification link, a sign-in code. Defaults to none: the account gets no mail.

Source

fn tenants(&self) -> &[Membership]

The tenants the user may act for, in the order the tenant switcher lists them. A session acts for the default_tenant until the user selects another. Defaults to none: the user has no tenant.

A panel acts for tenants when it offers a tenant registration or settings page, or mounts a resource over tenant-owned rows. Any other acts for no tenant: tenant_id answers None there, and the panel offers no tenant menu and no route to switch.

With two or more, on a panel that acts for tenants, a tenant menu sits atop the sidebar. It posts to {prefix}/tenant, which stores the choice on the session and returns to the panel’s home page. A tenant the user is not a member of answers 403, and a stored choice applies only while the membership lasts. One browser acts for one tenant at a time, in every tab.

Source

fn default_tenant(&self) -> Option<TenantId>

The tenant a session acts for until the user selects another, while it is one of tenants, such as one the user picks on their profile page and the app stores. Defaults to none: the first of tenants.

Source

fn time_zone(&self) -> Option<TimeZone>

The time zone the user reads and enters wall-clock times in: a timestamp’s control, its DateColumn day and its DateFilter days. Defaults to none: the panel’s time_zone.

Source

fn locale(&self) -> Option<Locale>

The locale the user reads the panel and their mails in, such as fr. Defaults to none: the browser’s best match among the panel’s locales, else its default. A locale matches the closest the panel offers, as fr-CA reads fr; one with no match counts as none. A locale the user picks from the shell’s language menu outranks this one for their pages, while their mails still read this one, unless the authenticator stores the pick through Authenticator::store_locale for this method to read.

A user who stores their locale as text parses it:

ⓘ
fn locale(&self) -> Option<Locale> {
    self.locale.as_deref()?.parse().ok()
}

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§