use serde_json::Value;
use crate::error::{ChrononError, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EnqueueTrust {
Internal,
External,
}
pub trait ActorJsonPolicy: Send + Sync {
fn validate(&self, trust: EnqueueTrust, actor_json: &Value) -> Result<()>;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct RejectExternalSystemActor;
impl ActorJsonPolicy for RejectExternalSystemActor {
fn validate(&self, trust: EnqueueTrust, actor_json: &Value) -> Result<()> {
if trust == EnqueueTrust::External && actor_json.get("System").is_some() {
return Err(ChrononError::ParamError(
"external enqueue cannot use System-shaped actor_json".into(),
));
}
Ok(())
}
}
#[must_use]
pub fn default_http_enqueue_actor() -> Value {
serde_json::json!({"Service": {"name": "chronon_api"}})
}
#[must_use]
pub fn is_system_shaped_actor(actor_json: &Value) -> bool {
actor_json.get("System").is_some()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reject_external_system() {
let policy = RejectExternalSystemActor;
let system = serde_json::json!({"System": {"operation": "x"}});
assert!(policy
.validate(EnqueueTrust::External, &system)
.unwrap_err()
.to_string()
.contains("System"));
assert!(policy.validate(EnqueueTrust::Internal, &system).is_ok());
}
#[test]
fn allow_external_service() {
let policy = RejectExternalSystemActor;
let service = default_http_enqueue_actor();
assert!(!is_system_shaped_actor(&service));
assert!(policy.validate(EnqueueTrust::External, &service).is_ok());
}
}