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:
parent
b8ff35acea
commit
b12ad5d272
1 changed files with 32 additions and 20 deletions
|
|
@ -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
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue