pub trait SessionStore:
Send
+ Sync
+ 'static {
type Error: Debug + Send + Sync + 'static;
// Required methods
fn store_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session: &'life1 Session,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Session>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn delete_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn store_refresh_index<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
refresh_token: &'life1 str,
session_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn take_session_id_by_refresh<'life0, 'life1, 'async_trait>(
&'life0 self,
refresh_token: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn count_pending_challenges<'life0, 'life1, 'async_trait>(
&'life0 self,
did: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Storage operations the canonical handlers invoke.
Each backend wraps its own keyspace handle (vti-common’s
KeyspaceHandle enum, did-hosting’s KeyspaceHandle struct,
future cloud-store backends) in an adapter implementing this
trait. The handler holds a &S and never touches the concrete
storage type directly.
§Why this trait, not a single KeyspaceHandle type
did-hosting and vti-common evolved separate keyspace abstractions before the auth-architecture consolidation. Merging them is out of scope for the auth work; the trait boundary keeps them independent while still sharing the auth-flow code.
Required Associated Types§
Required Methods§
Sourcefn store_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session: &'life1 Session,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session: &'life1 Session,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Persist a session under its session_id.
Sourcefn get_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Session>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Session>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Load a session by session_id. Ok(None) if missing or expired-and-swept.
Sourcefn delete_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete a session and its refresh-token reverse-index.
Sourcefn store_refresh_index<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
refresh_token: &'life1 str,
session_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn store_refresh_index<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
refresh_token: &'life1 str,
session_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Persist the refresh_token → session_id reverse-index.
Implementors choose whether to hash the key (recommended;
vti-common does, did-hosting historically does not) — the
handler treats the token as an opaque bearer.
Sourcefn take_session_id_by_refresh<'life0, 'life1, 'async_trait>(
&'life0 self,
refresh_token: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn take_session_id_by_refresh<'life0, 'life1, 'async_trait>(
&'life0 self,
refresh_token: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Atomically claim-and-delete the refresh_token → session_id
reverse-index. Cross-replica safe (Redis GETDEL / DynamoDB
DeleteItem ReturnValues=ALL_OLD / fjall mutex). Exactly one
concurrent caller observes Some for any given token.
Used by /auth/refresh to close the rotation TOCTOU.
Sourcefn count_pending_challenges<'life0, 'life1, 'async_trait>(
&'life0 self,
did: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn count_pending_challenges<'life0, 'life1, 'async_trait>(
&'life0 self,
did: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Count ChallengeSent sessions for did. Backends with an
O(1) per-DID tracker (did-hosting) override the default
O(N) prefix-scan implementation by re-implementing this
method.
Default implementation provided for backends that haven’t yet built a tracker — correct but slow under load. Override before relying on per-DID rate limiting in production.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".