#![allow(dead_code)]
use std::path::PathBuf;
#[derive(Debug, Clone, Default)]
pub struct TlsConfig {
pub ca_cert_path: Option<PathBuf>,
pub insecure: bool,
}
impl TlsConfig {
pub fn configure_blocking_builder(
&self,
mut builder: reqwest::blocking::ClientBuilder,
) -> reqwest::blocking::ClientBuilder {
if self.insecure {
builder = builder.danger_accept_invalid_certs(true);
}
if let Some(ref ca_path) = self.ca_cert_path
&& let Ok(pem) = std::fs::read(ca_path)
&& let Ok(cert) = reqwest::Certificate::from_pem(&pem)
{
builder = builder.add_root_certificate(cert);
}
builder
}
pub fn build_blocking_client(&self) -> Result<reqwest::blocking::Client, reqwest::Error> {
self.configure_blocking_builder(reqwest::blocking::Client::builder())
.build()
}
pub fn build_async_client(&self) -> Result<reqwest::Client, reqwest::Error> {
let mut builder = reqwest::Client::builder();
if self.insecure {
builder = builder.danger_accept_invalid_certs(true);
}
if let Some(ref ca_path) = self.ca_cert_path
&& let Ok(pem) = std::fs::read(ca_path)
&& let Ok(cert) = reqwest::Certificate::from_pem(&pem)
{
builder = builder.add_root_certificate(cert);
}
builder.build()
}
}
#[derive(Clone)]
pub struct Configuration {
pub base_path: String,
pub user_agent: Option<String>,
pub client: reqwest::blocking::Client,
pub basic_auth: Option<BasicAuth>,
pub oauth_access_token: Option<String>,
pub bearer_access_token: Option<String>,
pub api_key: Option<ApiKey>,
pub tls: TlsConfig,
pub cookie_header: Option<String>,
}
impl std::fmt::Debug for Configuration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Configuration")
.field("base_path", &self.base_path)
.field("user_agent", &self.user_agent)
.field(
"basic_auth",
&self
.basic_auth
.as_ref()
.map(|(u, _)| (u, Some("[REDACTED]"))),
)
.field(
"oauth_access_token",
&self.oauth_access_token.as_ref().map(|_| "[REDACTED]"),
)
.field(
"bearer_access_token",
&self.bearer_access_token.as_ref().map(|_| "[REDACTED]"),
)
.field("api_key", &self.api_key.as_ref().map(|_| "[REDACTED]"))
.field("tls", &self.tls)
.field(
"cookie_header",
&self.cookie_header.as_ref().map(|_| "[REDACTED]"),
)
.finish()
}
}
pub type BasicAuth = (String, Option<String>);
#[derive(Debug, Clone)]
pub struct ApiKey {
pub prefix: Option<String>,
pub key: String,
}
impl Configuration {
pub fn new() -> Configuration {
Configuration::default()
}
pub fn with_tls(tls: TlsConfig) -> Configuration {
let client = tls
.build_blocking_client()
.expect("Failed to build HTTP client with TLS config");
Configuration {
base_path: "http://localhost/torc-service/v1".to_owned(),
user_agent: Some("OpenAPI-Generator/v0.7.0/rust".to_owned()),
client,
basic_auth: None,
oauth_access_token: None,
bearer_access_token: None,
api_key: None,
tls,
cookie_header: None,
}
}
pub fn apply_cookie_header(&mut self) -> Result<(), String> {
if let Some(ref cookie) = self.cookie_header {
let mut headers = reqwest::header::HeaderMap::new();
headers.insert(
reqwest::header::COOKIE,
reqwest::header::HeaderValue::from_str(cookie)
.map_err(|e| format!("Invalid cookie header value: {e}"))?,
);
self.client = self
.tls
.configure_blocking_builder(
reqwest::blocking::Client::builder().default_headers(headers),
)
.build()
.map_err(|e| format!("Failed to rebuild HTTP client with cookie header: {e}"))?;
}
Ok(())
}
pub fn apply_cookie_header_from_env(&mut self) -> Result<(), String> {
if let Ok(cookie) = std::env::var("TORC_COOKIE_HEADER") {
self.cookie_header = Some(cookie);
if let Err(e) = self.apply_cookie_header() {
self.cookie_header = None;
return Err(e);
}
}
Ok(())
}
pub fn apply_auth(
&self,
mut req_builder: reqwest::blocking::RequestBuilder,
) -> reqwest::blocking::RequestBuilder {
if let Some((ref username, ref password)) = self.basic_auth {
req_builder = req_builder.basic_auth(username, password.clone());
}
if let Some(ref token) = self.bearer_access_token {
req_builder = req_builder.bearer_auth(token);
} else if let Some(ref token) = self.oauth_access_token {
req_builder = req_builder.bearer_auth(token);
}
if let Some(ref api_key) = self.api_key {
let value = if let Some(ref prefix) = api_key.prefix {
format!("{prefix} {}", api_key.key)
} else {
api_key.key.clone()
};
req_builder = req_builder.header("X-API-Key", value);
}
req_builder
}
}
impl Default for Configuration {
fn default() -> Self {
Configuration {
base_path: "http://localhost/torc-service/v1".to_owned(),
user_agent: Some("OpenAPI-Generator/v0.7.0/rust".to_owned()),
client: reqwest::blocking::Client::new(),
basic_auth: None,
oauth_access_token: None,
bearer_access_token: None,
api_key: None,
tls: TlsConfig::default(),
cookie_header: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tls_config_default() {
let tls = TlsConfig::default();
assert!(tls.ca_cert_path.is_none());
assert!(!tls.insecure);
}
#[test]
fn test_tls_config_insecure_builds_client() {
let tls = TlsConfig {
ca_cert_path: None,
insecure: true,
};
let client = tls.build_blocking_client();
assert!(client.is_ok());
}
#[test]
fn test_tls_config_nonexistent_cert_builds_client() {
let tls = TlsConfig {
ca_cert_path: Some(PathBuf::from("/nonexistent/ca.pem")),
insecure: false,
};
let client = tls.build_blocking_client();
assert!(client.is_ok());
}
#[test]
fn test_configuration_with_tls() {
let tls = TlsConfig {
ca_cert_path: None,
insecure: true,
};
let config = Configuration::with_tls(tls);
assert!(config.tls.insecure);
}
#[test]
fn test_tls_config_async_client() {
let tls = TlsConfig {
ca_cert_path: None,
insecure: true,
};
let client = tls.build_async_client();
assert!(client.is_ok());
}
#[test]
fn test_apply_cookie_header_valid() {
let mut config = Configuration {
cookie_header: Some("session=abc123".to_string()),
..Default::default()
};
assert!(config.apply_cookie_header().is_ok());
}
#[test]
fn test_apply_cookie_header_invalid() {
let mut config = Configuration {
cookie_header: Some("session=abc\x00123".to_string()),
..Default::default()
};
assert!(config.apply_cookie_header().is_err());
}
#[test]
fn test_apply_cookie_header_none() {
let mut config = Configuration::default();
assert!(config.apply_cookie_header().is_ok());
}
#[test]
fn test_apply_cookie_header_from_env_unset() {
unsafe { std::env::remove_var("TORC_COOKIE_HEADER") };
let mut config = Configuration::default();
assert!(config.apply_cookie_header_from_env().is_ok());
assert!(config.cookie_header.is_none());
}
#[test]
fn test_debug_redacts_sensitive_fields() {
let config = Configuration {
cookie_header: Some("session=secret".to_string()),
bearer_access_token: Some("my-token".to_string()),
..Default::default()
};
let debug_output = format!("{:?}", config);
assert!(!debug_output.contains("secret"));
assert!(!debug_output.contains("my-token"));
assert!(debug_output.contains("[REDACTED]"));
}
}