From 01af34caae4b56e3217be456bbf72fcfd76a3ab8 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Wed, 29 Mar 2023 21:05:02 -0700 Subject: [PATCH 1/4] updates for async-sessions-v4 --- sessions/Cargo.toml | 9 ++++-- sessions/examples/sessions.rs | 3 +- sessions/src/lib.rs | 6 ++-- sessions/src/session_conn_ext.rs | 3 +- sessions/src/session_handler.rs | 52 +++++++++++++++++--------------- 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/sessions/Cargo.toml b/sessions/Cargo.toml index 2f9e8b3247..ac38dca199 100644 --- a/sessions/Cargo.toml +++ b/sessions/Cargo.toml @@ -12,14 +12,19 @@ categories = ["web-programming::http-server", "web-programming"] [dependencies] trillium-cookies = { path = "../cookies", version = "^0.4.0" } -trillium = { path = "../trillium", version = "^0.2.0"} -async-session = "3.0.0" +trillium = { path = "../trillium", version = "^0.2.0" } +async-session = { git = "https://github.com/http-rs/async-session", branch = "overhaul-session-and-session-store" } log = "0.4.17" +hmac = { version = "0.12.1", features = ["std"] } +sha2 = "0.10.6" +base64 = "0.21.0" +serde = "1.0.159" [dev-dependencies] env_logger = "0.10.0" trillium-smol = { path = "../smol" } trillium-testing = { path = "../testing" } +async-session-memory-store = { git = "https://github.com/http-rs/async-session", branch = "overhaul-session-and-session-store" } [package.metadata.cargo-udeps.ignore] development = ["trillium-testing"] diff --git a/sessions/examples/sessions.rs b/sessions/examples/sessions.rs index bd346c6352..54c775caa3 100644 --- a/sessions/examples/sessions.rs +++ b/sessions/examples/sessions.rs @@ -1,6 +1,7 @@ +use async_session_memory_store::MemoryStore; use trillium::Conn; use trillium_cookies::CookiesHandler; -use trillium_sessions::{MemoryStore, SessionConnExt, SessionHandler}; +use trillium_sessions::{SessionConnExt, SessionHandler}; pub fn main() { env_logger::init(); diff --git a/sessions/src/lib.rs b/sessions/src/lib.rs index b98398554d..4460ea9443 100644 --- a/sessions/src/lib.rs +++ b/sessions/src/lib.rs @@ -81,7 +81,9 @@ store if it requires it ``` use trillium::Conn; use trillium_cookies::{CookiesHandler, cookie::Cookie}; -use trillium_sessions::{MemoryStore, SessionConnExt, SessionHandler}; +use trillium_sessions::{SessionConnExt, SessionHandler}; +use async_session_memory_store::MemoryStore; + # std::env::set_var("TRILLIUM_SESSION_SECRET", "this is just for testing and you should not do this"); let session_secret = std::env::var("TRILLIUM_SESSION_SECRET").unwrap(); @@ -119,4 +121,4 @@ pub use session_conn_ext::SessionConnExt; mod session_handler; pub use session_handler::{sessions, SessionHandler}; -pub use async_session::{CookieStore, MemoryStore, Session}; +pub use async_session::Session; diff --git a/sessions/src/session_conn_ext.rs b/sessions/src/session_conn_ext.rs index d7a94fbcf0..a4363e621d 100644 --- a/sessions/src/session_conn_ext.rs +++ b/sessions/src/session_conn_ext.rs @@ -1,4 +1,5 @@ -use async_session::{serde::Serialize, Session}; +use async_session::Session; +use serde::Serialize; use trillium::Conn; /** diff --git a/sessions/src/session_handler.rs b/sessions/src/session_handler.rs index 4bc4ec9b30..0620a13992 100644 --- a/sessions/src/session_handler.rs +++ b/sessions/src/session_handler.rs @@ -1,10 +1,8 @@ const BASE64_DIGEST_LEN: usize = 44; -use async_session::{ - base64, - hmac::{Hmac, Mac, NewMac}, - sha2::Sha256, - Session, SessionStore, -}; +use async_session::{Session, SessionStore}; +use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; +use hmac::{digest::generic_array::GenericArray, Hmac, Mac}; +use sha2::Sha256; use std::{ fmt::{self, Debug, Formatter}, iter, @@ -35,7 +33,10 @@ pub struct SessionHandler { older_keys: Vec, } -impl Debug for SessionHandler { +impl Debug for SessionHandler +where + Store: Debug, +{ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("SessionHandler") .field("store", &self.store) @@ -51,7 +52,10 @@ impl Debug for SessionHandler { } } -impl SessionHandler { +impl SessionHandler +where + Store: SessionStore + Send + Sync + 'static, +{ /** Constructs a SessionHandler from the given [`async_session::SessionStore`] and secret. The `secret` MUST be @@ -82,7 +86,8 @@ impl SessionHandler { ```rust # use std::time::Duration; - # use trillium_sessions::{SessionHandler, MemoryStore}; + # use trillium_sessions::SessionHandler; + # use async_session_memory_store::MemoryStore; # use trillium_cookies::{CookiesHandler, cookie::SameSite}; # std::env::set_var("TRILLIUM_SESSION_SECRETS", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); // this logic will be unique to your deployment @@ -187,12 +192,7 @@ impl SessionHandler { async fn load_or_create(&self, cookie_value: Option<&str>) -> Session { let session = match cookie_value { - Some(cookie_value) => self - .store - .load_session(String::from(cookie_value)) - .await - .ok() - .flatten(), + Some(cookie_value) => self.store.load_session(cookie_value).await.ok().flatten(), None => None, }; @@ -230,7 +230,7 @@ impl SessionHandler { mac.update(cookie.value().as_bytes()); // Cookie's new value is [MAC | original-value]. - let mut new_value = base64::encode(mac.finalize().into_bytes()); + let mut new_value = BASE64.encode(mac.finalize().into_bytes()); new_value.push_str(cookie.value()); cookie.set_value(new_value); } @@ -248,7 +248,7 @@ impl SessionHandler { // Split [MAC | original-value] into its two parts. let (digest_str, value) = cookie_value.split_at(BASE64_DIGEST_LEN); - let digest = match base64::decode(digest_str) { + let digest = match BASE64.decode(digest_str) { Ok(digest) => digest, Err(_) => { log::trace!("bad base64 digest"); @@ -261,14 +261,17 @@ impl SessionHandler { .find_map(|key| { let mut mac = Hmac::::new_from_slice(key.signing()).expect("good key"); mac.update(value.as_bytes()); - mac.verify(&digest).ok() + mac.verify(GenericArray::from_slice(&digest)).ok() }) .map(|_| value) } } #[async_trait] -impl Handler for SessionHandler { +impl Handler for SessionHandler +where + Store: SessionStore + Send + Sync + 'static, +{ async fn run(&self, mut conn: Conn) -> Conn { let session = conn.take_state::(); @@ -290,20 +293,19 @@ impl Handler for SessionHandler { } async fn before_send(&self, mut conn: Conn) -> Conn { - if let Some(session) = conn.take_state::() { - let session_to_keep = session.clone(); + if let Some(mut session) = conn.take_state::() { let secure = conn.is_secure(); if session.is_destroyed() { - self.store.destroy_session(session).await.ok(); + self.store.destroy_session(&mut session).await.ok(); conn.cookies_mut() .remove(Cookie::named(self.cookie_name.clone())); } else if self.save_unchanged || session.data_changed() { - if let Ok(Some(cookie_value)) = self.store.store_session(session).await { + if let Ok(Some(cookie_value)) = self.store.store_session(&mut session).await { conn.cookies_mut() .add(self.build_cookie(secure, cookie_value)); } } - conn.with_state(session_to_keep) + conn.with_state(session) } else { conn } @@ -313,7 +315,7 @@ impl Handler for SessionHandler { /// Alias for [`SessionHandler::new`] pub fn sessions(store: Store, secret: impl AsRef<[u8]>) -> SessionHandler where - Store: SessionStore, + Store: SessionStore + Send + Sync + 'static, { SessionHandler::new(store, secret) } From 704540a9635194467cdc32710a0fa9d49f56f7d1 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Wed, 29 Mar 2023 21:09:49 -0700 Subject: [PATCH 2/4] reexport sessionstore --- sessions/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sessions/src/lib.rs b/sessions/src/lib.rs index 4460ea9443..42cf86ea22 100644 --- a/sessions/src/lib.rs +++ b/sessions/src/lib.rs @@ -121,4 +121,4 @@ pub use session_conn_ext::SessionConnExt; mod session_handler; pub use session_handler::{sessions, SessionHandler}; -pub use async_session::Session; +pub use async_session::{Session, SessionStore}; From 83aefbf6b9f8ac1947f7fb6b636f0ecb6e8004cf Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Thu, 30 Mar 2023 11:39:00 -0700 Subject: [PATCH 3/4] no longer rely on reexported stores --- aws-lambda-example/Cargo.toml | 1 + aws-lambda-example/src/main.rs | 3 ++- example/Cargo.toml | 1 + example/src/main.rs | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/aws-lambda-example/Cargo.toml b/aws-lambda-example/Cargo.toml index cd88ebf587..795cbec285 100644 --- a/aws-lambda-example/Cargo.toml +++ b/aws-lambda-example/Cargo.toml @@ -24,3 +24,4 @@ trillium-sessions = { path = "../sessions" } trillium-askama = { path = "../askama" } futures-lite = "1.12.0" askama = "0.12.0" +async-session-cookie-store = { git = "https://github.com/http-rs/async-session", branch = "overhaul-session-and-session-store" } diff --git a/aws-lambda-example/src/main.rs b/aws-lambda-example/src/main.rs index 7c769f7ac6..4beb1dea10 100644 --- a/aws-lambda-example/src/main.rs +++ b/aws-lambda-example/src/main.rs @@ -5,7 +5,8 @@ use trillium_aws_lambda::LambdaConnExt; use trillium_cookies::CookiesHandler; use trillium_logger::Logger; use trillium_router::{Router, RouterConnExt}; -use trillium_sessions::{CookieStore, SessionConnExt, SessionHandler}; +use trillium_sessions::{SessionConnExt, SessionHandler}; +use async_session_cookie_store::CookieStore; #[derive(Template)] #[template(path = "hello.html")] diff --git a/example/Cargo.toml b/example/Cargo.toml index fab231d3e6..d5acbf7736 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -31,6 +31,7 @@ trillium-method-override = { path = "../method-override" } trillium-conn-id = { path = "../conn-id" } trillium-caching-headers = { path = "../caching-headers" } trillium-compression = { path = "../compression" } +async-session-memory-store = { git = "https://github.com/http-rs/async-session", branch = "overhaul-session-and-session-store" } [dev-dependencies] trillium-testing = { path = "../testing" } diff --git a/example/src/main.rs b/example/src/main.rs index 504e75be12..510f8cb114 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -11,10 +11,11 @@ use trillium_conn_id::log_formatter::conn_id; use trillium_logger::apache_common; use trillium_router::{Router, RouterConnExt}; use trillium_rustls::RustlsConnector; -use trillium_sessions::{MemoryStore, SessionConnExt}; +use trillium_sessions::SessionConnExt; use trillium_smol::TcpConnector; use trillium_static_compiled::static_compiled; use trillium_websockets::{Message, WebSocket, WebSocketConn}; +use async_session_memory_store::MemoryStore; type Proxy = trillium_proxy::Proxy>; #[derive(Template)] From 21745100fd53ce3dca088cf0d4d977c848a13ce0 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Thu, 30 Mar 2023 11:48:12 -0700 Subject: [PATCH 4/4] fmt --- aws-lambda-example/src/main.rs | 2 +- example/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws-lambda-example/src/main.rs b/aws-lambda-example/src/main.rs index 4beb1dea10..6fae2525ee 100644 --- a/aws-lambda-example/src/main.rs +++ b/aws-lambda-example/src/main.rs @@ -1,4 +1,5 @@ use askama::Template; +use async_session_cookie_store::CookieStore; use trillium::Conn; use trillium_askama::AskamaConnExt; use trillium_aws_lambda::LambdaConnExt; @@ -6,7 +7,6 @@ use trillium_cookies::CookiesHandler; use trillium_logger::Logger; use trillium_router::{Router, RouterConnExt}; use trillium_sessions::{SessionConnExt, SessionHandler}; -use async_session_cookie_store::CookieStore; #[derive(Template)] #[template(path = "hello.html")] diff --git a/example/src/main.rs b/example/src/main.rs index 510f8cb114..3d68cbbae5 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -1,4 +1,5 @@ use askama::Template; +use async_session_memory_store::MemoryStore; use futures_lite::prelude::*; use std::time::Duration; use trillium::{Conn, Handler}; @@ -15,7 +16,6 @@ use trillium_sessions::SessionConnExt; use trillium_smol::TcpConnector; use trillium_static_compiled::static_compiled; use trillium_websockets::{Message, WebSocket, WebSocketConn}; -use async_session_memory_store::MemoryStore; type Proxy = trillium_proxy::Proxy>; #[derive(Template)]