use std::sync::Arc;
use axum_extra::extract::PrivateCookieJar;
use super::traits::SessionStore;
use crate::types::SessionId;
#[derive(Debug)]
pub enum SessionResolution<A> {
NoCookie,
Expired,
Authenticated(A),
}
pub struct SessionResolver<S: SessionStore> {
session_store: Arc<S>,
cookie_name: Arc<str>,
}
impl<S: SessionStore> Clone for SessionResolver<S> {
fn clone(&self) -> Self {
Self {
session_store: Arc::clone(&self.session_store),
cookie_name: Arc::clone(&self.cookie_name),
}
}
}
impl<S: SessionStore> SessionResolver<S> {
pub(super) fn new(session_store: Arc<S>, cookie_name: Arc<str>) -> Self {
Self {
session_store,
cookie_name,
}
}
pub(super) fn cookie_name(&self) -> &str {
&self.cookie_name
}
pub async fn resolve(
&self,
jar: &PrivateCookieJar,
) -> Result<SessionResolution<S::AuthContext>, S::Error> {
let Some(cookie) = jar.get(&self.cookie_name) else {
return Ok(SessionResolution::NoCookie);
};
let session_id = SessionId(cookie.value().to_string());
match self.session_store.find(&session_id).await? {
Some(ctx) => Ok(SessionResolution::Authenticated(ctx)),
None => Ok(SessionResolution::Expired),
}
}
}