pub struct PostgresDeviceStore { /* private fields */ }Available on crate features
device and postgres only.Expand description
PostgreSQL-backed DeviceStore.
Wrap an existing PgPool and call
init_schema once at startup.
§Encryption
Same shape as
SqliteDeviceStore: the
optional SessionCrypto envelope is applied to the bindings
blob only.
Implementations§
Source§impl PostgresDeviceStore
impl PostgresDeviceStore
Sourcepub fn new(pool: PgPool, crypto: SessionCrypto) -> Self
pub fn new(pool: PgPool, crypto: SessionCrypto) -> Self
Create an encrypted store (recommended for production).
Sourcepub fn with_clock(self, clock: Arc<dyn Clock>) -> Self
pub fn with_clock(self, clock: Arc<dyn Clock>) -> Self
Inject a Clock for deterministic-simulation testing.
Sourcepub fn with_sweep_config(self, config: SweepConfig) -> Self
pub fn with_sweep_config(self, config: SweepConfig) -> Self
Override the SweepConfig driving the retention ladder.
Sourcepub async fn init_schema(&self) -> Result<(), Error>
pub async fn init_schema(&self) -> Result<(), Error>
Create tables + indexes. Idempotent.
Trait Implementations§
Source§impl Clone for PostgresDeviceStore
impl Clone for PostgresDeviceStore
Source§fn clone(&self) -> PostgresDeviceStore
fn clone(&self) -> PostgresDeviceStore
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl DeviceStore for PostgresDeviceStore
impl DeviceStore for PostgresDeviceStore
Source§type Error = SqlDeviceStoreError
type Error = SqlDeviceStoreError
The error type returned by storage operations.
Source§fn load(
&self,
tenant_id: &TenantId,
id: &DeviceId,
) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
fn load( &self, tenant_id: &TenantId, id: &DeviceId, ) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
Load the device by id. Returns
None if absent.Source§fn find_by_fingerprint(
&self,
tenant_id: &TenantId,
hash: &FingerprintHash,
) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
fn find_by_fingerprint( &self, tenant_id: &TenantId, hash: &FingerprintHash, ) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
Look up a device by its keyed fingerprint within a tenant. Used as
the fast-path during request handling when no
device_id cookie is
present yet. Collisions must be vanishingly rare given a
per-tenant HMAC key, but implementations MUST scope the query by
tenant_id to prevent cross-tenant correlation.Source§fn find_for_user(
&self,
tenant_id: &TenantId,
user_id: &UserId,
limit: usize,
) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
fn find_for_user( &self, tenant_id: &TenantId, user_id: &UserId, limit: usize, ) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
List active devices for a user, newest-sighted first.
limit caps
the result so a high-cardinality user doesn’t blow up
device-management UIs. Read moreSource§fn find_by_refresh_family(
&self,
tenant_id: &TenantId,
family_id: &str,
) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
fn find_by_refresh_family( &self, tenant_id: &TenantId, family_id: &str, ) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
Find every device in
tenant carrying a
DeviceBinding::Refresh { family_id }
matching the supplied family_id. Used by the refresh-cascade
path to convert “this refresh-token family was compromised”
into the list of Devices to revoke. Read moreSource§fn save(
&self,
device: &Device,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn save( &self, device: &Device, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Persist a new device row, or overwrite an existing one. Idempotent.
Source§fn record_sighting(
&self,
tenant_id: &TenantId,
id: &DeviceId,
now: DateTime<Utc>,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn record_sighting( &self, tenant_id: &TenantId, id: &DeviceId, now: DateTime<Utc>, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Touch the
last_seen_at timestamp for the given device.
Implementations SHOULD perform this as a single UPDATE rather than
a load-modify-save round trip.Source§fn set_trust_level(
&self,
tenant_id: &TenantId,
id: &DeviceId,
level: DeviceTrustLevel,
now: DateTime<Utc>,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn set_trust_level( &self, tenant_id: &TenantId, id: &DeviceId, level: DeviceTrustLevel, now: DateTime<Utc>, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Set the trust level. Drives transitions across the
DeviceTrustLevel ladder. Setting to
DeviceTrustLevel::Revoked also stamps revoked_at = now.Source§fn delete(
&self,
tenant_id: &TenantId,
id: &DeviceId,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn delete( &self, tenant_id: &TenantId, id: &DeviceId, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Hard-delete the row. Idempotent. Used by the retention sweep once a
Revoked device has aged out of the configured grace window, and
by Art 17 erasure cascades.Source§fn sweep(
&self,
tenant_id: &TenantId,
now: DateTime<Utc>,
) -> impl Future<Output = Result<SweepCounts, Self::Error>> + Send
fn sweep( &self, tenant_id: &TenantId, now: DateTime<Utc>, ) -> impl Future<Output = Result<SweepCounts, Self::Error>> + Send
Drive the three-stage retention ladder: Trusted → Seen (after the
configured Trusted-idle window), Seen → Revoked (after the
configured Seen-idle window), Revoked → purged (after the
configured grace window). Returns the count of rows changed at
each stage. Read more
Source§fn find_active_for_user(
&self,
tenant_id: &TenantId,
user_id: &UserId,
limit: usize,
) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
fn find_active_for_user( &self, tenant_id: &TenantId, user_id: &UserId, limit: usize, ) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
Same as
find_for_user but excludes
Revoked rows. Default implementation filters in-memory after a
full find_for_user call; SQL backends SHOULD override with a
WHERE trust_level != 'Revoked' clause that the optimiser can
use against the trust-level index.Source§impl HealthCheck for PostgresDeviceStore
impl HealthCheck for PostgresDeviceStore
Auto Trait Implementations§
impl Freeze for PostgresDeviceStore
impl !RefUnwindSafe for PostgresDeviceStore
impl Send for PostgresDeviceStore
impl Sync for PostgresDeviceStore
impl Unpin for PostgresDeviceStore
impl UnsafeUnpin for PostgresDeviceStore
impl !UnwindSafe for PostgresDeviceStore
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
The archived version of the pointer metadata for this type.
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Converts some archived metadata to the pointer metadata for itself.
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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 moreSource§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Returns the layout of the type.
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Returns whether the given value has been niched. Read more
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
Writes data to
out indicating that a T is niched.