pub trait AuthBackend: Send + Sync {
Show 13 methods
// Required methods
fn authenticate<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn verify_identity<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_users<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<Username>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn create_user<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn delete_user<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn change_password<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
new_password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
// Provided methods
fn fetch_scram_credentials<'life0, 'life1, 'async_trait>(
&'life0 self,
_user: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ScramCredentials>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn get_scram_params<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(Vec<u8>, u32)>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn get_scram_stored_key<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn get_scram_server_key<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn store_scram_credentials<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 Username,
_salt: Vec<u8>,
_iterations: u32,
_stored_key: Vec<u8>,
_server_key: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn get_apop_secret<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn verify_bearer_token<'life0, 'life1, 'async_trait>(
&'life0 self,
token: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Username>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Required Methods§
Sourcefn authenticate<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn authenticate<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Authenticate a user with username and password
Sourcefn verify_identity<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn verify_identity<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Verify if a username maps to a valid identity
Sourcefn list_users<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<Username>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_users<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<Username>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List all users (for admin CLI)
Sourcefn create_user<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn create_user<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Create a new user with the given password
Sourcefn delete_user<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete_user<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete a user
Sourcefn change_password<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
new_password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn change_password<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
username: &'life1 Username,
new_password: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Change a user’s password
Provided Methods§
Sourcefn fetch_scram_credentials<'life0, 'life1, 'async_trait>(
&'life0 self,
_user: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ScramCredentials>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn fetch_scram_credentials<'life0, 'life1, 'async_trait>(
&'life0 self,
_user: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ScramCredentials>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch the full RFC 5802 SCRAM-SHA-256 credential bundle for a user.
Returns Ok(Some(creds)) when pre-computed SCRAM credentials exist,
Ok(None) when this backend does not store SCRAM credentials for the
user (SCRAM-SHA-256 should then be declined; PLAIN / LOGIN remain available),
and Err(...) only on I/O or parse failures.
The default implementation returns Ok(None), meaning SQL / LDAP / OAuth2
backends gracefully degrade without requiring any code changes in those backends.
Only the file backend overrides this with a real implementation.
Sourcefn get_scram_params<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(Vec<u8>, u32)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_scram_params<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(Vec<u8>, u32)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get SCRAM-SHA-256 parameters (salt, iteration count) for a user
Returns (salt, iterations) if SCRAM credentials are stored. Default implementation returns an error indicating SCRAM is not supported.
Sourcefn get_scram_stored_key<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_scram_stored_key<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get SCRAM-SHA-256 StoredKey for a user
StoredKey = SHA256(ClientKey) where ClientKey = HMAC(SaltedPassword, “Client Key”) Default implementation returns an error indicating SCRAM is not supported.
Sourcefn get_scram_server_key<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_scram_server_key<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get SCRAM-SHA-256 ServerKey for a user
ServerKey = HMAC(SaltedPassword, “Server Key”) Default implementation returns an error indicating SCRAM is not supported.
Sourcefn store_scram_credentials<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 Username,
_salt: Vec<u8>,
_iterations: u32,
_stored_key: Vec<u8>,
_server_key: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_scram_credentials<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 Username,
_salt: Vec<u8>,
_iterations: u32,
_stored_key: Vec<u8>,
_server_key: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Store SCRAM-SHA-256 credentials for a user
This should store: salt, iterations, StoredKey, and ServerKey Default implementation returns an error indicating SCRAM is not supported.
Sourcefn get_apop_secret<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_apop_secret<'life0, 'life1, 'async_trait>(
&'life0 self,
_username: &'life1 Username,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get plaintext password for APOP authentication
Returns the plaintext password if available. Default implementation returns an error indicating APOP is not supported.
WARNING: This method exposes plaintext passwords and should only be used for APOP authentication. Consider disabling APOP in production environments.
Sourcefn verify_bearer_token<'life0, 'life1, 'async_trait>(
&'life0 self,
token: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Username>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn verify_bearer_token<'life0, 'life1, 'async_trait>(
&'life0 self,
token: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Username>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Verify a Bearer token and return the authenticated username.
This is the entry point for HTTP Bearer authentication (e.g. in JMAP). The default implementation rejects all tokens unconditionally so that backends without OAuth2 support never silently accept Bearer credentials.
Backends that support Bearer / JWT verification (e.g. backends::oauth2)
override this method to perform real token introspection or JWT validation.
§Errors
Returns an anyhow::Error wrapping a rejected-token message if the
token is invalid, expired, or this backend does not support Bearer auth.
Callers that want a typed rejection should map the error to their own
error type (e.g. AuthError::Unauthorized).