-
Notifications
You must be signed in to change notification settings - Fork 160
Add functions for inspecting TPE determining policies #2401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6e677ed
8197a5a
0276383
2da907c
a1b7f39
85ce1f9
a1b0e6a
feccd1a
ce2ef49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -59,8 +59,8 @@ impl ResidualPolicy { | |||||
| } | ||||||
|
|
||||||
| /// Get the [`PolicyID`] | ||||||
| pub fn get_policy_id(&self) -> PolicyID { | ||||||
| self.policy.id().clone() | ||||||
| pub fn get_policy_id(&self) -> &PolicyID { | ||||||
| self.policy.id() | ||||||
| } | ||||||
|
john-h-kastner-aws marked this conversation as resolved.
|
||||||
|
|
||||||
| /// All literal uids referenced by this residual | ||||||
|
|
@@ -87,16 +87,20 @@ impl From<ResidualPolicy> for Policy { | |||||
| pub struct Response<'a> { | ||||||
| decision: Option<Decision>, | ||||||
| residuals: HashMap<PolicyID, ResidualPolicy>, | ||||||
| // All of the [`Effect::Permit`] policies that were satisfied | ||||||
| satisfied_permits: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Permit`] policies that were not satisfied | ||||||
| // All of the [`Effect::Permit`] policies that were true | ||||||
| true_permits: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Permit`] policies that were false | ||||||
| false_permits: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Permit`] policies that errored | ||||||
| error_permits: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Permit`] policies that evaluated to a residual | ||||||
| residual_permits: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Forbid`] policies that were satisfied | ||||||
| satisfied_forbids: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Forbid`] policies that were not satisfied | ||||||
| // All of the [`Effect::Forbid`] policies that were true | ||||||
| true_forbids: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Forbid`] policies that were false | ||||||
| false_forbids: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Forbid`] policies that errored | ||||||
| error_forbids: HashSet<PolicyID>, | ||||||
| // All of the [`Effect::Forbid`] policies that evaluated to a residual | ||||||
| residual_forbids: HashSet<PolicyID>, | ||||||
| // request used for this partial evaluation | ||||||
|
|
@@ -117,11 +121,13 @@ impl<'a> Response<'a> { | |||||
| schema: &'a ValidatorSchema, | ||||||
| ) -> Self { | ||||||
| let mut residual_map = HashMap::new(); | ||||||
| let mut satisfied_permits = HashSet::new(); | ||||||
| let mut true_permits = HashSet::new(); | ||||||
| let mut false_permits = HashSet::new(); | ||||||
| let mut error_permits = HashSet::new(); | ||||||
| let mut residual_permits = HashSet::new(); | ||||||
| let mut satisfied_forbids = HashSet::new(); | ||||||
| let mut true_forbids = HashSet::new(); | ||||||
| let mut false_forbids = HashSet::new(); | ||||||
| let mut error_forbids = HashSet::new(); | ||||||
| let mut residual_forbids = HashSet::new(); | ||||||
| for rp in residuals { | ||||||
| let r = rp.get_residual(); | ||||||
|
|
@@ -130,28 +136,32 @@ impl<'a> Response<'a> { | |||||
| match rp.get_effect() { | ||||||
| Effect::Forbid => { | ||||||
| if r.is_true() { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: feels like this could be a good candidate to have an enum / match statement for in the future.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could write this as a match on the residual, but I don't think I see how it would make the code any nicer |
||||||
| satisfied_forbids.insert(id); | ||||||
| } else if r.is_false() || r.is_error() { | ||||||
| false_forbids.insert(id); | ||||||
| true_forbids.insert(id.clone()); | ||||||
| } else if r.is_false() { | ||||||
| false_forbids.insert(id.clone()); | ||||||
| } else if r.is_error() { | ||||||
| error_forbids.insert(id.clone()); | ||||||
| } else { | ||||||
| residual_forbids.insert(id); | ||||||
| residual_forbids.insert(id.clone()); | ||||||
| } | ||||||
| } | ||||||
| Effect::Permit => { | ||||||
| if r.is_true() { | ||||||
| satisfied_permits.insert(id); | ||||||
| } else if r.is_false() || r.is_error() { | ||||||
| false_permits.insert(id); | ||||||
| true_permits.insert(id.clone()); | ||||||
| } else if r.is_false() { | ||||||
| false_permits.insert(id.clone()); | ||||||
| } else if r.is_error() { | ||||||
| error_permits.insert(id.clone()); | ||||||
| } else { | ||||||
| residual_permits.insert(id); | ||||||
| residual_permits.insert(id.clone()); | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| let decision = match ( | ||||||
| !satisfied_forbids.is_empty(), | ||||||
| !satisfied_permits.is_empty(), | ||||||
| !true_forbids.is_empty(), | ||||||
| !true_permits.is_empty(), | ||||||
| !residual_permits.is_empty(), | ||||||
| !residual_forbids.is_empty(), | ||||||
| ) { | ||||||
|
|
@@ -170,11 +180,13 @@ impl<'a> Response<'a> { | |||||
| Self { | ||||||
| decision, | ||||||
| residuals: residual_map, | ||||||
| satisfied_permits, | ||||||
| true_permits, | ||||||
| false_permits, | ||||||
| error_permits, | ||||||
| residual_permits, | ||||||
| satisfied_forbids, | ||||||
| true_forbids, | ||||||
| false_forbids, | ||||||
| error_forbids, | ||||||
| residual_forbids, | ||||||
| request, | ||||||
| entities, | ||||||
|
|
@@ -188,7 +200,7 @@ impl<'a> Response<'a> { | |||||
| clippy::unwrap_used, | ||||||
| reason = "we know that the policy ids are in the residuals map" | ||||||
| )] | ||||||
| self.satisfied_permits | ||||||
| self.true_permits | ||||||
| .iter() | ||||||
| .map(|id| self.residuals.get(id).unwrap()) | ||||||
| } | ||||||
|
|
@@ -199,7 +211,7 @@ impl<'a> Response<'a> { | |||||
| clippy::unwrap_used, | ||||||
| reason = "we know that the policy ids are in the residuals map" | ||||||
| )] | ||||||
| self.satisfied_forbids | ||||||
| self.true_forbids | ||||||
| .iter() | ||||||
| .map(|id| self.residuals.get(id).unwrap()) | ||||||
| } | ||||||
|
|
@@ -215,6 +227,17 @@ impl<'a> Response<'a> { | |||||
| .map(|id| self.residuals.get(id).unwrap()) | ||||||
| } | ||||||
|
|
||||||
| /// Get trivially erroring permit residual policies | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
nit: not sure I understand the word trivially in this context, maybe just drop it? |
||||||
| pub fn error_permits(&self) -> impl Iterator<Item = &ResidualPolicy> { | ||||||
| #[expect( | ||||||
| clippy::unwrap_used, | ||||||
| reason = "we know that the policy ids are in the residuals map" | ||||||
| )] | ||||||
| self.error_permits | ||||||
| .iter() | ||||||
| .map(|id| self.residuals.get(id).unwrap()) | ||||||
| } | ||||||
|
|
||||||
| /// Get trivially false forbid residual policies | ||||||
| pub fn false_forbids(&self) -> impl Iterator<Item = &ResidualPolicy> { | ||||||
| #[expect( | ||||||
|
|
@@ -226,6 +249,17 @@ impl<'a> Response<'a> { | |||||
| .map(|id| self.residuals.get(id).unwrap()) | ||||||
| } | ||||||
|
|
||||||
| /// Get trivially erroring forbid residual policies | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| pub fn error_forbids(&self) -> impl Iterator<Item = &ResidualPolicy> { | ||||||
| #[expect( | ||||||
| clippy::unwrap_used, | ||||||
| reason = "we know that the policy ids are in the residuals map" | ||||||
| )] | ||||||
| self.error_forbids | ||||||
| .iter() | ||||||
| .map(|id| self.residuals.get(id).unwrap()) | ||||||
| } | ||||||
|
|
||||||
| /// Get non-trivial permit residual policies | ||||||
| pub fn residual_permits(&self) -> impl Iterator<Item = &ResidualPolicy> { | ||||||
| #[expect( | ||||||
|
|
@@ -258,6 +292,14 @@ impl<'a> Response<'a> { | |||||
| self.decision | ||||||
| } | ||||||
|
|
||||||
| /// Get the determining policies for the authorization decision | ||||||
| pub fn reason(&self) -> Option<impl Iterator<Item = &PolicyID>> { | ||||||
| match self.decision? { | ||||||
| Decision::Allow => Some(self.true_permits.iter()), | ||||||
| Decision::Deny => Some(self.true_forbids.iter()), | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// Perform reauthorization | ||||||
| pub fn reauthorize( | ||||||
| &self, | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.