From 9e2a0c75ca0d9a03b111b8f79e9b5ee696a33af9 Mon Sep 17 00:00:00 2001 From: Gerard Guillemas Martos Date: Wed, 13 Mar 2024 10:06:16 +0100 Subject: [PATCH] Fix: Consistently enforce session expiration (#3686) --- core/src/iam/signin.rs | 9 ++++++--- core/src/iam/signup.rs | 32 +++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/core/src/iam/signin.rs b/core/src/iam/signin.rs index c0a3cfe6..8723c4eb 100644 --- a/core/src/iam/signin.rs +++ b/core/src/iam/signin.rs @@ -244,7 +244,8 @@ pub async fn db( session.tk = Some(val.into()); session.ns = Some(ns.to_owned()); session.db = Some(db.to_owned()); - session.exp = exp; + // TODO(gguillemas): Enforce expiration once session lifetime can be customized. + session.exp = None; session.au = Arc::new((&u, Level::Database(ns.to_owned(), db.to_owned())).into()); // Check the authentication token match enc { @@ -296,7 +297,8 @@ pub async fn ns( // Set the authentication on the session session.tk = Some(val.into()); session.ns = Some(ns.to_owned()); - session.exp = exp; + // TODO(gguillemas): Enforce expiration once session lifetime can be customized. + session.exp = None; session.au = Arc::new((&u, Level::Namespace(ns.to_owned())).into()); // Check the authentication token match enc { @@ -346,7 +348,8 @@ pub async fn root( let enc = encode(&HEADER, &val, &key); // Set the authentication on the session session.tk = Some(val.into()); - session.exp = exp; + // TODO(gguillemas): Enforce expiration once session lifetime can be customized. + session.exp = None; session.au = Arc::new((&u, Level::Root).into()); // Check the authentication token match enc { diff --git a/core/src/iam/signup.rs b/core/src/iam/signup.rs index d316c55a..45fd60cf 100644 --- a/core/src/iam/signup.rs +++ b/core/src/iam/signup.rs @@ -70,20 +70,33 @@ pub async fn sc( // Create the authentication key let key = EncodingKey::from_secret(sv.code.as_ref()); // Create the authentication claim + let exp = Some( + match sv.session { + Some(v) => { + // The defined session duration must be valid + match Duration::from_std(v.0) { + // The resulting session expiration must be valid + Ok(d) => match Utc::now().checked_add_signed(d) { + Some(exp) => exp, + None => { + return Err(Error::InvalidSessionExpiration) + } + }, + Err(_) => { + return Err(Error::InvalidSessionDuration) + } + } + } + _ => Utc::now() + Duration::hours(1), + } + .timestamp(), + ); let val = Claims { iss: Some(SERVER_NAME.to_owned()), iat: Some(Utc::now().timestamp()), nbf: Some(Utc::now().timestamp()), jti: Some(Uuid::new_v4().to_string()), - exp: Some( - match sv.session { - Some(v) => { - Utc::now() + Duration::from_std(v.0).unwrap() - } - _ => Utc::now() + Duration::hours(1), - } - .timestamp(), - ), + exp, ns: Some(ns.to_owned()), db: Some(db.to_owned()), sc: Some(sc.to_owned()), @@ -100,6 +113,7 @@ pub async fn sc( session.db = Some(db.to_owned()); session.sc = Some(sc.to_owned()); session.sd = Some(Value::from(rid.to_owned())); + session.exp = exp; session.au = Arc::new(Auth::new(Actor::new( rid.to_string(), Default::default(),