aboutsummaryrefslogtreecommitdiffstats
path: root/src/document
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-09 15:37:16 +0000
committertv <tv@krebsco.de>2026-11-09 18:20:09 +0100
commit822e6a8268e2bc03463b2f0672fd6d6aad160432 (patch)
tree42228ecc05d87c19ddaf1f7f66e5cdd00740deb7 /src/document
parentd16da7283ceca16f223f3fb6b0429c7b2ae1aec0 (diff)
signatures: a listed signed path takes `*`, as everything else does
Review 4, appendix: whether a write is signed because `_continuum/access/signed` lists its path compared the listed paths by prefix (`signatures::related`), so a `*` there was a literal key, while api.md says the list holds paths as capabilities name them, which take `*` since 1259, and signed values already read the same list as patterns (`envelope::reaches_signed`). A listed `metrics/*/alerts` signed nothing. It compares by `access::agree` now: within or above the pattern, `*` for any one key.
Diffstat (limited to 'src/document')
-rw-r--r--src/document/signatures.rs19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/document/signatures.rs b/src/document/signatures.rs
index da2df03..e5c9e69 100644
--- a/src/document/signatures.rs
+++ b/src/document/signatures.rs
@@ -60,10 +60,11 @@ impl Sign {
}
}
-/// Whether a write at `path` touches what is at `signed`: within it, or above it
-/// (replacing or deleting what holds it).
+/// Whether a write at `path` touches what is at `signed`, a pattern as capabilities and
+/// signed values take them (`*` for any one key): within it, or above it (replacing or
+/// deleting what holds it).
fn related(signed: &[String], path: &[String]) -> bool {
- path.starts_with(signed) || signed.starts_with(path)
+ crate::access::agree(signed, path)
}
/// The paths `doc` lists as signed (`SIGNED_PATHS`); an entry that isn't a list of
@@ -587,6 +588,18 @@ mod tests {
.unwrap();
}
+ /// A listed signed path is a pattern: `*` takes any one key, within and above.
+ #[test]
+ fn listed_paths_take_a_star() {
+ let path = |text: &str| -> Vec<String> { text.split('/').map(str::to_owned).collect() };
+ let signed = path("metrics/*/alerts");
+ assert!(related(&signed, &path("metrics/eu/alerts/x")));
+ assert!(related(&signed, &path("metrics/eu")));
+ assert!(related(&signed, &path("metrics")));
+ assert!(!related(&signed, &path("metrics/eu/rates")));
+ assert!(!related(&signed, &path("other")));
+ }
+
/// The latest unsigned change of each of this node's actors is signed, below the
/// heads too (an earlier actor's, built on under a later one); another node's, and
/// those vouched for, left.