diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/access/mod.rs | 10 | ||||
| -rw-r--r-- | src/api/access.rs | 14 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/access/mod.rs b/src/access/mod.rs index ad50c72..cc6b7a2 100644 --- a/src/access/mod.rs +++ b/src/access/mod.rs @@ -197,8 +197,16 @@ impl Caps { self.limit.is_some() } + /// Whether they give nothing: none at all, or none that a token's limit meets + /// somewhere (`Capability::meet`). pub(crate) fn is_empty(&self) -> bool { - self.caps.is_empty() || self.limit.as_ref().is_some_and(Vec::is_empty) + match &self.limit { + None => self.caps.is_empty(), + Some(limit) => !self + .caps + .iter() + .any(|cap| limit.iter().any(|outer| cap.meet(outer).is_some())), + } } } diff --git a/src/api/access.rs b/src/api/access.rs index 6977a0a..ddcaad0 100644 --- a/src/api/access.rs +++ b/src/api/access.rs @@ -419,10 +419,22 @@ mod tests { by: String::new(), since: 0, }]; - let handed = Access::Caps(operator.clone().within(members)); + let handed = Access::Caps(operator.clone().within(members.clone())); let need = |method: &Method, at: &str| needed(method, at, "n1"); assert!(allowed(need(&Method::GET, "/admin/stats"), &handed)); assert!(allowed(need(&Method::GET, "/peers"), &handed)); + // A limit where the user has nothing: nothing to look with. + let elsewhere = Caps::new(vec![Capability { + path: path("data/eu"), + rights: ["read".to_owned()].into(), + by: String::new(), + since: 0, + }]) + .within(members.clone()); + assert!(!allowed( + need(&Method::GET, "/admin/stats"), + &Access::Caps(elsewhere) + )); for (method, at) in [ (Method::POST, "/auth/refresh"), (Method::DELETE, "/auth/session"), |
