use super::build_entity_attrs::build_entity_attrs;
use super::built_entities::BuiltEntities;
use super::schema::MappingSchema;
use super::{BuildEntityError, BuildEntityErrorKind, build_cedar_entity};
use crate::common::policy_store::TrustedIssuer;
use cedar_policy::Entity;
use serde_json::{Value, json};
use smol_str::ToSmolStr;
use std::collections::{HashMap, HashSet};
use url::Origin;
pub(super) fn build_iss_entity(
iss_type_name: &str,
id: &str,
iss: &TrustedIssuer,
schema: Option<&MappingSchema>,
) -> Result<(Origin, Entity), BuildEntityError> {
let origin = iss.get_oidc_endpoint().origin();
let attrs_shape = schema
.as_ref()
.map(|s| {
s.get_entity_shape(iss_type_name)
.ok_or(BuildEntityErrorKind::EntityNotInSchema.while_building(iss_type_name))
})
.transpose()?;
let attrs = build_entity_attrs(
&iss.entity_attr_srcs(),
&BuiltEntities::default(),
attrs_shape,
)
.map_err(|e| BuildEntityErrorKind::from(e).while_building(iss_type_name))?;
let entity = build_cedar_entity(iss_type_name, id, attrs, HashSet::new())?;
Ok((origin, entity))
}
impl TrustedIssuer {
fn entity_attr_srcs(&self) -> HashMap<String, Value> {
let oidc_endpoint = &self.get_oidc_endpoint();
HashMap::from([(
"issuer_entity_id".into(),
json!({
"host": oidc_endpoint.host().map(|h| h.to_smolstr()),
"path": "/",
"protocol": oidc_endpoint.scheme(),
}),
)])
}
}
#[cfg(test)]
mod test {
use std::collections::HashMap;
use serde_json::json;
use url::Url;
use super::super::build_iss_entity::build_iss_entity;
use super::super::test::*;
use crate::common::policy_store::TrustedIssuer;
use crate::entity_builder::schema::MappingSchema;
fn test_trusted_issuer() -> TrustedIssuer {
TrustedIssuer::new(
"some_iss".to_string(),
"some_desc".to_string(),
Url::parse("https://test.jans.org").unwrap(),
HashMap::new(),
)
}
#[test]
fn can_build_trusted_issuer_entity_with_schema() {
let iss = test_trusted_issuer();
let schema: MappingSchema = (&*CEDARLING_VALIDATOR_SCHEMA)
.try_into()
.expect("should initialize mapping schema");
let (origin, iss_entity) =
build_iss_entity("Jans::TrustedIssuer", "some_iss", &iss, Some(&schema))
.expect("should build TrustedIssuer entity");
assert_eq!(origin.ascii_serialization(), "https://test.jans.org");
assert_entity_eq(
&iss_entity,
&json!({
"uid": {"type": "Jans::TrustedIssuer", "id": "some_iss"},
"attrs": {
"issuer_entity_id": {
"protocol": "https",
"host": "test.jans.org",
"path": "/",
}
},
"parents": [],
}),
Some(&CEDARLING_API_SCHEMA),
);
}
#[test]
fn can_build_trusted_issuer_entity_without_schema() {
let iss = test_trusted_issuer();
let (origin, iss_entity) = build_iss_entity("TrustedIssuer", "some_iss", &iss, None)
.expect("should build TrustedIssuer entity");
assert_eq!(origin.ascii_serialization(), "https://test.jans.org");
assert_entity_eq(
&iss_entity,
&json!({
"uid": {"type": "TrustedIssuer", "id": "some_iss"},
"attrs": {
"issuer_entity_id": {
"protocol": "https",
"host": "test.jans.org",
"path": "/",
},
},
"parents": [],
}),
None,
);
}
}