torii_core/session/
opaque.rs1use std::sync::Arc;
7
8use async_trait::async_trait;
9use chrono::{Duration, Utc};
10
11use crate::{
12 Error, Session, SessionStorage, SessionToken, UserId,
13 error::{SessionError, StorageError},
14};
15
16use super::provider::SessionProvider;
17
18pub struct OpaqueSessionProvider<S: SessionStorage> {
24 storage: Arc<S>,
25}
26
27impl<S: SessionStorage> OpaqueSessionProvider<S> {
28 pub fn new(storage: Arc<S>) -> Self {
30 Self { storage }
31 }
32}
33
34#[async_trait]
35impl<S: SessionStorage> SessionProvider for OpaqueSessionProvider<S> {
36 async fn create_session(
37 &self,
38 user_id: &UserId,
39 user_agent: Option<String>,
40 ip_address: Option<String>,
41 duration: Duration,
42 ) -> Result<Session, Error> {
43 let session = Session::builder()
44 .token(SessionToken::new_random())
45 .user_id(user_id.clone())
46 .user_agent(user_agent)
47 .ip_address(ip_address)
48 .expires_at(Utc::now() + duration)
49 .build()?;
50
51 let session = self
52 .storage
53 .create_session(&session)
54 .await
55 .map_err(|e| StorageError::Database(e.to_string()))?;
56
57 Ok(session)
58 }
59
60 async fn get_session(&self, token: &SessionToken) -> Result<Session, Error> {
61 let session = self
62 .storage
63 .get_session(token)
64 .await
65 .map_err(|e| StorageError::Database(e.to_string()))?;
66
67 if let Some(session) = session {
68 if session.is_expired() {
69 self.delete_session(token).await?;
70 return Err(Error::Session(SessionError::Expired));
71 }
72 Ok(session)
73 } else {
74 Err(Error::Session(SessionError::NotFound))
75 }
76 }
77
78 async fn delete_session(&self, token: &SessionToken) -> Result<(), Error> {
79 self.storage
80 .delete_session(token)
81 .await
82 .map_err(|e| StorageError::Database(e.to_string()))?;
83
84 Ok(())
85 }
86
87 async fn cleanup_expired_sessions(&self) -> Result<(), Error> {
88 self.storage
89 .cleanup_expired_sessions()
90 .await
91 .map_err(|e| StorageError::Database(e.to_string()))?;
92
93 Ok(())
94 }
95
96 async fn delete_sessions_for_user(&self, user_id: &UserId) -> Result<(), Error> {
97 self.storage
98 .delete_sessions_for_user(user_id)
99 .await
100 .map_err(|e| StorageError::Database(e.to_string()))?;
101
102 Ok(())
103 }
104}