From de12c862b3f4e69290c8e93b3b4520024ba458f6 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 7 Nov 2026 22:35:09 +0100 Subject: access: the users endpoints /admin/users: list, add (one or several), remove, disable, grant and revoke capabilities; each one change, refused if it would lock its writer out. Capabilities as the store's paths name them. Auth plan M1. --- src/api/store.rs | 66 +------------------------------------------------------- 1 file changed, 1 insertion(+), 65 deletions(-) (limited to 'src/api/store.rs') diff --git a/src/api/store.rs b/src/api/store.rs index e1f9b53..48fc2c6 100644 --- a/src/api/store.rs +++ b/src/api/store.rs @@ -18,7 +18,7 @@ use sha2::{Digest, Sha256}; use tokio::sync::broadcast; use tracing::{debug, error, instrument, warn}; -use super::access::{Access, Visible, prune, prune_shallow}; +use super::access::{Access, Before, Visible, prune, prune_shallow, registry_kept}; use super::auth::AuthenticatedUser; use super::{ApiError, store_status}; use crate::document::meta; @@ -468,70 +468,6 @@ fn parse_write_path( Ok(path) } -/// The registry as a write found it (`registry_kept`): whether it existed, and whether -/// the writing user could manage users (`registry::managers`). -#[derive(Clone, Copy)] -struct Before { - existed: bool, - managed: bool, -} - -impl Before { - fn of(doc: &impl crate::document::ReadDoc, user: &str) -> Self { - use crate::access::registry; - let existed = registry::exists(doc); - Self { - existed, - managed: existed - && registry::caps_of(doc, user) - .allows(crate::access::Right::Write, ®istry::users_dir()), - } - } -} - -/// `409` for a write to `path` by `user` that would lock that user out of managing -/// users: one that could and no longer may (deleting, disabling or narrowing its own -/// entry), and the write that makes the registry, if it doesn't make `user` one who may -/// (from then on only registered users are served). And for one that would remove -/// the registry, back to a swarm without one. Checked in the write's transaction, -/// after it: the write is dropped whole. Others are not kept from removing the last who -/// may manage users: no node could keep two such writes at once on two nodes from -/// leaving nobody once they merge; then the users in `--protocol-writers` may do -/// everything again (`access::authorize`). -fn registry_kept( - doc: &impl crate::document::ReadDoc, - path: &[String], - before: Before, - user: &str, -) -> Result<(), ApiError> { - use crate::access::registry; - if !store::paths_related(path, ®istry::users_dir()) { - return Ok(()); - } - let refuse = |why: &str| { - Err(ApiError( - StatusCode::CONFLICT, - Some(format!("{why} (docs/access.md)")), - )) - }; - if !registry::exists(doc) { - return if before.existed { - refuse("this would remove the user registry") - } else { - Ok(()) - }; - } - let manages = - registry::caps_of(doc, user).allows(crate::access::Right::Write, ®istry::users_dir()); - if !before.existed && !manages { - return refuse("the registry's first users must include you, with write on _continuum"); - } - if before.managed && !manages { - return refuse("this would keep you from managing users"); - } - Ok(()) -} - /// How a value is shown, as the request's `Accept` asks. #[derive(Clone, Copy, Debug)] enum Shown { -- cgit v1.3.1