feat: redact sensitive informations

This commit is contained in:
Nathan Lamy 2025-08-26 01:01:08 +02:00
parent 3841e08a9f
commit 97f2fab89d

View file

@ -20,6 +20,47 @@ use tokio_cron_scheduler::{Job, JobScheduler};
mod api; mod api;
mod configuration; mod configuration;
mod parser; mod parser;
use std::fmt;
#[derive(Clone)]
struct RedactedEvent {
inner: serde_json::Value,
}
impl fmt::Debug for RedactedEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let redacted = redact_sensitive_fields(&self.inner);
write!(
f,
"{}",
serde_json::to_string_pretty(&redacted).unwrap_or_else(|_| "Invalid JSON".to_string())
)
}
}
fn redact_sensitive_fields(value: &serde_json::Value) -> serde_json::Value {
match value {
serde_json::Value::Object(map) => {
let mut new_map = serde_json::Map::new();
for (key, val) in map {
let key_lower = key.to_lowercase();
if key_lower.contains("username") || key_lower.contains("password") {
new_map.insert(
key.clone(),
serde_json::Value::String("***REDACTED***".to_string()),
);
} else {
new_map.insert(key.clone(), redact_sensitive_fields(val));
}
}
serde_json::Value::Object(new_map)
}
serde_json::Value::Array(arr) => {
serde_json::Value::Array(arr.iter().map(redact_sensitive_fields).collect())
}
_ => value.clone(),
}
}
#[tokio::main] #[tokio::main]
async fn main() -> redis::RedisResult<()> { async fn main() -> redis::RedisResult<()> {
@ -57,10 +98,12 @@ async fn main() -> redis::RedisResult<()> {
if let Ok(event) = serde_json::from_str::<Value>(&payload) { if let Ok(event) = serde_json::from_str::<Value>(&payload) {
match process_job(&event, &mut job_con, &config).await { match process_job(&event, &mut job_con, &config).await {
Ok(_) => { Ok(_) => {
println!("Job processed successfully: {:?}", event); let redacted_event = RedactedEvent { inner: event };
println!("Job processed successfully: {:?}", redacted_event);
} }
Err(e) => { Err(e) => {
eprintln!("Error processing job: {:?}, Error: {}", event, e); let redacted_event = RedactedEvent { inner: event };
eprintln!("Error processing job: {:?}, Error: {}", redacted_event, e);
} }
} }
} }
@ -136,7 +179,8 @@ async fn process_job(
config: &configuration::Settings, config: &configuration::Settings,
) -> RedisResult<()> { ) -> RedisResult<()> {
// Retrieve the class name from the job // Retrieve the class name from the job
println!("Processing job: {:?}", job); let redacted_job = RedactedEvent { inner: job.clone() };
println!("Processing job: {:?}", redacted_job);
let class_name = job["class_name"].as_str(); let class_name = job["class_name"].as_str();
if class_name.is_none() { if class_name.is_none() {
eprintln!("Job does not contain a class name."); eprintln!("Job does not contain a class name.");