pinakes-server: fix session token distribution bias; propagate auth audit

errors

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I96027de89511f13e9db6d277de2bcf436a6a6964
This commit is contained in:
raf 2026-03-07 16:55:43 +03:00
commit b12ad5d272
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF

View file

@ -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::<u32>() 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
},