use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TlsPolicy {
#[serde(default = "default_min_tls")]
pub min_tls_version: String,
#[serde(default)]
pub reject_cleartext: bool,
}
fn default_min_tls() -> String {
"1.2".into()
}
impl Default for TlsPolicy {
fn default() -> Self {
Self {
min_tls_version: default_min_tls(),
reject_cleartext: false,
}
}
}
impl TlsPolicy {
pub fn check_connection(&self, is_tls: bool, is_superuser: bool) -> crate::Result<()> {
if !is_tls && self.reject_cleartext && !is_superuser {
return Err(crate::Error::RejectedAuthz {
tenant_id: crate::types::TenantId::new(0),
resource: format!(
"cleartext connections rejected by policy (min_tls_version={})",
self.min_tls_version
),
});
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cleartext_rejected_for_non_superuser() {
let policy = TlsPolicy {
reject_cleartext: true,
min_tls_version: "1.3".into(),
};
assert!(policy.check_connection(false, false).is_err());
assert!(policy.check_connection(false, true).is_ok()); assert!(policy.check_connection(true, false).is_ok()); }
#[test]
fn default_allows_cleartext() {
let policy = TlsPolicy::default();
assert!(policy.check_connection(false, false).is_ok());
}
}