diff options
| author | tv <tv@krebsco.de> | 2026-11-07 22:35:21 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-07 22:35:21 +0100 |
| commit | 3d7230d952aa4a71a1aeb64fee9841d16b70ed91 (patch) | |
| tree | 82c36db267f03afe88b728d130e20955ca29a2da /src/access/policy.rs | |
| parent | f44fbf5b93269bb3573e8a2701e70ab0d7613153 (diff) | |
access: signatures required
"signatures": "required": a change counts only once a signature by its
committer vouches for it, and waits until then; every node then signs
every change it makes.
Auth plan M6.
Diffstat (limited to 'src/access/policy.rs')
| -rw-r--r-- | src/access/policy.rs | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/access/policy.rs b/src/access/policy.rs index 7ddef0e..f8ccfc2 100644 --- a/src/access/policy.rs +++ b/src/access/policy.rs @@ -4,7 +4,9 @@ //! by a user who may write protocol data, as any of it. //! //! `{"version": 1, "signatures": "optional"}`: rules enforced; a change is its claimed -//! committer's whether or not a signature proves it (`document::signatures`). A policy +//! committer's whether or not a signature proves it (`document::signatures`). +//! `"required"`: a change is applied once a signature by its committer vouches for it, +//! and waits until then; every node signs every change it makes. A policy //! this node doesn't know (another version, or a setting it lacks) stops it from taking //! writes through the API, and it receives without judging: it can't judge as the //! others do, so it writes nothing they might refuse, until it is upgraded. @@ -26,15 +28,21 @@ pub(crate) fn path() -> Vec<String> { pub(crate) enum Policy { /// None: changes aren't judged. Open, - /// Rules by path enforced. - Enforced, + /// Rules by path enforced; with signatures `required`, only on changes a signature + /// proves. + Enforced { required: bool }, /// One this node doesn't know, and why. Unknown(String), } impl Policy { pub(crate) fn enforced(&self) -> bool { - matches!(self, Policy::Enforced) + matches!(self, Policy::Enforced { .. }) + } + + /// Whether changes need a signature (`signatures: "required"`). + pub(crate) fn required(&self) -> bool { + matches!(self, Policy::Enforced { required: true }) } } @@ -55,7 +63,8 @@ pub(crate) fn of(doc: &impl ReadDoc) -> Policy { )); } match value.get("signatures").and_then(JsonValue::as_str) { - None | Some("optional") => Policy::Enforced, + None | Some("optional") => Policy::Enforced { required: false }, + Some("required") => Policy::Enforced { required: true }, Some(other) => Policy::Unknown(format!("signatures {other:?}")), } } @@ -78,10 +87,15 @@ mod tests { #[test] fn what_the_policy_says() { assert_eq!(of(&Document::new()), Policy::Open); - assert_eq!(with(json!({"version": 1})), Policy::Enforced); + let optional = Policy::Enforced { required: false }; + assert_eq!(with(json!({"version": 1})), optional); assert_eq!( with(json!({"version": 1, "signatures": "optional"})), - Policy::Enforced + optional + ); + assert_eq!( + with(json!({"version": 1, "signatures": "required"})), + Policy::Enforced { required: true } ); assert!(matches!(with(json!({"version": 2})), Policy::Unknown(_))); assert!(matches!( |
