From b12ad5d27286459f549838d4005778c2873d1b4e Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sat, 7 Mar 2026 16:55:43 +0300 Subject: [PATCH] pinakes-server: fix session token distribution bias; propagate auth audit errors Signed-off-by: NotAShelf Change-Id: I96027de89511f13e9db6d277de2bcf436a6a6964 --- crates/pinakes-server/src/routes/auth.rs | 50 +++++++++++++++--------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/crates/pinakes-server/src/routes/auth.rs b/crates/pinakes-server/src/routes/auth.rs index 7769d84..af8c45b 100644 --- a/crates/pinakes-server/src/routes/auth.rs +++ b/crates/pinakes-server/src/routes/auth.rs @@ -64,30 +64,33 @@ pub async fn login( } // Record failed login attempt in audit log - let _ = pinakes_core::audit::record_action( + if let Err(e) = pinakes_core::audit::record_action( &state.storage, None, pinakes_core::model::AuditAction::LoginFailed, Some(format!("username: {}", req.username)), ) - .await; + .await + { + tracing::warn!(error = %e, "failed to record failed login audit"); + } return Err(StatusCode::UNAUTHORIZED); } // At this point we know the user exists and password is valid - let user = user.expect("user should exist at this point"); + let user = user.ok_or(StatusCode::INTERNAL_SERVER_ERROR)?; - // Generate session token - let token: String = (0..48) - .map(|_| { - const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ - abcdefghijklmnopqrstuvwxyz\ - 0123456789"; - let idx = (rand::random::() as usize) % CHARSET.len(); - CHARSET[idx] as char - }) - .collect(); + // Generate session token using unbiased uniform distribution + let token: String = { + use rand::seq::IndexedRandom; + const CHARSET: &[u8] = + b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + let mut rng = rand::rng(); + (0..48) + .map(|_| *CHARSET.choose(&mut rng).expect("non-empty charset") as char) + .collect() + }; let role = user.role; let username = user.username.clone(); @@ -112,13 +115,16 @@ pub async fn login( tracing::info!(username = %username, role = %role, "login successful"); // Record successful login in audit log - let _ = pinakes_core::audit::record_action( + if let Err(e) = pinakes_core::audit::record_action( &state.storage, None, pinakes_core::model::AuditAction::LoginSuccess, Some(format!("username: {}, role: {}", username, role)), ) - .await; + .await + { + tracing::warn!(error = %e, "failed to record login audit"); + } Ok(Json(LoginResponse { token, @@ -146,13 +152,16 @@ pub async fn logout( // Record logout in audit log if let Some(user) = username { - let _ = pinakes_core::audit::record_action( + if let Err(e) = pinakes_core::audit::record_action( &state.storage, None, pinakes_core::model::AuditAction::Logout, Some(format!("username: {}", user)), ) - .await; + .await + { + tracing::warn!(error = %e, "failed to record logout audit"); + } } } StatusCode::OK @@ -221,13 +230,16 @@ pub async fn revoke_all_sessions( tracing::info!(username = %username, count = count, "revoked all user sessions"); // Record in audit log - let _ = pinakes_core::audit::record_action( + if let Err(e) = pinakes_core::audit::record_action( &state.storage, None, pinakes_core::model::AuditAction::Logout, Some(format!("revoked all sessions for username: {}", username)), ) - .await; + .await + { + tracing::warn!(error = %e, "failed to record session revocation audit"); + } StatusCode::OK },