pub trait Authenticator:
Send
+ Sync
+ 'static {
type User: PanelUser;
// Required methods
fn verify(
&self,
cx: &Cx,
login: &str,
password: &str,
) -> impl Future<Output = Result<Option<Self::User>>> + Send;
fn find_by_id(
&self,
cx: &Cx,
id: &str,
) -> impl Future<Output = Result<Option<Self::User>>> + Send;
// Provided methods
fn confirm_password(
&self,
cx: &Cx,
user: &Self::User,
password: &str,
) -> impl Future<Output = Result<bool>> + Send { ... }
fn store_locale(
&self,
cx: &Cx,
user: &Self::User,
locale: &Locale,
) -> impl Future<Output = Result<()>> + Send { ... }
}Expand description
How a panel loads its users (ADR-0013).
The default PasswordAuth implements it against the shipped
AdminUser model; an app with an existing user table implements it and
passes the value to Panel::auth via
Auth::custom. Sessions are the framework’s, so an implementation only
maps credentials to a user and a stored id back to one. An app that signs its users in itself
implements ExternalAuth instead.
Every credential failure must return Ok(None), never a distinguishable
error: the login response is one generic message for all of them. An
infrastructure failure is not a credential verdict, so an implementation
that cannot reach its store returns the driver’s error instead — the login
handler maps it to the opaque outage page, which keeps a database outage
from rendering as a rejected password. An implementation’s own error keeps
its own mapping.
Required Associated Types§
Required Methods§
Sourcefn verify(
&self,
cx: &Cx,
login: &str,
password: &str,
) -> impl Future<Output = Result<Option<Self::User>>> + Send
fn verify( &self, cx: &Cx, login: &str, password: &str, ) -> impl Future<Output = Result<Option<Self::User>>> + Send
Verify login/password, returning the user on success.
Implementations must run comparable work for unknown accounts so
timing does not leak account existence; verify_password does,
given None for an unknown account.
Sourcefn find_by_id(
&self,
cx: &Cx,
id: &str,
) -> impl Future<Output = Result<Option<Self::User>>> + Send
fn find_by_id( &self, cx: &Cx, id: &str, ) -> impl Future<Output = Result<Option<Self::User>>> + Send
Load the session’s user by PanelUser::user_id, with everything the request
reads from it — its tenants included.
It runs on every request, which is what makes deactivation, revocation
and a removed membership take effect immediately; return None when
the user no longer authenticates.
Provided Methods§
Sourcefn confirm_password(
&self,
cx: &Cx,
user: &Self::User,
password: &str,
) -> impl Future<Output = Result<bool>> + Send
fn confirm_password( &self, cx: &Cx, user: &Self::User, password: &str, ) -> impl Future<Output = Result<bool>> + Send
Whether password is user’s current password: what a page asks before a change a stolen
session must not make, such as turning two-factor sign-in on.
It defaults to verify with the user’s email as the
login, and answers false for a user without one: override it when users sign in with
something else.
Sourcefn store_locale(
&self,
cx: &Cx,
user: &Self::User,
locale: &Locale,
) -> impl Future<Output = Result<()>> + Send
fn store_locale( &self, cx: &Cx, user: &Self::User, locale: &Locale, ) -> impl Future<Output = Result<()>> + Send
Stores locale as user’s after they pick it from the shell’s language menu, so their
locale reads it on the next request, in another browser, and in the
mail a job sends them. It runs only when the pick differs from that locale, and never
while someone impersonates the user.
It defaults to storing nothing: the pick then lives in the browser’s cookie alone. A failure is logged, and the page still switches to the locale picked.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".