actix_session/storage/
cookie.rs1use actix_web::cookie::time::Duration;
2use anyhow::Error;
3
4use super::SessionKey;
5use crate::storage::{
6 interface::{LoadError, SaveError, SessionState, UpdateError},
7 SessionStore,
8};
9
10#[derive(Default)]
49#[non_exhaustive]
50pub struct CookieSessionStore;
51
52impl SessionStore for CookieSessionStore {
53 async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> {
54 serde_json::from_str(session_key.as_ref())
55 .map(Some)
56 .map_err(anyhow::Error::new)
57 .map_err(LoadError::Deserialization)
58 }
59
60 async fn save(
61 &self,
62 session_state: SessionState,
63 _ttl: &Duration,
64 ) -> Result<SessionKey, SaveError> {
65 let session_key = serde_json::to_string(&session_state)
66 .map_err(anyhow::Error::new)
67 .map_err(SaveError::Serialization)?;
68
69 session_key
70 .try_into()
71 .map_err(Into::into)
72 .map_err(SaveError::Other)
73 }
74
75 async fn update(
76 &self,
77 _session_key: SessionKey,
78 session_state: SessionState,
79 ttl: &Duration,
80 ) -> Result<SessionKey, UpdateError> {
81 self.save(session_state, ttl)
82 .await
83 .map_err(|err| match err {
84 SaveError::Serialization(err) => UpdateError::Serialization(err),
85 SaveError::Other(err) => UpdateError::Other(err),
86 })
87 }
88
89 async fn update_ttl(&self, _session_key: &SessionKey, _ttl: &Duration) -> Result<(), Error> {
90 Ok(())
91 }
92
93 async fn delete(&self, _session_key: &SessionKey) -> Result<(), anyhow::Error> {
94 Ok(())
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use crate::{storage::utils::generate_session_key, test_helpers::acceptance_test_suite};
102
103 #[actix_web::test]
104 async fn test_session_workflow() {
105 acceptance_test_suite(CookieSessionStore::default, false).await;
106 }
107
108 #[actix_web::test]
109 async fn loading_a_random_session_key_returns_deserialization_error() {
110 let store = CookieSessionStore::default();
111 let session_key = generate_session_key();
112 assert!(matches!(
113 store.load(&session_key).await.unwrap_err(),
114 LoadError::Deserialization(_),
115 ));
116 }
117}