use crate::config::PolicyConfig;
#[derive(Clone, Default, Debug)]
pub struct Policy {
pub allow: Vec<String>,
pub deny: Vec<String>,
pub redact_keys: Vec<String>,
pub require_approval: Vec<String>,
pub approval_timeout_secs: u64,
pub webhook: Option<crate::config::WebhookConfig>,
}
impl Policy {
pub fn from_config(config: Option<PolicyConfig>) -> Self {
let Some(config) = config else {
return Self::default();
};
Self {
allow: config.allow,
deny: config.deny,
redact_keys: config.redact_keys,
require_approval: config.require_approval,
approval_timeout_secs: config.approval_timeout_secs.unwrap_or(300),
webhook: config.webhook,
}
}
pub fn allows(&self, id: impl AsRef<str>) -> bool {
let id_ref = id.as_ref();
if self
.deny
.iter()
.any(|pattern| wildcard_match(pattern, id_ref))
{
return false;
}
if self.allow.is_empty() {
return true;
}
self.allow
.iter()
.any(|pattern| wildcard_match(pattern, id_ref))
}
pub fn requires_approval(&self, id: impl AsRef<str>) -> bool {
let id_ref = id.as_ref();
self.require_approval
.iter()
.any(|pattern| wildcard_match(pattern, id_ref))
}
}
pub fn wildcard_match(pattern: &str, value: &str) -> bool {
if pattern == "*" {
return true;
}
if let Some(prefix) = pattern.strip_suffix('*') {
return value.starts_with(prefix);
}
pattern == value
}