pub trait SessionStore:
Send
+ Sync
+ 'static {
// Required methods
fn insert_session(
&self,
session: &SessionRecord,
token: &TokenHash,
) -> impl Future<Output = Result<(), StoreError>> + Send;
fn find_by_token(
&self,
token: &TokenHash,
) -> impl Future<Output = Result<Option<TokenLookup>, StoreError>> + Send;
fn apply(
&self,
update: &SessionUpdate,
) -> impl Future<Output = Result<bool, StoreError>> + Send;
fn delete_session(
&self,
session_id: Uuid,
) -> impl Future<Output = Result<bool, StoreError>> + Send;
fn delete_subject_sessions(
&self,
subject: &str,
) -> impl Future<Output = Result<u64, StoreError>> + Send;
fn list_subject_sessions(
&self,
subject: &str,
) -> impl Future<Output = Result<Vec<SessionRecord>, StoreError>> + Send;
fn delete_expired(
&self,
now: DateTime<Utc>,
idle_cutoff: DateTime<Utc>,
) -> impl Future<Output = Result<u64, StoreError>> + Send;
fn record_event(
&self,
event: &SessionEvent,
) -> impl Future<Output = Result<(), StoreError>> + Send;
fn delete_events_before(
&self,
cutoff: DateTime<Utc>,
) -> impl Future<Output = Result<u64, StoreError>> + Send;
// Provided method
fn claim_event(
&self,
session_id: Uuid,
kind: EventKind,
now: DateTime<Utc>,
window: TimeDelta,
) -> impl Future<Output = Result<bool, StoreError>> + Send { ... }
}Expand description
Session persistence.
Every method must be safe to call concurrently from many processes. Each returned future
must be Send. Timestamps may be stored at microsecond precision.
Required Methods§
Sourcefn insert_session(
&self,
session: &SessionRecord,
token: &TokenHash,
) -> impl Future<Output = Result<(), StoreError>> + Send
fn insert_session( &self, session: &SessionRecord, token: &TokenHash, ) -> impl Future<Output = Result<(), StoreError>> + Send
Stores a new session with token as its current token (issued_at = created_at,
unused, not superseded).
Sourcefn find_by_token(
&self,
token: &TokenHash,
) -> impl Future<Output = Result<Option<TokenLookup>, StoreError>> + Send
fn find_by_token( &self, token: &TokenHash, ) -> impl Future<Output = Result<Option<TokenLookup>, StoreError>> + Send
Finds the session holding token, current or superseded.
Sourcefn apply(
&self,
update: &SessionUpdate,
) -> impl Future<Output = Result<bool, StoreError>> + Send
fn apply( &self, update: &SessionUpdate, ) -> impl Future<Output = Result<bool, StoreError>> + Send
Applies update atomically, in this order:
- If
rotationis set and itsSupersedecondition holds for the current token: supersede it, insert the new token as current, prune old superseded tokens. - Mark
mark_usedused if it belongs to the session and is unused; this includes the token step 1 just inserted. - Set
last_seen_at = nowand everySomefield.
A session must never have more than one current token. Returns whether the rotation
happened; a missing session is not an error and returns false.
Sourcefn delete_session(
&self,
session_id: Uuid,
) -> impl Future<Output = Result<bool, StoreError>> + Send
fn delete_session( &self, session_id: Uuid, ) -> impl Future<Output = Result<bool, StoreError>> + Send
Deletes a session and its tokens. Returns whether it existed.
Sourcefn delete_subject_sessions(
&self,
subject: &str,
) -> impl Future<Output = Result<u64, StoreError>> + Send
fn delete_subject_sessions( &self, subject: &str, ) -> impl Future<Output = Result<u64, StoreError>> + Send
Deletes every session of subject (canonical JSON). Returns how many.
Sourcefn list_subject_sessions(
&self,
subject: &str,
) -> impl Future<Output = Result<Vec<SessionRecord>, StoreError>> + Send
fn list_subject_sessions( &self, subject: &str, ) -> impl Future<Output = Result<Vec<SessionRecord>, StoreError>> + Send
Every session of subject (canonical JSON), including expired ones not yet purged.
Sourcefn delete_expired(
&self,
now: DateTime<Utc>,
idle_cutoff: DateTime<Utc>,
) -> impl Future<Output = Result<u64, StoreError>> + Send
fn delete_expired( &self, now: DateTime<Utc>, idle_cutoff: DateTime<Utc>, ) -> impl Future<Output = Result<u64, StoreError>> + Send
Deletes sessions with expires_at <= now or last_seen_at <= idle_cutoff. Returns how
many.
Sourcefn record_event(
&self,
event: &SessionEvent,
) -> impl Future<Output = Result<(), StoreError>> + Send
fn record_event( &self, event: &SessionEvent, ) -> impl Future<Output = Result<(), StoreError>> + Send
Appends a security event. Stores without an event log may discard it.
Sourcefn delete_events_before(
&self,
cutoff: DateTime<Utc>,
) -> impl Future<Output = Result<u64, StoreError>> + Send
fn delete_events_before( &self, cutoff: DateTime<Utc>, ) -> impl Future<Output = Result<u64, StoreError>> + Send
Deletes events with at < cutoff. Returns how many. Also deletes event claims older
than cutoff.
Provided Methods§
Sourcefn claim_event(
&self,
session_id: Uuid,
kind: EventKind,
now: DateTime<Utc>,
window: TimeDelta,
) -> impl Future<Output = Result<bool, StoreError>> + Send
fn claim_event( &self, session_id: Uuid, kind: EventKind, now: DateTime<Utc>, window: TimeDelta, ) -> impl Future<Output = Result<bool, StoreError>> + Send
Claims the right to record an unenforced kind event for a session, for shadow-mode
deduplication across processes. Succeeds (true) unless a claim for the same session
and kind was made after now - window, and records now as the new claim when it
does. Must be atomic across processes.
The default always succeeds, which leaves deduplication to each process.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementations on Foreign Types§
Source§impl<T: SessionStore> SessionStore for Arc<T>
impl<T: SessionStore> SessionStore for Arc<T>
fn insert_session( &self, session: &SessionRecord, token: &TokenHash, ) -> impl Future<Output = Result<(), StoreError>> + Send
fn find_by_token( &self, token: &TokenHash, ) -> impl Future<Output = Result<Option<TokenLookup>, StoreError>> + Send
fn apply( &self, update: &SessionUpdate, ) -> impl Future<Output = Result<bool, StoreError>> + Send
fn delete_session( &self, session_id: Uuid, ) -> impl Future<Output = Result<bool, StoreError>> + Send
fn delete_subject_sessions( &self, subject: &str, ) -> impl Future<Output = Result<u64, StoreError>> + Send
fn list_subject_sessions( &self, subject: &str, ) -> impl Future<Output = Result<Vec<SessionRecord>, StoreError>> + Send
fn delete_expired( &self, now: DateTime<Utc>, idle_cutoff: DateTime<Utc>, ) -> impl Future<Output = Result<u64, StoreError>> + Send
fn record_event( &self, event: &SessionEvent, ) -> impl Future<Output = Result<(), StoreError>> + Send
fn delete_events_before( &self, cutoff: DateTime<Utc>, ) -> impl Future<Output = Result<u64, StoreError>> + Send
fn claim_event( &self, session_id: Uuid, kind: EventKind, now: DateTime<Utc>, window: TimeDelta, ) -> impl Future<Output = Result<bool, StoreError>> + Send
Implementors§
impl SessionStore for MemoryStore
impl SessionStore for PgStore
postgres only.impl SessionStore for ValkeyStore
valkey only.