diff --git a/Cargo.lock b/Cargo.lock index 5086fdc..5cf7761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,9 +26,9 @@ dependencies = [ "log", "once_cell", "parking_lot 0.12.1", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "smallvec", - "tokio 1.29.1", + "tokio 1.30.0", "tokio-util 0.7.3", ] @@ -81,8 +81,8 @@ dependencies = [ "futures-sink", "log", "memchr", - "pin-project-lite 0.2.9", - "tokio 1.29.1", + "pin-project-lite 0.2.12", + "tokio 1.30.0", "tokio-util 0.7.3", ] @@ -106,7 +106,7 @@ dependencies = [ "mime", "mime_guess", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", ] [[package]] @@ -149,11 +149,11 @@ dependencies = [ "local-channel", "mime", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "rand 0.8.5", "sha1 0.10.1", "smallvec", - "tokio 1.29.1", + "tokio 1.30.0", "tokio-util 0.7.3", "tracing", "zstd", @@ -172,10 +172,29 @@ dependencies = [ "jsonwebtoken", "serde", "time 0.3.25", - "tokio 1.29.1", + "tokio 1.30.0", "tracing", ] +[[package]] +name = "actix-jwt-session" +version = "0.1.0" +dependencies = [ + "actix-web", + "async-trait", + "bincode", + "futures", + "futures-lite", + "futures-util", + "jsonwebtoken", + "redis", + "redis-async-pool", + "serde", + "thiserror", + "tokio 1.30.0", + "uuid", +] + [[package]] name = "actix-macros" version = "0.2.3" @@ -208,7 +227,7 @@ dependencies = [ "serde_json", "serde_plain", "tempfile", - "tokio 1.29.1", + "tokio 1.30.0", ] [[package]] @@ -246,7 +265,7 @@ checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" dependencies = [ "actix-macros", "futures-core", - "tokio 1.29.1", + "tokio 1.30.0", ] [[package]] @@ -262,8 +281,8 @@ dependencies = [ "futures-util", "mio 0.8.8", "num_cpus", - "socket2", - "tokio 1.29.1", + "socket2 0.4.9", + "tokio 1.30.0", "tracing", ] @@ -275,7 +294,7 @@ checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" dependencies = [ "futures-core", "paste", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", ] [[package]] @@ -320,7 +339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" dependencies = [ "local-waker", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", ] [[package]] @@ -353,13 +372,13 @@ dependencies = [ "log", "mime", "once_cell", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "regex", "serde", "serde_json", "serde_urlencoded", "smallvec", - "socket2", + "socket2 0.4.9", "time 0.3.25", "url", ] @@ -640,7 +659,7 @@ dependencies = [ "blocking", "futures-lite", "once_cell", - "tokio 1.29.1", + "tokio 1.30.0", ] [[package]] @@ -658,7 +677,7 @@ dependencies = [ "parking", "polling", "slab", - "socket2", + "socket2 0.4.9", "waker-fn", "winapi 0.3.9", ] @@ -693,7 +712,7 @@ dependencies = [ "log", "memchr", "once_cell", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "pin-utils", "slab", "wasm-bindgen-futures", @@ -707,7 +726,7 @@ checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", ] [[package]] @@ -1186,7 +1205,7 @@ dependencies = [ "bytes 1.1.0", "futures-core", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "tokio 0.2.25", ] @@ -1666,7 +1685,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "waker-fn", ] @@ -1706,7 +1725,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "pin-utils", "slab", ] @@ -1837,7 +1856,7 @@ dependencies = [ "http", "indexmap 1.9.1", "slab", - "tokio 1.29.1", + "tokio 1.30.0", "tokio-util 0.7.3", "tracing", ] @@ -2281,7 +2300,7 @@ dependencies = [ "oswilno-contract", "sea-orm", "sea-orm-migration", - "tokio 1.29.1", + "tokio 1.30.0", ] [[package]] @@ -2515,7 +2534,7 @@ dependencies = [ "sea-orm", "serde", "serde_json", - "tokio 1.29.1", + "tokio 1.30.0", "toml 0.7.6", "tracing", "tracing-subscriber", @@ -2577,7 +2596,7 @@ dependencies = [ "sea-orm", "serde", "serde_json", - "tokio 1.29.1", + "tokio 1.30.0", ] [[package]] @@ -2604,7 +2623,7 @@ dependencies = [ "sea-orm", "serde", "time 0.3.25", - "tokio 1.29.1", + "tokio 1.30.0", "tracing", "uuid", ] @@ -2861,9 +2880,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -3713,6 +3732,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spez" version = "0.1.2" @@ -3835,7 +3864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" dependencies = [ "once_cell", - "tokio 1.29.1", + "tokio 1.30.0", "tokio-rustls", ] @@ -4045,25 +4074,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46409491c9375a693ce7032101970a54f8a2010efb77e13f70788f0d84489e39" dependencies = [ "autocfg", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", ] [[package]] name = "tokio" -version = "1.29.1" +version = "1.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" dependencies = [ - "autocfg", "backtrace", "bytes 1.1.0", "libc", "mio 0.8.8", "num_cpus", "parking_lot 0.12.1", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "signal-hook-registry", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys 0.48.0", ] @@ -4086,7 +4114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ "rustls", - "tokio 1.29.1", + "tokio 1.30.0", "webpki", ] @@ -4097,8 +4125,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" dependencies = [ "futures-core", - "pin-project-lite 0.2.9", - "tokio 1.29.1", + "pin-project-lite 0.2.12", + "tokio 1.30.0", ] [[package]] @@ -4124,8 +4152,8 @@ dependencies = [ "bytes 1.1.0", "futures-core", "futures-sink", - "pin-project-lite 0.2.9", - "tokio 1.29.1", + "pin-project-lite 0.2.12", + "tokio 1.30.0", "tracing", ] @@ -4180,7 +4208,7 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.12", "tracing-attributes", "tracing-core", ] @@ -4542,7 +4570,7 @@ dependencies = [ "askama", "serde", "serde_json", - "tokio 1.29.1", + "tokio 1.30.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1d7cec4..3eaf352 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ members = [ './crates/oswilno-parking-space', './crates/migration', './crates/oswilno-actix-admin', + './crates/actix-jwt-session', ] diff --git a/crates/migration/src/m20230809_135630_add_spot.rs b/crates/migration/src/m20230809_135630_add_spot.rs index 7479bd9..9f1f5af 100644 --- a/crates/migration/src/m20230809_135630_add_spot.rs +++ b/crates/migration/src/m20230809_135630_add_spot.rs @@ -11,9 +11,7 @@ impl MigrationTrait for Migration { m.alter_table( Table::alter() .table(ParkingSpace::ParkingSpaces) - .add_column( - ColumnDef::new(ParkingSpace::Spot) - .integer()) + .add_column(ColumnDef::new(ParkingSpace::Spot).integer()) .to_owned(), ) .await?; diff --git a/crates/oswilno-session/src/lib.rs b/crates/oswilno-session/src/lib.rs index 00db360..6dbd988 100644 --- a/crates/oswilno-session/src/lib.rs +++ b/crates/oswilno-session/src/lib.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use actix_jwt_authc::*; use actix_web::web::{Data, Form, ServiceConfig}; use actix_web::{get, post, HttpResponse}; -use askama_actix::{Template, TemplateToResponse as _}; +use askama_actix::Template; use autometrics::autometrics; use futures::channel::{mpsc, mpsc::Sender}; use futures::stream::Stream; @@ -20,6 +20,7 @@ use time::ext::*; use time::OffsetDateTime; use tokio::sync::Mutex; +mod extract_session; mod hashing; pub use oswilno_view::filters; @@ -30,11 +31,13 @@ pub type UserSession = Authenticated; pub struct JWTTtl(time::Duration); #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)] +#[serde(rename_all = "snake_case")] enum Audience { Web, } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)] +#[serde(rename_all = "snake_case")] pub struct Claims { #[serde(rename = "exp")] expires_at: usize, @@ -196,7 +199,7 @@ async fn login( let mut errors = Errors::default(); match login_inner( jwt_encoding_key, - jwt_ttl, + jwt_ttl.into_inner(), payload.into_inner(), db.into_inner(), redis.into_inner(), @@ -206,7 +209,12 @@ async fn login( { Ok(res) => Ok(HttpResponse::Ok().json(res)), Err(form) => Ok(HttpResponse::Ok().body( - (SignInPartialTemplate { form, lang, t, errors }) + (SignInPartialTemplate { + form, + lang, + t, + errors, + }) .render() .unwrap(), )), @@ -215,7 +223,7 @@ async fn login( async fn login_inner( jwt_encoding_key: Data, - jwt_ttl: Data, + jwt_ttl: Arc, payload: SignInPayload, db: Arc, redis: Arc, @@ -274,8 +282,13 @@ async fn login_inner( errors.push_global("Failed to sign in. Please try later"); return Err(payload); }; + if let Err(e) = conn - .set::<'_, _, _, String>(jwt_claims.jwt_id.as_bytes(), bin_value) + .set_ex::<'_, _, _, String>( + jwt_claims.jwt_id.as_bytes(), + bin_value, + jwt_ttl.0.as_seconds_f32() as usize, + ) .await { tracing::warn!("Failed to set sign-in claims in redis: {e}"); @@ -298,10 +311,16 @@ async fn session_info(authenticated: UserSession) -> Result #[autometrics] #[get("/logout")] async fn logout( - invalidated_jwts: Data, authenticated: Authenticated, + redis: Data, ) -> Result { - invalidated_jwts.add_to_invalidated(authenticated).await; + { + use redis::AsyncCommands; + let jwt_id = authenticated.claims.jwt_id; + if let Ok(mut conn) = redis.get().await { + if conn.del::<_, String>(jwt_id.as_bytes()).await.is_err() {} + } + } Ok(HttpResponse::Ok().json(EmptyResponse {})) }