From 97f2fab89d65ced1bcf72c0b324905022c896397 Mon Sep 17 00:00:00 2001 From: Nathan Lamy Date: Tue, 26 Aug 2025 01:01:08 +0200 Subject: [PATCH] feat: redact sensitive informations --- src/main.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 70b6e77..2ec9e4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,47 @@ use tokio_cron_scheduler::{Job, JobScheduler}; mod api; mod configuration; 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] async fn main() -> redis::RedisResult<()> { @@ -57,10 +98,12 @@ async fn main() -> redis::RedisResult<()> { if let Ok(event) = serde_json::from_str::(&payload) { match process_job(&event, &mut job_con, &config).await { Ok(_) => { - println!("Job processed successfully: {:?}", event); + let redacted_event = RedactedEvent { inner: event }; + println!("Job processed successfully: {:?}", redacted_event); } 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, ) -> RedisResult<()> { // 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(); if class_name.is_none() { eprintln!("Job does not contain a class name.");