diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/access/strict.rs | 9 | ||||
| -rw-r--r-- | src/remake/kind.rs | 16 |
2 files changed, 25 insertions, 0 deletions
diff --git a/src/access/strict.rs b/src/access/strict.rs index f5051a8..0fa6577 100644 --- a/src/access/strict.rs +++ b/src/access/strict.rs @@ -140,6 +140,15 @@ pub(crate) fn read(text: &str) -> Result<Manifest, String> { if manifest.policy.get("values").and_then(JsonValue::as_str) != Some("signed") { return Err("its policy isn't strict (\"values\": \"signed\")".to_owned()); } + // A strict swarm without a registry would let every member do anything. + let users = crate::access::registry::users_dir(); + if !manifest + .keep + .iter() + .any(|kept| kept.path.len() == users.len() + 1 && kept.path.starts_with(&users)) + { + return Err("it keeps no user".to_owned()); + } Ok(manifest) } diff --git a/src/remake/kind.rs b/src/remake/kind.rs index a429828..f32f847 100644 --- a/src/remake/kind.rs +++ b/src/remake/kind.rs @@ -277,6 +277,22 @@ impl RemakeKind for Strict { target: &mut Transaction<'_>, ) -> Result<(), StoreError> { let manifest = Self::manifest(content)?; + // What holds the registry, the policy and the bans made anew, maps, with only + // what the manifest keeps in them: whatever a member made of them before (a + // scalar in place of the registry, say) is gone too. + for holder in [meta::USERS, meta::ACCESS, meta::BANNED] { + let at = meta::path(&[holder]); + match store::delete_path(target, &at, false) { + Ok(()) | Err(StoreError::NotFound) => {} + Err(error) => return Err(error), + } + store::write_path(target, &at, &JsonValue::Object(Default::default()))?; + } + for (path, value) in crate::access::strict::held(old_at_base) { + if meta::is_protocol(&path) && manifest.keeps(&path, &value) { + store::copy_path(old_at_base, target, &path)?; + } + } Self::keep_named(old_at_base, &manifest, target, meta::is_protocol)?; store::write_path( target, |
