Skip to main content

LocalPasswordAuthenticator

Struct LocalPasswordAuthenticator 

Source
pub struct LocalPasswordAuthenticator { /* private fields */ }
Expand description

Email + password authenticator backed by Argon2id and the #411 identity store.

Construct with new (OWASP-default parameters) or with_params (to tune cost), call init once on startup, then signup / login. The connecting PgPool role must own (or BYPASSRLS) the core tables — calling init creates them, so the connecting role owns them by construction.

Implementations§

Source§

impl LocalPasswordAuthenticator

Source

pub fn with_email_sender(self, sender: Arc<dyn ResetEmailSender>) -> Self

Attach the ResetEmailSender used to deliver reset links.

Without it, start_password_reset still issues and persists a token but logs a warning instead of delivering it.

Source

pub fn with_session_store(self, store: Arc<dyn SessionStore>) -> Self

Attach the session store whose sessions are revoked on a successful reset.

Without it, confirm_password_reset changes the password but logs a warning that outstanding sessions were not revoked.

Source

pub async fn start_password_reset(&self, email: &str) -> Result<()>

Begin a password reset for email. Always returns Ok(()) (non-enumerable).

Resolves the local credential for email; if one exists, issues a single-use, one-hour token, persists its selector + verifier hash, and dispatches the reset link via the configured ResetEmailSender in a spawned task. An unknown or OAuth-only email is a silent no-op. The return value and timing do not reveal whether an account exists.

§Errors

Returns AuthError::DatabaseError only if the credential lookup or the token insert fails — i.e. infrastructure errors, never “account does not exist”.

Source

pub async fn confirm_password_reset( &self, token: &str, new_password: &str, ) -> Result<()>

Redeem a reset token and set new_password.

Validates the new password’s length policy, looks the token up by selector, verifies the verifier in constant time, and rejects it if expired or already used. On success it sets the new Argon2id hash, marks the token used, invalidates the user’s other outstanding tokens, and revokes the user’s sessions (if a session store is wired) — all in one transaction for the credential changes.

§Errors
Source§

impl LocalPasswordAuthenticator

Source

pub fn new(db: PgPool, accounts: Arc<dyn AccountStore>) -> Self

Create an authenticator with OWASP-default Argon2id parameters.

Source

pub fn with_params( db: PgPool, accounts: Arc<dyn AccountStore>, m_cost: u32, t_cost: u32, p_cost: u32, ) -> Result<Self>

Create an authenticator with explicit Argon2id cost parameters: m_cost (memory in KiB), t_cost (iterations), and p_cost (parallelism lanes).

Use this to raise the cost over the default, or (in tests) to lower it. A login whose stored hash used different parameters is transparently rehashed to these on the next successful sign-in.

§Errors

Returns AuthError::ConfigError if the parameters are not a valid Argon2 combination (e.g. m_cost < 8 * p_cost).

Source

pub async fn init(&self) -> Result<()>

Ensure the identity + credential schema exists (idempotent).

Runs the #411 identity DDL first (the credential table FK-references core.tb_user) and then the credential DDL, so it is self-sufficient whether or not PostgresAccountStore::init has already run. Call once on startup.

§Errors

Returns AuthError::DatabaseError if the DDL fails.

Source

pub async fn signup(&self, email: &str, password: &str) -> Result<String>

Register a new local email + password account. Returns the stable user_id.

Validates the input, resolves or creates the user through the AccountStore with email_verified = false (fail-closed — no auto-link into a verified-email account), then stores the Argon2id hash.

§Errors
Source

pub async fn login(&self, email: &str, password: &str) -> Result<String>

Verify an email + password and return the stable user_id on success.

Non-enumerable: an unknown user and a wrong password return the same AuthError::InvalidCredentials and pay the same Argon2 cost (unknown users are verified against a same-parameter dummy hash). A correct password on a disabled account returns AuthError::AccountDisabled; a wrong password on a disabled account returns AuthError::InvalidCredentials (no disabled disclosure). A successful login rehashes if the stored parameters are weaker than the current policy.

§Errors
Source

pub async fn set_password_disabled( &self, user_id: &str, disabled: bool, ) -> Result<()>

Enable or disable local-password sign-in for an account.

Disabling stamps disabled_at; a subsequent login with the correct password returns AuthError::AccountDisabled. Enabling clears it.

§Errors

Auto Trait Implementations§

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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