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
impl LocalPasswordAuthenticator
Sourcepub fn with_email_sender(self, sender: Arc<dyn ResetEmailSender>) -> Self
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.
Sourcepub fn with_session_store(self, store: Arc<dyn SessionStore>) -> Self
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.
Sourcepub async fn start_password_reset(&self, email: &str) -> Result<()>
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”.
Sourcepub async fn confirm_password_reset(
&self,
token: &str,
new_password: &str,
) -> Result<()>
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
AuthError::InvalidRegistrationifnew_passwordviolates the length policy.AuthError::InvalidTokenfor any unredeemable token (unknown / malformed / expired / used / wrong verifier) — one generic error; the audit log records the precise reason.AuthError::DatabaseError/AuthError::Internalon a storage failure.
Source§impl LocalPasswordAuthenticator
impl LocalPasswordAuthenticator
Sourcepub fn new(db: PgPool, accounts: Arc<dyn AccountStore>) -> Self
pub fn new(db: PgPool, accounts: Arc<dyn AccountStore>) -> Self
Create an authenticator with OWASP-default Argon2id parameters.
Sourcepub fn with_params(
db: PgPool,
accounts: Arc<dyn AccountStore>,
m_cost: u32,
t_cost: u32,
p_cost: u32,
) -> Result<Self>
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).
Sourcepub async fn init(&self) -> Result<()>
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.
Sourcepub async fn signup(&self, email: &str, password: &str) -> Result<String>
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
AuthError::InvalidRegistrationif the email is empty/malformed or the password violates the length policy.AuthError::EmailAlreadyRegisteredif a local credential already exists for this email.AuthError::DatabaseError/AuthError::Internalon a storage failure.
Sourcepub async fn login(&self, email: &str, password: &str) -> Result<String>
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
AuthError::InvalidCredentialsfor unknown user or wrong password.AuthError::AccountDisabledfor a disabled account with the correct password.AuthError::DatabaseError/AuthError::Internalon a storage failure.
Sourcepub async fn set_password_disabled(
&self,
user_id: &str,
disabled: bool,
) -> Result<()>
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
AuthError::TokenNotFoundif the user has no local credential.AuthError::DatabaseErroron a storage failure.
Auto Trait Implementations§
impl !RefUnwindSafe for LocalPasswordAuthenticator
impl !UnwindSafe for LocalPasswordAuthenticator
impl Freeze for LocalPasswordAuthenticator
impl Send for LocalPasswordAuthenticator
impl Sync for LocalPasswordAuthenticator
impl Unpin for LocalPasswordAuthenticator
impl UnsafeUnpin for LocalPasswordAuthenticator
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<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 more