Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cedar-policy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- `AsRef<str>` implementation for `PolicyId`.
- New API `template_links` for `Policy` to retrieve the linked values for a
template-linked policy. (resolving #489)

### Changed

Expand Down
16 changes: 16 additions & 0 deletions cedar-policy/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2612,6 +2612,22 @@ impl Policy {
}
}

/// Get the values this `Template` is linked to, expressed as a map from `SlotId` to `EntityUid`.
/// If this is a static policy, this will return `None`.
pub fn template_links(&self) -> Option<HashMap<SlotId, EntityUid>> {
if self.is_static() {
None
} else {
let wrapped_vals: HashMap<SlotId, EntityUid> = self
.ast
.env()
.into_iter()
.map(|(key, value)| (SlotId(*key), EntityUid(value.clone())))
.collect();
Some(wrapped_vals)
}
}

/// Get the `Effect` (`Permit` or `Forbid`) for this instance
pub fn effect(&self) -> Effect {
self.ast.effect()
Expand Down
35 changes: 35 additions & 0 deletions cedar-policy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,41 @@ mod policy_set_tests {
use ast::LinkingError;
use cool_asserts::assert_matches;

#[test]
fn template_link_lookup() {
let mut pset = PolicySet::new();
let p = Policy::parse(Some("p".into()), "permit(principal,action,resource);")
.expect("Failed to parse");
pset.add(p).expect("Failed to add");
let template = Template::parse(
Some("t".into()),
"permit(principal == ?principal, action, resource);",
)
.expect("Failed to parse");
pset.add_template(template).expect("Add failed");

let env: HashMap<SlotId, EntityUid> =
std::iter::once((SlotId::principal(), EntityUid::from_strs("Test", "test"))).collect();
pset.link(
PolicyId::from_str("t").unwrap(),
PolicyId::from_str("id").unwrap(),
env.clone(),
)
.expect("Failed to link");

let p0 = pset.policy(&PolicyId::from_str("p").unwrap()).unwrap();
let tp = pset.policy(&PolicyId::from_str("id").unwrap()).unwrap();

let env0 = p0.template_links();
assert_eq!(env0, None, "A normal policy should not have template links");
let env1 = tp.template_links();
assert_eq!(
env1,
Some(env),
"A template-linked policy's links should be stored properly"
);
}

#[test]
fn link_conflicts() {
let mut pset = PolicySet::new();
Expand Down