use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::bootstrap_config::BootstrapConfigLoadingError;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PolicyStoreConfig {
pub source: PolicyStoreSource,
#[serde(default)]
pub refresh_interval_secs: u64,
}
impl PolicyStoreConfig {
pub(crate) const MIN_REFRESH_INTERVAL_SECS: u64 = 5;
#[must_use]
pub fn refresh_enabled(&self) -> bool {
self.refresh_interval_secs > 0
&& matches!(
self.source,
PolicyStoreSource::CjarUrl(_)
| PolicyStoreSource::LockServer(_)
| PolicyStoreSource::Uri(_)
)
}
#[must_use]
pub(crate) fn effective_refresh_interval(&self) -> (u64, bool) {
let raw = self.refresh_interval_secs;
if raw == 0 || raw >= Self::MIN_REFRESH_INTERVAL_SECS {
(raw, false)
} else {
(Self::MIN_REFRESH_INTERVAL_SECS, true)
}
}
}
impl Default for PolicyStoreConfig {
fn default() -> Self {
Self {
source: PolicyStoreSource::Yaml(
"cedar_version: v4.0.0\npolicy_stores: {}\n".to_string(),
),
refresh_interval_secs: 0,
}
}
}
pub struct PolicyStoreConfigRaw {
pub source: String,
pub path: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PolicyStoreSource {
Json(String),
Yaml(String),
LockServer(String),
FileJson(PathBuf),
FileYaml(PathBuf),
CjarFile(PathBuf),
CjarUrl(String),
Directory(PathBuf),
Uri(String),
ArchiveBytes(Vec<u8>),
}
pub enum PolicyStoreSourceRaw {
Json(String),
Yaml(String),
LockServer(String),
FileJson(String),
FileYaml(String),
CjarFile(String),
CjarUrl(String),
Directory(String),
}
impl TryFrom<PolicyStoreConfigRaw> for PolicyStoreConfig {
type Error = BootstrapConfigLoadingError;
fn try_from(raw: PolicyStoreConfigRaw) -> Result<Self, Self::Error> {
let source = match raw.source.as_str() {
"json" => PolicyStoreSource::Json(raw.path.unwrap_or_default()),
"yaml" => PolicyStoreSource::Yaml(raw.path.unwrap_or_default()),
"lock_server" => PolicyStoreSource::LockServer(raw.path.unwrap_or_default()),
"file_json" => PolicyStoreSource::FileJson(raw.path.unwrap_or_default().into()),
"file_yaml" => PolicyStoreSource::FileYaml(raw.path.unwrap_or_default().into()),
"cjar_file" => PolicyStoreSource::CjarFile(
raw.path
.filter(|p| !p.is_empty())
.unwrap_or_else(|| "policy-store.cjar".to_string())
.into(),
),
"cjar_url" => {
let url = raw.path.filter(|p| !p.is_empty()).unwrap_or_default();
if url.is_empty() {
return Err(BootstrapConfigLoadingError::MissingCjarUrl);
}
PolicyStoreSource::CjarUrl(url)
},
"directory" => PolicyStoreSource::Directory(
raw.path
.filter(|p| !p.is_empty())
.unwrap_or_else(|| "policy-store".to_string())
.into(),
),
_ => PolicyStoreSource::FileYaml("policy-store.yaml".into()),
};
Ok(Self {
source,
refresh_interval_secs: 0,
})
}
}