mod common;
use chrono::{Duration, Utc};
use typesec_core::PolicyResult;
use typesec_odrl::{OdrlEngine, constraint::ConstraintContext};
use common::{ODRL_PURPOSE, odrl_with_expiry};
#[tokio::test]
async fn odrl_time_constraint() {
let future_expiry = (Utc::now() + Duration::days(365))
.format("%Y-%m-%dT%H:%M:%SZ")
.to_string();
let yaml = odrl_with_expiry(&future_expiry);
let engine = OdrlEngine::from_yaml(&yaml).expect("parse odrl");
let now_ok = ConstraintContext::default().with_time(Utc::now() - Duration::days(1));
let result = engine.check_with_context("agent:reader", "read", "reports/q1", &now_ok);
assert_eq!(result, PolicyResult::Allow, "should allow before expiry");
let now_expired = ConstraintContext::default().with_time(Utc::now() + Duration::days(730)); let result_expired =
engine.check_with_context("agent:reader", "read", "reports/q1", &now_expired);
assert!(
!matches!(result_expired, PolicyResult::Allow),
"should not allow after expiry"
);
}
#[tokio::test]
async fn odrl_purpose_constraint() {
let engine = OdrlEngine::from_yaml(ODRL_PURPOSE).expect("parse odrl");
let ctx_ok = ConstraintContext::default().with_purpose("analytics");
let result_ok = engine.check_with_context("agent:analyst", "read", "reports/q1", &ctx_ok);
assert_eq!(
result_ok,
PolicyResult::Allow,
"correct purpose should allow"
);
let ctx_bad = ConstraintContext::default().with_purpose("billing");
let result_bad = engine.check_with_context("agent:analyst", "read", "reports/q1", &ctx_bad);
assert!(
!matches!(result_bad, PolicyResult::Allow),
"wrong purpose must not allow"
);
}