From 67bed6695b36e41fb20a4371ba153c0f2940bccd Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Thu, 16 Feb 2023 20:13:43 -0800 Subject: [PATCH 1/4] updates for async-sessions v4 --- .cargo/config.toml | 2 ++ .github/workflows/ci.yaml | 7 ---- Cargo.toml | 12 ++++--- src/lib.rs | 67 +++++++++++++++++++++++++-------------- 4 files changed, 54 insertions(+), 34 deletions(-) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..8af59dd --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[env] +RUST_TEST_THREADS = "1" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0c30e9b..c2fb418 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -43,13 +43,6 @@ jobs: command: check args: --all --bins --examples - - name: check avoid-dev-deps - uses: actions-rs/cargo@v1 - if: matrix.rust == 'nightly' - with: - command: check - args: --all -Z avoid-dev-deps - - name: tests uses: actions-rs/cargo@v1 with: diff --git a/Cargo.toml b/Cargo.toml index e3da58f..0e608a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,15 @@ keywords = ["sessions", "tide", "async-session", "redis"] categories = ["web-programming::http-server", "web-programming", "database"] [dependencies.redis] -version = "0.21.0" -features = ["aio", "async-std-comp"] +version = "0.22.3" +features = ["aio"] [dependencies] -async-session = "3.0.0" +async-session = { git = "https://github.com/http-rs/async-session", branch = "overhaul-session-and-session-store", default-features = false } +base64 = "0.21.0" +serde_json = "1.0.93" +thiserror = "1.0.38" [dev-dependencies] -async-std = { version = "1.9.0", features = ["attributes"] } +redis = { version = "0.22.3", features = ["async-std-comp"] } +async-std = { version = "1.12.0", features = ["attributes"] } diff --git a/src/lib.rs b/src/lib.rs index 0241b08..7a120ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,9 @@ //! # async-redis-session //! ```rust -//! use async_redis_session::RedisSessionStore; +//! use async_redis_session::{RedisSessionStore, Error}; //! use async_session::{Session, SessionStore}; //! -//! # fn main() -> async_session::Result { async_std::task::block_on(async { +//! # fn main() -> Result<(), Error> { async_std::task::block_on(async { //! let store = RedisSessionStore::new("redis://127.0.0.1/")?; //! //! let mut session = Session::new(); @@ -25,9 +25,27 @@ unused_qualifications )] -use async_session::{async_trait, serde_json, Result, Session, SessionStore}; +use async_session::{async_trait, Session, SessionStore}; use redis::{aio::Connection, AsyncCommands, Client, IntoConnectionInfo, RedisResult}; +/// Errors that can arise in the operation of the session stores +/// included in this crate +#[derive(thiserror::Error, Debug)] +#[non_exhaustive] +pub enum Error { + /// an error that comes from sqlx + #[error(transparent)] + Redis(#[from] redis::RedisError), + + /// an error that comes from serde_json + #[error(transparent)] + SerdeJson(#[from] serde_json::Error), + + /// an error that comes from base64 + #[error(transparent)] + Base64(#[from] base64::DecodeError), +} + /// # RedisSessionStore #[derive(Clone, Debug)] pub struct RedisSessionStore { @@ -77,12 +95,12 @@ impl RedisSessionStore { self } - async fn ids(&self) -> Result> { + async fn ids(&self) -> Result, Error> { Ok(self.connection().await?.keys(self.prefix_key("*")).await?) } /// returns the number of sessions in this store - pub async fn count(&self) -> Result { + pub async fn count(&self) -> Result { if self.prefix.is_none() { let mut connection = self.connection().await?; Ok(redis::cmd("DBSIZE").query_async(&mut connection).await?) @@ -92,7 +110,7 @@ impl RedisSessionStore { } #[cfg(test)] - async fn ttl_for_session(&self, session: &Session) -> Result { + async fn ttl_for_session(&self, session: &Session) -> Result { Ok(self .connection() .await? @@ -101,21 +119,24 @@ impl RedisSessionStore { } fn prefix_key(&self, key: impl AsRef) -> String { + let key = key.as_ref(); if let Some(ref prefix) = self.prefix { - format!("{}{}", prefix, key.as_ref()) + format!("{prefix}{key}") } else { - key.as_ref().into() + key.to_string() } } async fn connection(&self) -> RedisResult { - self.client.get_async_std_connection().await + self.client.get_async_connection().await } } #[async_trait] impl SessionStore for RedisSessionStore { - async fn load_session(&self, cookie_value: String) -> Result> { + type Error = Error; + + async fn load_session(&self, cookie_value: String) -> Result, Self::Error> { let id = Session::id_from_cookie_value(&cookie_value)?; let mut connection = self.connection().await?; let record: Option = connection.get(self.prefix_key(id)).await?; @@ -125,7 +146,7 @@ impl SessionStore for RedisSessionStore { } } - async fn store_session(&self, session: Session) -> Result> { + async fn store_session(&self, session: Session) -> Result, Self::Error> { let id = self.prefix_key(session.id()); let string = serde_json::to_string(&session)?; @@ -144,14 +165,14 @@ impl SessionStore for RedisSessionStore { Ok(session.into_cookie_value()) } - async fn destroy_session(&self, session: Session) -> Result { + async fn destroy_session(&self, session: Session) -> Result<(), Self::Error> { let mut connection = self.connection().await?; - let key = self.prefix_key(session.id().to_string()); + let key = self.prefix_key(session.id()); connection.del(key).await?; Ok(()) } - async fn clear_store(&self) -> Result { + async fn clear_store(&self) -> Result<(), Self::Error> { let mut connection = self.connection().await?; if self.prefix.is_none() { @@ -179,7 +200,7 @@ mod tests { } #[async_std::test] - async fn creating_a_new_session_with_no_expiry() -> Result { + async fn creating_a_new_session_with_no_expiry() -> Result<(), Error> { let store = test_store().await; let mut session = Session::new(); session.insert("key", "value")?; @@ -195,7 +216,7 @@ mod tests { } #[async_std::test] - async fn updating_a_session() -> Result { + async fn updating_a_session() -> Result<(), Error> { let store = test_store().await; let mut session = Session::new(); @@ -214,11 +235,11 @@ mod tests { } #[async_std::test] - async fn updating_a_session_extending_expiry() -> Result { + async fn updating_a_session_extending_expiry() -> Result<(), Error> { let store = test_store().await; let mut session = Session::new(); session.expire_in(Duration::from_secs(5)); - let original_expires = session.expiry().unwrap().clone(); + let original_expires = *session.expiry().unwrap(); let cookie_value = store.store_session(session).await?.unwrap(); let mut session = store.load_session(cookie_value.clone()).await?.unwrap(); @@ -227,7 +248,7 @@ mod tests { assert_eq!(session.expiry().unwrap(), &original_expires); session.expire_in(Duration::from_secs(10)); - let new_expires = session.expiry().unwrap().clone(); + let new_expires = *session.expiry().unwrap(); store.store_session(session).await?; let session = store.load_session(cookie_value.clone()).await?.unwrap(); @@ -244,7 +265,7 @@ mod tests { } #[async_std::test] - async fn creating_a_new_session_with_expiry() -> Result { + async fn creating_a_new_session_with_expiry() -> Result<(), Error> { let store = test_store().await; let mut session = Session::new(); session.expire_in(Duration::from_secs(3)); @@ -268,7 +289,7 @@ mod tests { } #[async_std::test] - async fn destroying_a_single_session() -> Result { + async fn destroying_a_single_session() -> Result<(), Error> { let store = test_store().await; for _ in 0..3i8 { store.store_session(Session::new()).await?; @@ -287,7 +308,7 @@ mod tests { } #[async_std::test] - async fn clearing_the_whole_store() -> Result { + async fn clearing_the_whole_store() -> Result<(), Error> { let store = test_store().await; for _ in 0..3i8 { store.store_session(Session::new()).await?; @@ -301,7 +322,7 @@ mod tests { } #[async_std::test] - async fn prefixes() -> Result { + async fn prefixes() -> Result<(), Error> { test_store().await; // clear the db let store = RedisSessionStore::new("redis://127.0.0.1")?.with_prefix("sessions/"); From 9f89318d874231b905fc9f56361010409c272227 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Wed, 29 Mar 2023 20:03:44 -0700 Subject: [PATCH 2/4] update to latest v4 --- src/lib.rs | 66 +++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7a120ba..3d44e55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,8 +9,8 @@ //! let mut session = Session::new(); //! session.insert("key", "value")?; //! -//! let cookie_value = store.store_session(session).await?.unwrap(); -//! let session = store.load_session(cookie_value).await?.unwrap(); +//! let cookie_value = store.store_session(&mut session).await?.unwrap(); +//! let session = store.load_session(&cookie_value).await?.unwrap(); //! assert_eq!(&session.get::("key").unwrap(), "value"); //! # Ok(()) }) } //! ``` @@ -136,8 +136,8 @@ impl RedisSessionStore { impl SessionStore for RedisSessionStore { type Error = Error; - async fn load_session(&self, cookie_value: String) -> Result, Self::Error> { - let id = Session::id_from_cookie_value(&cookie_value)?; + async fn load_session(&self, cookie_value: &str) -> Result, Self::Error> { + let id = Session::id_from_cookie_value(cookie_value)?; let mut connection = self.connection().await?; let record: Option = connection.get(self.prefix_key(id)).await?; match record { @@ -146,7 +146,7 @@ impl SessionStore for RedisSessionStore { } } - async fn store_session(&self, session: Session) -> Result, Self::Error> { + async fn store_session(&self, session: &mut Session) -> Result, Self::Error> { let id = self.prefix_key(session.id()); let string = serde_json::to_string(&session)?; @@ -162,10 +162,10 @@ impl SessionStore for RedisSessionStore { } }; - Ok(session.into_cookie_value()) + Ok(session.take_cookie_value()) } - async fn destroy_session(&self, session: Session) -> Result<(), Self::Error> { + async fn destroy_session(&self, session: &mut Session) -> Result<(), Self::Error> { let mut connection = self.connection().await?; let key = self.prefix_key(session.id()); connection.del(key).await?; @@ -205,9 +205,9 @@ mod tests { let mut session = Session::new(); session.insert("key", "value")?; let cloned = session.clone(); - let cookie_value = store.store_session(session).await?.unwrap(); + let cookie_value = store.store_session(&mut session).await?.unwrap(); - let loaded_session = store.load_session(cookie_value).await?.unwrap(); + let loaded_session = store.load_session(&cookie_value).await?.unwrap(); assert_eq!(cloned.id(), loaded_session.id()); assert_eq!("value", &loaded_session.get::("key").unwrap()); @@ -221,13 +221,13 @@ mod tests { let mut session = Session::new(); session.insert("key", "value")?; - let cookie_value = store.store_session(session).await?.unwrap(); + let cookie_value = store.store_session(&mut session).await?.unwrap(); - let mut session = store.load_session(cookie_value.clone()).await?.unwrap(); + let mut session = store.load_session(&cookie_value).await?.unwrap(); session.insert("key", "other value")?; - assert_eq!(None, store.store_session(session).await?); + assert_eq!(None, store.store_session(&mut session).await?); - let session = store.load_session(cookie_value.clone()).await?.unwrap(); + let session = store.load_session(&cookie_value).await?.unwrap(); assert_eq!(&session.get::("key").unwrap(), "other value"); assert_eq!(1, store.count().await.unwrap()); @@ -240,18 +240,18 @@ mod tests { let mut session = Session::new(); session.expire_in(Duration::from_secs(5)); let original_expires = *session.expiry().unwrap(); - let cookie_value = store.store_session(session).await?.unwrap(); + let cookie_value = store.store_session(&mut session).await?.unwrap(); - let mut session = store.load_session(cookie_value.clone()).await?.unwrap(); + let mut session = store.load_session(&cookie_value).await?.unwrap(); let ttl = store.ttl_for_session(&session).await?; assert!(ttl > 3 && ttl < 5); assert_eq!(session.expiry().unwrap(), &original_expires); session.expire_in(Duration::from_secs(10)); let new_expires = *session.expiry().unwrap(); - store.store_session(session).await?; + store.store_session(&mut session).await?; - let session = store.load_session(cookie_value.clone()).await?.unwrap(); + let session = store.load_session(&cookie_value).await?.unwrap(); let ttl = store.ttl_for_session(&session).await?; assert!(ttl > 8 && ttl < 10); assert_eq!(session.expiry().unwrap(), &new_expires); @@ -272,18 +272,18 @@ mod tests { session.insert("key", "value")?; let cloned = session.clone(); - let cookie_value = store.store_session(session).await?.unwrap(); + let cookie_value = store.store_session(&mut session).await?.unwrap(); assert!(store.ttl_for_session(&cloned).await? > 1); - let loaded_session = store.load_session(cookie_value.clone()).await?.unwrap(); + let loaded_session = store.load_session(&cookie_value).await?.unwrap(); assert_eq!(cloned.id(), loaded_session.id()); assert_eq!("value", &loaded_session.get::("key").unwrap()); assert!(!loaded_session.is_expired()); task::sleep(Duration::from_secs(2)).await; - assert_eq!(None, store.load_session(cookie_value).await?); + assert_eq!(None, store.load_session(&cookie_value).await?); Ok(()) } @@ -292,18 +292,18 @@ mod tests { async fn destroying_a_single_session() -> Result<(), Error> { let store = test_store().await; for _ in 0..3i8 { - store.store_session(Session::new()).await?; + store.store_session(&mut Session::new()).await?; } - let cookie = store.store_session(Session::new()).await?.unwrap(); + let cookie = store.store_session(&mut Session::new()).await?.unwrap(); assert_eq!(4, store.count().await?); - let session = store.load_session(cookie.clone()).await?.unwrap(); - store.destroy_session(session.clone()).await.unwrap(); - assert_eq!(None, store.load_session(cookie).await?); + let mut session = store.load_session(&cookie).await?.unwrap(); + store.destroy_session(&mut session).await.unwrap(); + assert_eq!(None, store.load_session(&cookie).await?); assert_eq!(3, store.count().await?); // attempting to destroy the session again is not an error - assert!(store.destroy_session(session).await.is_ok()); + assert!(store.destroy_session(&mut session).await.is_ok()); Ok(()) } @@ -311,7 +311,7 @@ mod tests { async fn clearing_the_whole_store() -> Result<(), Error> { let store = test_store().await; for _ in 0..3i8 { - store.store_session(Session::new()).await?; + store.store_session(&mut Session::new()).await?; } assert_eq!(3, store.count().await?); @@ -329,19 +329,19 @@ mod tests { store.clear_store().await?; for _ in 0..3i8 { - store.store_session(Session::new()).await?; + store.store_session(&mut Session::new()).await?; } let mut session = Session::new(); session.insert("key", "value")?; - let cookie_value = store.store_session(session).await?.unwrap(); + let cookie_value = store.store_session(&mut session).await?.unwrap(); - let mut session = store.load_session(cookie_value.clone()).await?.unwrap(); + let mut session = store.load_session(&cookie_value).await?.unwrap(); session.insert("key", "other value")?; - assert_eq!(None, store.store_session(session).await?); + assert_eq!(None, store.store_session(&mut session).await?); - let session = store.load_session(cookie_value.clone()).await?.unwrap(); + let session = store.load_session(&cookie_value).await?.unwrap(); assert_eq!(&session.get::("key").unwrap(), "other value"); assert_eq!(4, store.count().await.unwrap()); @@ -351,7 +351,7 @@ mod tests { assert_eq!(0, other_store.count().await.unwrap()); for _ in 0..3i8 { - other_store.store_session(Session::new()).await?; + other_store.store_session(&mut Session::new()).await?; } other_store.clear_store().await?; From a122c4e95adc3affaedd875ff57cf43c12632ee9 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Wed, 29 Mar 2023 20:08:53 -0700 Subject: [PATCH 3/4] remove some clones --- src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3d44e55..983e101 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ + //! # async-redis-session //! ```rust //! use async_redis_session::{RedisSessionStore, Error}; @@ -204,11 +205,10 @@ mod tests { let store = test_store().await; let mut session = Session::new(); session.insert("key", "value")?; - let cloned = session.clone(); let cookie_value = store.store_session(&mut session).await?.unwrap(); let loaded_session = store.load_session(&cookie_value).await?.unwrap(); - assert_eq!(cloned.id(), loaded_session.id()); + assert_eq!(session.id(), loaded_session.id()); assert_eq!("value", &loaded_session.get::("key").unwrap()); assert!(!loaded_session.is_expired()); @@ -270,14 +270,13 @@ mod tests { let mut session = Session::new(); session.expire_in(Duration::from_secs(3)); session.insert("key", "value")?; - let cloned = session.clone(); let cookie_value = store.store_session(&mut session).await?.unwrap(); - assert!(store.ttl_for_session(&cloned).await? > 1); + assert!(store.ttl_for_session(&session).await? > 1); let loaded_session = store.load_session(&cookie_value).await?.unwrap(); - assert_eq!(cloned.id(), loaded_session.id()); + assert_eq!(session.id(), loaded_session.id()); assert_eq!("value", &loaded_session.get::("key").unwrap()); assert!(!loaded_session.is_expired()); From ca2b4eb654afd851fb3b690537be4374a01b3d58 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Wed, 29 Mar 2023 21:09:59 -0700 Subject: [PATCH 4/4] fmt --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 983e101..f07d2ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ - //! # async-redis-session //! ```rust //! use async_redis_session::{RedisSessionStore, Error};