pub struct PgStore { /* private fields */ }Available on crate feature
postgres only.Expand description
Stores sessions in PostgreSQL through a sqlx PgPool. Shared safely by any number of
processes; rotations are single transactions with a conditional update, and a partial unique
index guarantees at most one current token per session.
Tables are named session_guard_*. Create them with PgStore::migrated, or run
PgStore::migrator in your own deployment pipeline. Applied migrations are tracked in
_session_guard_migrations, separate from your app’s _sqlx_migrations.
use session_guard::{Guard, PgStore};
let pool = sqlx::PgPool::connect("postgres://localhost/app").await?;
let guard = Guard::new(PgStore::migrated(pool).await?);Implementations§
Source§impl PgStore
impl PgStore
Sourcepub fn new(pool: PgPool) -> Self
pub fn new(pool: PgPool) -> Self
Wraps pool without touching the schema. Run PgStore::migrator first.
Sourcepub async fn migrated(pool: PgPool) -> Result<Self, MigrateError>
pub async fn migrated(pool: PgPool) -> Result<Self, MigrateError>
Runs the embedded migrations, then wraps pool. Safe to call from many processes at
once and on every start: applied migrations are skipped.
§Errors
If a migration fails or the applied migrations do not match the embedded ones.
Trait Implementations§
Source§impl SessionStore for PgStore
impl SessionStore for PgStore
Source§async fn insert_session(
&self,
session: &SessionRecord,
token: &TokenHash,
) -> Result<(), StoreError>
async fn insert_session( &self, session: &SessionRecord, token: &TokenHash, ) -> Result<(), StoreError>
Stores a new session with
token as its current token (issued_at = created_at,
unused, not superseded).Source§async fn find_by_token(
&self,
token: &TokenHash,
) -> Result<Option<TokenLookup>, StoreError>
async fn find_by_token( &self, token: &TokenHash, ) -> Result<Option<TokenLookup>, StoreError>
Finds the session holding
token, current or superseded.Source§async fn apply(&self, update: &SessionUpdate) -> Result<bool, StoreError>
async fn apply(&self, update: &SessionUpdate) -> Result<bool, StoreError>
Applies
update atomically, in this order: Read moreSource§async fn delete_session(&self, session_id: Uuid) -> Result<bool, StoreError>
async fn delete_session(&self, session_id: Uuid) -> Result<bool, StoreError>
Deletes a session and its tokens. Returns whether it existed.
Source§async fn delete_subject_sessions(
&self,
subject: &str,
) -> Result<Vec<Uuid>, StoreError>
async fn delete_subject_sessions( &self, subject: &str, ) -> Result<Vec<Uuid>, StoreError>
Deletes every session of
subject (canonical JSON). Returns the ids it deleted.Source§async fn list_subject_sessions(
&self,
subject: &str,
) -> Result<Vec<SessionRecord>, StoreError>
async fn list_subject_sessions( &self, subject: &str, ) -> Result<Vec<SessionRecord>, StoreError>
Every session of
subject (canonical JSON), including expired ones not yet purged.Source§async fn delete_expired(
&self,
now: DateTime<Utc>,
idle_cutoff: DateTime<Utc>,
) -> Result<u64, StoreError>
async fn delete_expired( &self, now: DateTime<Utc>, idle_cutoff: DateTime<Utc>, ) -> Result<u64, StoreError>
Deletes sessions with
expires_at <= now or last_seen_at <= idle_cutoff. Returns how
many.Source§async fn record_event(&self, event: &SessionEvent) -> Result<(), StoreError>
async fn record_event(&self, event: &SessionEvent) -> Result<(), StoreError>
Appends a security event. Stores without an event log may discard it.
Source§async fn delete_events_before(
&self,
cutoff: DateTime<Utc>,
) -> Result<u64, StoreError>
async fn delete_events_before( &self, cutoff: DateTime<Utc>, ) -> Result<u64, StoreError>
Deletes events with
at < cutoff. Returns how many. Also deletes event claims older
than cutoff.Source§async fn claim_event(
&self,
scope: ClaimScope<'_>,
kind: EventKind,
now: DateTime<Utc>,
window: TimeDelta,
) -> Result<bool, StoreError>
async fn claim_event( &self, scope: ClaimScope<'_>, kind: EventKind, now: DateTime<Utc>, window: TimeDelta, ) -> Result<bool, StoreError>
Claims the right to report a
kind event for scope, for deduplication across
processes. Succeeds (true) unless a claim for the same scope and kind was made after
now - window, and records now as the new claim when it does. Session and subject
claims are independent. Must be atomic across processes. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for PgStore
impl !UnwindSafe for PgStore
impl Freeze for PgStore
impl Send for PgStore
impl Sync for PgStore
impl Unpin for PgStore
impl UnsafeUnpin for PgStore
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
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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> ⓘ
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 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> ⓘ
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