use anyhow::Context;
use serde::{Deserialize, Serialize};
use std::path::Path;
pub(crate) fn default_bearer_prefix() -> String {
"Bearer".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
pub enum AuthConfig {
Bearer {
token_env: String,
#[serde(default)]
token_file: Option<String>,
#[serde(default = "default_bearer_prefix")]
prefix: String,
},
ApiKey {
header: String,
key_env: String,
#[serde(default)]
key_file: Option<String>,
},
Basic {
user_env: String,
#[serde(default)]
user_file: Option<String>,
password_env: String,
#[serde(default)]
password_file: Option<String>,
},
#[serde(rename = "oauth2")]
OAuth2 {
token_url: String,
client_id_env: String,
#[serde(default)]
client_id_file: Option<String>,
#[serde(default)]
client_secret_env: Option<String>,
#[serde(default)]
client_secret_file: Option<String>,
#[serde(default)]
client_private_key_env: Option<String>,
#[serde(default)]
client_private_key_file: Option<String>,
#[serde(default)]
refresh_token_env: Option<String>,
#[serde(default)]
refresh_token_file: Option<String>,
#[serde(default)]
scopes: Option<Vec<String>>,
#[serde(default)]
dpop: bool,
},
#[serde(rename = "google_service_account")]
GoogleServiceAccount {
#[serde(default)]
credentials_file: Option<String>,
#[serde(default)]
credentials_env: Option<String>,
#[serde(default)]
subject_env: Option<String>,
#[serde(default)]
subject_file: Option<String>,
scopes: Vec<String>,
},
}
pub fn read_secret(file_path: Option<&str>, env_var: &str) -> anyhow::Result<String> {
if let Some(p) = file_path
&& !p.is_empty()
{
let s = std::fs::read_to_string(Path::new(p))
.with_context(|| format!("read secret file {:?}", p))?;
return Ok(s.trim().to_string());
}
std::env::var(env_var).with_context(|| format!("env {} not set", env_var))
}