Skip to main content

vti_common/auth/handlers/
store.rs

1//! [`SessionStore`] impl for vti-common's [`KeyspaceHandle`].
2//!
3//! VTA + VTC use this directly: their `AuthBackend::Store` is
4//! `KeyspaceSessionStore` and the trait methods delegate to the
5//! free-standing helpers in [`crate::auth::session`].
6//!
7//! did-hosting writes its own `SessionStore` impl wrapping
8//! [`did_hosting_common::server::store::KeyspaceHandle`] —
9//! different concrete keyspace type, same trait surface.
10
11use async_trait::async_trait;
12
13use crate::auth::backend::SessionStore;
14use crate::auth::session::{self, Session};
15use crate::error::AppError;
16use crate::store::KeyspaceHandle;
17
18/// Thin newtype around [`KeyspaceHandle`] that implements
19/// [`SessionStore`].
20///
21/// Newtype rather than blanket-impl-on-`KeyspaceHandle` so the
22/// trait surface stays decoupled from the storage type (orphan
23/// rule + future-proofing — a different store would implement
24/// `SessionStore` on a different newtype).
25#[derive(Clone)]
26pub struct KeyspaceSessionStore {
27    inner: KeyspaceHandle,
28}
29
30impl KeyspaceSessionStore {
31    pub fn new(inner: KeyspaceHandle) -> Self {
32        Self { inner }
33    }
34
35    pub fn handle(&self) -> &KeyspaceHandle {
36        &self.inner
37    }
38}
39
40#[async_trait]
41impl SessionStore for KeyspaceSessionStore {
42    type Error = AppError;
43
44    async fn store_session(&self, s: &Session) -> Result<(), Self::Error> {
45        session::store_session(&self.inner, s).await
46    }
47
48    async fn get_session(&self, session_id: &str) -> Result<Option<Session>, Self::Error> {
49        session::get_session(&self.inner, session_id).await
50    }
51
52    async fn delete_session(&self, session_id: &str) -> Result<(), Self::Error> {
53        session::delete_session(&self.inner, session_id).await
54    }
55
56    async fn store_refresh_index(
57        &self,
58        refresh_token: &str,
59        session_id: &str,
60    ) -> Result<(), Self::Error> {
61        session::store_refresh_index(&self.inner, refresh_token, session_id).await
62    }
63
64    async fn take_session_id_by_refresh(
65        &self,
66        refresh_token: &str,
67    ) -> Result<Option<String>, Self::Error> {
68        session::take_session_id_by_refresh(&self.inner, refresh_token).await
69    }
70
71    async fn count_pending_challenges(&self, did: &str) -> Result<usize, Self::Error> {
72        session::count_pending_challenges(&self.inner, did).await
73    }
74}