Microservice to bring 2FA to self hosted PDSes

light changes to logging changes

+39 -35
+1
Cargo.lock
··· 2595 2595 "tracing", 2596 2596 "tracing-subscriber", 2597 2597 "urlencoding", 2598 + "valuable", 2598 2599 ] 2599 2600 2600 2601 [[package]]
+3 -2
Cargo.toml
··· 11 11 dotenvy = "0.15.7" 12 12 serde = { version = "1.0", features = ["derive"] } 13 13 serde_json = "1.0" 14 - tracing = "0.1" 15 - tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json"] } 14 + tracing = { version = "0.1.44" } 15 + tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json", "serde", ] } 16 16 hyper-util = { version = "0.1.19", features = ["client", "client-legacy"] } 17 17 tower-http = { version = "0.6", features = ["cors", "compression-zstd", "trace"] } 18 18 tower_governor = { version = "0.8.0", features = ["axum", "tracing"] } ··· 39 39 josekit = "0.10.3" 40 40 dashmap = "6.1" 41 41 tower = "0.5" 42 + valuable = "0.1.1"
+35 -33
src/main.rs
··· 30 30 use tower_governor::{ 31 31 GovernorLayer, governor::GovernorConfigBuilder, key_extractor::SmartIpKeyExtractor, 32 32 }; 33 + use tower_http::trace::{DefaultOnRequest, HttpMakeClassifier}; 33 34 use tower_http::{ 34 35 compression::CompressionLayer, 35 36 cors::{Any, CorsLayer}, 36 37 trace::TraceLayer, 37 38 }; 38 - use tracing::log; 39 + use tracing::{Span, log}; 39 40 use tracing_subscriber::{EnvFilter, fmt, prelude::*}; 40 41 41 42 mod auth; ··· 198 199 199 200 #[tokio::main] 200 201 async fn main() -> Result<(), Box<dyn std::error::Error>> { 201 - setup_tracing(); 202 202 let pds_env_location = 203 203 env::var("PDS_ENV_LOCATION").unwrap_or_else(|_| "/pds/pds.env".to_string()); 204 204 ··· 208 208 "Error loading pds.env file (ignore if you loaded your variables in the environment somehow else): {e}" 209 209 ); 210 210 } 211 + // Sets up after the pds.env file is loaded 212 + setup_tracing(); 211 213 212 214 let pds_root = 213 215 env::var("PDS_DATA_DIRECTORY").expect("PDS_DATA_DIRECTORY is not set in your pds.env file"); ··· 390 392 .map(|v| v.eq_ignore_ascii_case("true") || v == "1") 391 393 .unwrap_or(false); 392 394 393 - let app = if request_logging { 394 - app.layer(TraceLayer::new_for_http() 395 - .make_span_with(|req: &axum::http::Request<Body>| { 396 - let headers: std::collections::HashMap<&str, Vec<&str>> = req.headers() 397 - .keys() 398 - .map(|k| { 399 - let vals: Vec<&str> = req.headers() 400 - .get_all(k) 401 - .iter() 402 - .filter_map(|v| v.to_str().ok()) 403 - .collect(); 404 - (k.as_str(), vals) 405 - }) 406 - .collect(); 407 - let headers_json = serde_json::to_string(&headers).unwrap_or_default(); 395 + if request_logging { 396 + app = app.layer(request_trace_layer()); 397 + } 408 398 409 - tracing::info_span!("request", 410 - method = %req.method(), 411 - path = %req.uri().path(), 412 - headers = %headers_json, 413 - ) 414 - }) 415 - .on_response(|resp: &axum::http::Response<Body>, latency: Duration, _span: &tracing::Span| { 416 - tracing::info!(status = resp.status().as_u16(), latency_ms = latency.as_millis() as u64, "response"); 417 - }) 418 - ) 399 + let app = app 419 400 .layer(CompressionLayer::new()) 420 401 .layer(cors) 421 - .with_state(state) 422 - } else { 423 - app.layer(CompressionLayer::new()) 424 - .layer(cors) 425 - .with_state(state) 426 - }; 402 + .with_state(state); 427 403 428 404 let host = env::var("GATEKEEPER_HOST").unwrap_or_else(|_| "0.0.0.0".to_string()); 429 405 let port: u16 = env::var("GATEKEEPER_PORT") ··· 493 469 _ = terminate => {}, 494 470 } 495 471 } 472 + 473 + fn request_trace_layer() -> TraceLayer< 474 + HttpMakeClassifier, 475 + impl Fn(&axum::http::Request<Body>) -> Span + Clone, 476 + DefaultOnRequest, 477 + impl Fn(&axum::http::Response<Body>, Duration, &Span) + Clone, 478 + > { 479 + TraceLayer::new_for_http() 480 + .make_span_with(|req: &axum::http::Request<Body>| { 481 + let headers = req.headers(); 482 + tracing::info_span!("request", 483 + method = %req.method(), 484 + path = %req.uri().path(), 485 + headers = %format!("{:?}", headers), 486 + ) 487 + }) 488 + .on_response( 489 + |resp: &axum::http::Response<Body>, latency: Duration, _span: &tracing::Span| { 490 + tracing::info!( 491 + status = resp.status().as_u16(), 492 + latency_ms = latency.as_millis() as u64, 493 + "response" 494 + ); 495 + }, 496 + ) 497 + }