Strip all 413 #[allow(dead_code)] annotations from 139 files and remove the actual dead code they were suppressing: unused struct fields (and their constructor sites), unused methods/functions, and entire dead structs. Key removals: - trading_engine compliance: ~50 dead structs/fields across audit, reporting, SOX modules - trading_service: dead execution engine fields, broker routing, paper trading methods - ml_training_service: dead TLS validation (~340 lines), GPU state, monitoring fields - backtesting_service: dead model cache, TLS validation, TradeSignal fields - risk: dead VaR engine fields, safety coordinator fields, position tracker fields - adaptive-strategy: dead ensemble methods, regime detection, sizing functions 147 files changed, -4264 net lines. Workspace compiles with 0 errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
127 lines
4.3 KiB
Rust
127 lines
4.3 KiB
Rust
//! TLS configuration for Backtesting Service with mutual TLS
|
|
//!
|
|
//! This module provides enterprise-grade TLS configuration for the backtesting service:
|
|
//! - Mutual TLS (mTLS) for all gRPC connections
|
|
//! - Static certificate management via config crate
|
|
//! - Client certificate validation and authentication
|
|
//! - Performance optimized for HFT requirements
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
// Re-export shared TLS types from common for backward compatibility
|
|
#[allow(unused_imports)]
|
|
pub use common::tls::{ClientIdentity, TlsProtocolVersion, UserRole};
|
|
// TLS imports - TLS feature should be enabled in Cargo.toml
|
|
use tonic::transport::{Certificate, Identity, ServerTlsConfig};
|
|
use tracing::info;
|
|
|
|
/// TLS configuration for the trading service
|
|
#[derive(Debug, Clone)]
|
|
pub struct BacktestingServiceTlsConfig {
|
|
/// Server certificate and private key
|
|
pub server_identity: Identity,
|
|
/// CA certificate for client verification
|
|
pub ca_certificate: Certificate,
|
|
/// Require client certificates
|
|
pub require_client_cert: bool,
|
|
}
|
|
|
|
impl BacktestingServiceTlsConfig {
|
|
/// Create TLS configuration from certificate files
|
|
pub async fn from_files(
|
|
cert_path: &str,
|
|
key_path: &str,
|
|
ca_cert_path: &str,
|
|
require_client_cert: bool,
|
|
) -> Result<Self> {
|
|
info!("Loading TLS certificates from filesystem");
|
|
|
|
// Read server certificate and key
|
|
let cert_pem = tokio::fs::read_to_string(cert_path)
|
|
.await
|
|
.with_context(|| format!("Failed to read certificate file: {}", cert_path))?;
|
|
|
|
let key_pem = tokio::fs::read_to_string(key_path)
|
|
.await
|
|
.with_context(|| format!("Failed to read private key file: {}", key_path))?;
|
|
|
|
// Combine certificate and key for server identity
|
|
let server_identity = Identity::from_pem(cert_pem, key_pem);
|
|
|
|
// Read CA certificate for client verification
|
|
let ca_pem = tokio::fs::read_to_string(ca_cert_path)
|
|
.await
|
|
.with_context(|| format!("Failed to read CA certificate file: {}", ca_cert_path))?;
|
|
|
|
let ca_certificate = Certificate::from_pem(ca_pem);
|
|
|
|
info!(
|
|
"TLS certificates loaded successfully - mTLS: {}",
|
|
require_client_cert
|
|
);
|
|
|
|
Ok(Self {
|
|
server_identity,
|
|
ca_certificate,
|
|
require_client_cert,
|
|
})
|
|
}
|
|
|
|
/// Convert to tonic ServerTlsConfig
|
|
pub fn to_server_tls_config(&self) -> ServerTlsConfig {
|
|
let mut tls_config = ServerTlsConfig::new().identity(self.server_identity.clone());
|
|
|
|
if self.require_client_cert {
|
|
tls_config = tls_config.client_ca_root(self.ca_certificate.clone());
|
|
}
|
|
|
|
tls_config
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_client_identity_authorization() {
|
|
let trading_identity = ClientIdentity {
|
|
common_name: "trader1.trading.foxhunt.internal".to_string(),
|
|
organizational_unit: "trading".to_string(),
|
|
serial_number: "12345".to_string(),
|
|
issuer: "Foxhunt Trading CA".to_string(),
|
|
};
|
|
|
|
assert!(trading_identity.is_authorized_for_trading());
|
|
assert!(trading_identity.is_authorized_for_readonly());
|
|
assert_eq!(trading_identity.get_role(), UserRole::Trader);
|
|
|
|
let readonly_identity = ClientIdentity {
|
|
common_name: "analyst1.analytics.foxhunt.internal".to_string(),
|
|
organizational_unit: "analytics".to_string(),
|
|
serial_number: "12346".to_string(),
|
|
issuer: "Foxhunt Trading CA".to_string(),
|
|
};
|
|
|
|
assert!(!readonly_identity.is_authorized_for_trading());
|
|
assert!(readonly_identity.is_authorized_for_readonly());
|
|
assert_eq!(readonly_identity.get_role(), UserRole::Analyst);
|
|
}
|
|
|
|
#[test]
|
|
fn test_user_role_permissions() {
|
|
let trader = UserRole::Trader;
|
|
let permissions = trader.get_permissions();
|
|
|
|
assert!(permissions.contains(&"trading.submit_order"));
|
|
assert!(permissions.contains(&"trading.cancel_order"));
|
|
assert!(!permissions.contains(&"system.configure"));
|
|
|
|
let readonly = UserRole::ReadOnly;
|
|
let readonly_permissions = readonly.get_permissions();
|
|
|
|
assert!(!readonly_permissions.contains(&"trading.submit_order"));
|
|
assert!(readonly_permissions.contains(&"analytics.view_data"));
|
|
}
|
|
}
|