style: cargo fmt --all — make codebase rustfmt-clean
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 2m59s
Build and Test / Build Agent (Windows) (push) Has started running
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled

First run of the build-and-test CI gate (cargo fmt --all -- --check) surfaced
pre-existing formatting drift across the agent and server crates. Apply rustfmt
across the workspace so the codebase meets its own CI gate. Pure formatting; no
logic changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 15:02:12 +00:00
parent f2e0456f8d
commit 1c5c1e78e7
48 changed files with 1174 additions and 797 deletions

View File

@@ -54,7 +54,10 @@ pub struct JwtConfig {
impl JwtConfig {
/// Create new JWT config
pub fn new(secret: String, expiry_hours: i64) -> Self {
Self { secret, expiry_hours }
Self {
secret,
expiry_hours,
}
}
/// Create a JWT token for a user
@@ -97,9 +100,9 @@ impl JwtConfig {
pub fn validate_token(&self, token: &str) -> Result<Claims> {
// SEC-13: Explicit validation configuration
let mut validation = Validation::default();
validation.validate_exp = true; // Enforce expiration check
validation.validate_exp = true; // Enforce expiration check
validation.validate_nbf = false; // Not using "not before" claim
validation.leeway = 0; // No clock skew tolerance
validation.leeway = 0; // No clock skew tolerance
let token_data = decode::<Claims>(
token,
@@ -129,12 +132,14 @@ mod tests {
let config = JwtConfig::new("test-secret".to_string(), 24);
let user_id = Uuid::new_v4();
let token = config.create_token(
user_id,
"testuser",
"admin",
vec!["view".to_string(), "control".to_string()],
).unwrap();
let token = config
.create_token(
user_id,
"testuser",
"admin",
vec!["view".to_string(), "control".to_string()],
)
.unwrap();
let claims = config.validate_token(&token).unwrap();
assert_eq!(claims.username, "testuser");

View File

@@ -8,7 +8,7 @@ pub mod password;
pub mod token_blacklist;
pub use jwt::{Claims, JwtConfig};
pub use password::{hash_password, verify_password, generate_random_password};
pub use password::{generate_random_password, hash_password, verify_password};
pub use token_blacklist::TokenBlacklist;
use axum::{

View File

@@ -6,7 +6,7 @@
use anyhow::{anyhow, Result};
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2, Algorithm, Version, Params,
Algorithm, Argon2, Params, Version,
};
/// Hash a password using Argon2id
@@ -22,9 +22,9 @@ pub fn hash_password(password: &str) -> Result<String> {
// Explicitly use Argon2id (Algorithm::Argon2id)
let argon2 = Argon2::new(
Algorithm::Argon2id, // SEC-9: Explicit Argon2id variant
Version::V0x13, // Latest version
Params::default(), // Default params (19456 KiB, 2 iterations, 1 parallelism)
Algorithm::Argon2id, // SEC-9: Explicit Argon2id variant
Version::V0x13, // Latest version
Params::default(), // Default params (19456 KiB, 2 iterations, 1 parallelism)
);
let hash = argon2
@@ -35,12 +35,14 @@ pub fn hash_password(password: &str) -> Result<String> {
/// Verify a password against a stored hash
pub fn verify_password(password: &str, hash: &str) -> Result<bool> {
let parsed_hash = PasswordHash::new(hash)
.map_err(|e| anyhow!("Invalid password hash format: {}", e))?;
let parsed_hash =
PasswordHash::new(hash).map_err(|e| anyhow!("Invalid password hash format: {}", e))?;
// Argon2::default() uses Argon2id, but we verify against the hash's embedded algorithm
let argon2 = Argon2::default();
Ok(argon2.verify_password(password.as_bytes(), &parsed_hash).is_ok())
Ok(argon2
.verify_password(password.as_bytes(), &parsed_hash)
.is_ok())
}
/// Generate a random password (for initial admin)

View File

@@ -6,7 +6,7 @@
use std::collections::HashSet;
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::{info, debug};
use tracing::{debug, info};
/// Token blacklist for revocation
///
@@ -41,7 +41,10 @@ impl TokenBlacklist {
let was_new = tokens.insert(token.to_string());
if was_new {
debug!("Token revoked and added to blacklist (length: {})", token.len());
debug!(
"Token revoked and added to blacklist (length: {})",
token.len()
);
}
}
@@ -92,7 +95,11 @@ impl TokenBlacklist {
let removed = original_len - tokens.len();
if removed > 0 {
info!("Cleaned {} expired tokens from blacklist ({} remaining)", removed, tokens.len());
info!(
"Cleaned {} expired tokens from blacklist ({} remaining)",
removed,
tokens.len()
);
}
removed