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
|
// Record failed login attempt in audit log
|
||||||
let _ = pinakes_core::audit::record_action(
|
if let Err(e) = pinakes_core::audit::record_action(
|
||||||
&state.storage,
|
&state.storage,
|
||||||
None,
|
None,
|
||||||
pinakes_core::model::AuditAction::LoginFailed,
|
pinakes_core::model::AuditAction::LoginFailed,
|
||||||
Some(format!("username: {}", req.username)),
|
Some(format!("username: {}", req.username)),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
tracing::warn!(error = %e, "failed to record failed login audit");
|
||||||
|
}
|
||||||
|
|
||||||
return Err(StatusCode::UNAUTHORIZED);
|
return Err(StatusCode::UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point we know the user exists and password is valid
|
// 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
|
// Generate session token using unbiased uniform distribution
|
||||||
let token: String = (0..48)
|
let token: String = {
|
||||||
.map(|_| {
|
use rand::seq::IndexedRandom;
|
||||||
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
const CHARSET: &[u8] =
|
||||||
abcdefghijklmnopqrstuvwxyz\
|
b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
0123456789";
|
let mut rng = rand::rng();
|
||||||
let idx = (rand::random::<u32>() as usize) % CHARSET.len();
|
(0..48)
|
||||||
CHARSET[idx] as char
|
.map(|_| *CHARSET.choose(&mut rng).expect("non-empty charset") as char)
|
||||||
})
|
.collect()
|
||||||
.collect();
|
};
|
||||||
|
|
||||||
let role = user.role;
|
let role = user.role;
|
||||||
let username = user.username.clone();
|
let username = user.username.clone();
|
||||||
|
|
@ -112,13 +115,16 @@ pub async fn login(
|
||||||
tracing::info!(username = %username, role = %role, "login successful");
|
tracing::info!(username = %username, role = %role, "login successful");
|
||||||
|
|
||||||
// Record successful login in audit log
|
// Record successful login in audit log
|
||||||
let _ = pinakes_core::audit::record_action(
|
if let Err(e) = pinakes_core::audit::record_action(
|
||||||
&state.storage,
|
&state.storage,
|
||||||
None,
|
None,
|
||||||
pinakes_core::model::AuditAction::LoginSuccess,
|
pinakes_core::model::AuditAction::LoginSuccess,
|
||||||
Some(format!("username: {}, role: {}", username, role)),
|
Some(format!("username: {}, role: {}", username, role)),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
tracing::warn!(error = %e, "failed to record login audit");
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Json(LoginResponse {
|
Ok(Json(LoginResponse {
|
||||||
token,
|
token,
|
||||||
|
|
@ -146,13 +152,16 @@ pub async fn logout(
|
||||||
|
|
||||||
// Record logout in audit log
|
// Record logout in audit log
|
||||||
if let Some(user) = username {
|
if let Some(user) = username {
|
||||||
let _ = pinakes_core::audit::record_action(
|
if let Err(e) = pinakes_core::audit::record_action(
|
||||||
&state.storage,
|
&state.storage,
|
||||||
None,
|
None,
|
||||||
pinakes_core::model::AuditAction::Logout,
|
pinakes_core::model::AuditAction::Logout,
|
||||||
Some(format!("username: {}", user)),
|
Some(format!("username: {}", user)),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
tracing::warn!(error = %e, "failed to record logout audit");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatusCode::OK
|
StatusCode::OK
|
||||||
|
|
@ -221,13 +230,16 @@ pub async fn revoke_all_sessions(
|
||||||
tracing::info!(username = %username, count = count, "revoked all user sessions");
|
tracing::info!(username = %username, count = count, "revoked all user sessions");
|
||||||
|
|
||||||
// Record in audit log
|
// Record in audit log
|
||||||
let _ = pinakes_core::audit::record_action(
|
if let Err(e) = pinakes_core::audit::record_action(
|
||||||
&state.storage,
|
&state.storage,
|
||||||
None,
|
None,
|
||||||
pinakes_core::model::AuditAction::Logout,
|
pinakes_core::model::AuditAction::Logout,
|
||||||
Some(format!("revoked all sessions for username: {}", username)),
|
Some(format!("revoked all sessions for username: {}", username)),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
tracing::warn!(error = %e, "failed to record session revocation audit");
|
||||||
|
}
|
||||||
|
|
||||||
StatusCode::OK
|
StatusCode::OK
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue