aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/access/mod.rs10
-rw-r--r--src/api/access.rs14
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"),