use super::{
BuildEntityError, BuildEntityErrorKind, BuiltEntities, Entity, EntityBuilder, HashSet,
build_cedar_entity, build_cedar_uid, build_entity_attrs,
};
use crate::EntityData;
impl EntityBuilder {
pub(crate) fn build_resource_entity(
&self,
resource_data: &EntityData,
) -> Result<Entity, BuildEntityError> {
let resource_type_name = &resource_data.cedar_mapping.entity_type;
if resource_data.attributes.is_empty() {
let uid = build_cedar_uid(resource_type_name, &resource_data.cedar_mapping.id)?;
if let Some(resource_default_entity) = self.default_entities.get(&uid) {
return Ok(resource_default_entity.clone());
}
}
let attrs_shape = self
.schema
.as_ref()
.and_then(|s| s.get_entity_shape(resource_type_name));
let attrs = build_entity_attrs(
&resource_data.attributes,
&BuiltEntities::default(),
attrs_shape,
)
.map_err(|e| BuildEntityErrorKind::from(e).while_building(resource_type_name))?;
let resource = build_cedar_entity(
resource_type_name,
&resource_data.cedar_mapping.id,
attrs,
HashSet::new(),
)?;
Ok(resource)
}
}
#[cfg(test)]
mod test {
use super::super::test::*;
use super::super::*;
use crate::CedarEntityMapping;
use serde_json::json;
#[test]
fn can_build_entity() {
let builder = EntityBuilder::new(
TrustedIssuerIndex::new(&HashMap::new(), None),
Some(&CEDARLING_VALIDATOR_SCHEMA),
DefaultEntities::default(),
)
.expect("should init entity builder");
let resource_data = EntityData {
cedar_mapping: CedarEntityMapping {
entity_type: "Jans::HTTP_Request".to_string(),
id: "some_request".to_string(),
},
attributes: HashMap::from([
("header".to_string(), json!({"Accept": "test"})),
(
"url".to_string(),
json!({"host": "protected.host", "protocol": "http", "path": "/protected"}),
),
]),
};
let entity = builder
.build_resource_entity(&resource_data)
.expect("expected to build resource entity");
assert_entity_eq(
&entity,
&json!({
"uid": {"type": "Jans::HTTP_Request", "id": "some_request"},
"attrs": {
"url": {
"host": "protected.host",
"protocol": "http",
"path": "/protected",
},
"header": {
"Accept": "test",
}
},
"parents": [],
}),
Some(&CEDARLING_API_SCHEMA),
);
}
#[test]
fn can_build_entity_with_optional_attr() {
let builder = EntityBuilder::new(
TrustedIssuerIndex::new(&HashMap::new(), None),
Some(&CEDARLING_VALIDATOR_SCHEMA),
DefaultEntities::default(),
)
.expect("should init entity builder");
let resource_data = EntityData {
cedar_mapping: CedarEntityMapping {
entity_type: "Jans::HTTP_Request".to_string(),
id: "some_request".to_string(),
},
attributes: HashMap::from([
(
"url".to_string(),
json!({"host": "protected.host", "protocol": "http", "path": "/protected"}),
),
("header".to_string(), json!({})),
]),
};
let entity = builder
.build_resource_entity(&resource_data)
.expect("expected to build resource entity");
assert!(
entity.attr("url").is_some(),
"entity should have a `url` attribute"
);
assert!(
entity.attr("header").is_some(),
"entity should have a `header` attribute"
);
}
}