pub struct NotPolicy<D: PolicyDomain> { /* private fields */ }Expand description
Inverts the decision of an inner policy.
Implementations§
Source§impl<D: PolicyDomain> NotPolicy<D>
impl<D: PolicyDomain> NotPolicy<D>
Sourcepub fn new(policy: impl Policy<D> + 'static) -> Self
pub fn new(policy: impl Policy<D> + 'static) -> Self
Creates a new NotPolicy that inverts the given policy’s decision.
Examples found in repository?
examples/deny_override.rs (line 275)
237async fn scoped_exclusion_demo() {
238 #[derive(Debug, Clone)]
239 struct Member {
240 is_owner: bool,
241 is_collaborator: bool,
242 muted: bool,
243 }
244 #[derive(Debug, Clone)]
245 struct Thread;
246
247 struct ThreadDomain;
248
249 impl PolicyDomain for ThreadDomain {
250 type Subject = Member;
251 type Action = Access;
252 type Resource = Thread;
253 type Context = ();
254 }
255
256 let owner_policy = PolicyBuilder::<ThreadDomain>::new("ThreadOwner")
257 .subjects(|member| member.is_owner)
258 .build();
259 let collaborator_policy: Arc<dyn Policy<ThreadDomain>> = Arc::from(
260 PolicyBuilder::<ThreadDomain>::new("Collaborator")
261 .subjects(|member| member.is_collaborator)
262 .build(),
263 );
264 // The block rule for the scoped case *grants when it matches* so that
265 // `NotPolicy` can invert it into a local gate. Compare with the
266 // checker-level rules above, where `Effect::Forbid` keeps natural
267 // polarity — this inversion is the price of scoping, which is why a
268 // global block should prefer `Effect::Forbid`.
269 let muted = PolicyBuilder::<ThreadDomain>::new("Muted")
270 .subjects(|member| member.muted)
271 .build();
272
273 let collaborator_unless_muted = AndPolicy::try_new(vec![
274 collaborator_policy,
275 Arc::new(NotPolicy::new(muted)) as Arc<dyn Policy<ThreadDomain>>,
276 ])
277 .expect("gate has the grant arm and the guard");
278
279 let mut checker = PermissionChecker::<ThreadDomain>::named("ThreadChecker");
280 checker.add_policy(owner_policy);
281 checker.add_policy(collaborator_unless_muted);
282
283 let muted_collaborator = Member {
284 is_owner: false,
285 is_collaborator: true,
286 muted: true,
287 };
288 let muted_owner = Member {
289 is_owner: true,
290 is_collaborator: false,
291 muted: true,
292 };
293
294 let session = EvaluationSession::empty();
295 let action = Access;
296 let context = ();
297
298 // The mute only gates the collaborator path...
299 checker
300 .bind(&session, &muted_collaborator, &action, &context)
301 .check(&Thread)
302 .await
303 .assert_denied();
304 // ...the owner path is untouched, which a global Effect::Forbid mute
305 // could not express.
306 checker
307 .bind(&session, &muted_owner, &action, &context)
308 .check(&Thread)
309 .await
310 .assert_granted_by("ThreadOwner");
311
312 println!("\nScoped exclusion: muted collaborator blocked, muted owner unaffected.");
313}Trait Implementations§
Source§impl<D: PolicyDomain> Policy<D> for NotPolicy<D>
impl<D: PolicyDomain> Policy<D> for NotPolicy<D>
Source§fn policy_type(&self) -> Cow<'static, str>
fn policy_type(&self) -> Cow<'static, str>
Policy name for debugging, trace trees, and telemetry fallbacks.
Source§fn effect(&self) -> Effect
fn effect(&self) -> Effect
The declared effect of this policy. Defaults to
Effect::Allow. Read moreSource§fn evaluate<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 EvalCtx<'life2, D>,
) -> Pin<Box<dyn Future<Output = PolicyEvalResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn evaluate<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 EvalCtx<'life2, D>,
) -> Pin<Box<dyn Future<Output = PolicyEvalResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Evaluates whether access should be granted.
Source§fn evaluate_batch<'item, 'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 BatchEvalCtx<'item, D>,
) -> Pin<Box<dyn Future<Output = Vec<PolicyEvalResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'item: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn evaluate_batch<'item, 'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 BatchEvalCtx<'item, D>,
) -> Pin<Box<dyn Future<Output = Vec<PolicyEvalResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'item: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Evaluates access for a batch of resources. Read more
Source§fn security_rule(&self) -> SecurityRuleMetadata
fn security_rule(&self) -> SecurityRuleMetadata
Metadata describing the security rule that backs this policy.
Auto Trait Implementations§
impl<D> !RefUnwindSafe for NotPolicy<D>
impl<D> !UnwindSafe for NotPolicy<D>
impl<D> Freeze for NotPolicy<D>
impl<D> Send for NotPolicy<D>
impl<D> Sync for NotPolicy<D>
impl<D> Unpin for NotPolicy<D>
impl<D> UnsafeUnpin for NotPolicy<D>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more