1- use crate :: { async_trait, Result , Session , SessionStore } ;
1+ use crate :: { async_trait, Session , SessionStore } ;
2+ use base64:: { engine:: general_purpose:: STANDARD as BASE64 , Engine } ;
23
34/// A session store that serializes the entire session into a Cookie.
45///
56/// # ***This is not recommended for most production deployments.***
67///
7- /// This implementation uses [`bincode `](::bincode ) to serialize the
8- /// Session to decrease the size of the cookie. Note: There is a
9- /// maximum of 4093 cookie bytes allowed _per domain_, so the cookie
10- /// store is limited in capacity.
8+ /// This implementation uses [`bincode_json `](::bincode_json ) to
9+ /// serialize the Session to decrease the size of the cookie. Note:
10+ /// There is a maximum of 4093 cookie bytes allowed _per domain_, so
11+ /// the cookie store is limited in capacity.
1112///
1213/// **Note:** Currently, the data in the cookie is only signed, but *not
1314/// encrypted*. If the contained session data is sensitive and
@@ -29,24 +30,43 @@ impl CookieStore {
2930 }
3031}
3132
33+ #[ derive( thiserror:: Error , Debug ) ]
34+ #[ non_exhaustive]
35+ /// All errors that can occur in the [`CookieStore`]
36+ pub enum CookieStoreError {
37+ /// A bincode_json error
38+ #[ error( transparent) ]
39+ Bincode ( #[ from] bincode_json:: Error ) ,
40+
41+ /// A base64 error
42+ #[ error( transparent) ]
43+ Base64 ( #[ from] base64:: DecodeError ) ,
44+
45+ /// A json error
46+ #[ error( transparent) ]
47+ Json ( #[ from] serde_json:: Error ) ,
48+ }
49+
3250#[ async_trait]
3351impl SessionStore for CookieStore {
34- async fn load_session ( & self , cookie_value : String ) -> Result < Option < Session > > {
35- let serialized = base64:: decode ( cookie_value) ?;
36- let session: Session = bincode:: deserialize ( & serialized) ?;
52+ type Error = CookieStoreError ;
53+
54+ async fn load_session ( & self , cookie_value : String ) -> Result < Option < Session > , Self :: Error > {
55+ let serialized = BASE64 . decode ( cookie_value) ?;
56+ let session: Session = bincode_json:: from_slice ( & serialized) ?;
3757 Ok ( session. validate ( ) )
3858 }
3959
40- async fn store_session ( & self , session : Session ) -> Result < Option < String > > {
41- let serialized = bincode :: serialize ( & session) ?;
42- Ok ( Some ( base64 :: encode ( serialized) ) )
60+ async fn store_session ( & self , session : Session ) -> Result < Option < String > , Self :: Error > {
61+ let serialized = bincode_json :: to_vec ( & session) ?;
62+ Ok ( Some ( BASE64 . encode ( serialized) ) )
4363 }
4464
45- async fn destroy_session ( & self , _session : Session ) -> Result {
65+ async fn destroy_session ( & self , _session : Session ) -> Result < ( ) , Self :: Error > {
4666 Ok ( ( ) )
4767 }
4868
49- async fn clear_store ( & self ) -> Result {
69+ async fn clear_store ( & self ) -> Result < ( ) , Self :: Error > {
5070 Ok ( ( ) )
5171 }
5272}
@@ -57,7 +77,7 @@ mod tests {
5777 use async_std:: task;
5878 use std:: time:: Duration ;
5979 #[ async_std:: test]
60- async fn creating_a_new_session_with_no_expiry ( ) -> Result {
80+ async fn creating_a_new_session_with_no_expiry ( ) -> Result < ( ) , CookieStoreError > {
6181 let store = CookieStore :: new ( ) ;
6282 let mut session = Session :: new ( ) ;
6383 session. insert ( "key" , "Hello" ) ?;
@@ -72,7 +92,7 @@ mod tests {
7292 }
7393
7494 #[ async_std:: test]
75- async fn updating_a_session ( ) -> Result {
95+ async fn updating_a_session ( ) -> Result < ( ) , CookieStoreError > {
7696 let store = CookieStore :: new ( ) ;
7797 let mut session = Session :: new ( ) ;
7898
@@ -90,18 +110,18 @@ mod tests {
90110 }
91111
92112 #[ async_std:: test]
93- async fn updating_a_session_extending_expiry ( ) -> Result {
113+ async fn updating_a_session_extending_expiry ( ) -> Result < ( ) , CookieStoreError > {
94114 let store = CookieStore :: new ( ) ;
95115 let mut session = Session :: new ( ) ;
96116 session. expire_in ( Duration :: from_secs ( 1 ) ) ;
97- let original_expires = session. expiry ( ) . unwrap ( ) . clone ( ) ;
117+ let original_expires = * session. expiry ( ) . unwrap ( ) ;
98118 let cookie_value = store. store_session ( session) . await ?. unwrap ( ) ;
99119
100120 let mut session = store. load_session ( cookie_value. clone ( ) ) . await ?. unwrap ( ) ;
101121
102122 assert_eq ! ( session. expiry( ) . unwrap( ) , & original_expires) ;
103123 session. expire_in ( Duration :: from_secs ( 3 ) ) ;
104- let new_expires = session. expiry ( ) . unwrap ( ) . clone ( ) ;
124+ let new_expires = * session. expiry ( ) . unwrap ( ) ;
105125 let cookie_value = store. store_session ( session) . await ?. unwrap ( ) ;
106126
107127 let session = store. load_session ( cookie_value. clone ( ) ) . await ?. unwrap ( ) ;
@@ -114,7 +134,7 @@ mod tests {
114134 }
115135
116136 #[ async_std:: test]
117- async fn creating_a_new_session_with_expiry ( ) -> Result {
137+ async fn creating_a_new_session_with_expiry ( ) -> Result < ( ) , CookieStoreError > {
118138 let store = CookieStore :: new ( ) ;
119139 let mut session = Session :: new ( ) ;
120140 session. expire_in ( Duration :: from_secs ( 3 ) ) ;
0 commit comments