New JWT implementation

This commit is contained in:
Adrian Woźniak 2023-08-11 15:25:26 +02:00
parent 335a84838f
commit 26dea34054
4 changed files with 100 additions and 54 deletions

116
Cargo.lock generated
View File

@ -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]]

View File

@ -6,4 +6,5 @@ members = [
'./crates/oswilno-parking-space',
'./crates/migration',
'./crates/oswilno-actix-admin',
'./crates/actix-jwt-session',
]

View File

@ -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?;

View File

@ -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<Claims>;
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<EncodingKey>,
jwt_ttl: Data<JWTTtl>,
jwt_ttl: Arc<JWTTtl>,
payload: SignInPayload,
db: Arc<DatabaseConnection>,
redis: Arc<redis_async_pool::RedisPool>,
@ -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<HttpResponse, Error>
#[autometrics]
#[get("/logout")]
async fn logout(
invalidated_jwts: Data<InvalidatedJWTStore>,
authenticated: Authenticated<Claims>,
redis: Data<redis_async_pool::RedisPool>,
) -> Result<HttpResponse, Error> {
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 {}))
}