From eaf25a3638568f580098bd56be76d80dc514e736 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 7 Nov 2026 22:35:09 +0100 Subject: access: genesis of swarms from before the registry Swarms started before the registry keep working without one; the genesis node's options for a registry apply only to new swarms. What tests and migration leave is noted in future-work. Auth plan M1, bootstrap and migration (2.5). --- src/access/registry.rs | 53 ++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 34 deletions(-) (limited to 'src/access/registry.rs') diff --git a/src/access/registry.rs b/src/access/registry.rs index 948e0de..094e62c 100644 --- a/src/access/registry.rs +++ b/src/access/registry.rs @@ -147,34 +147,23 @@ pub(crate) fn capability(by: &str, since: u64, path: &[String], rights: &[Right] pub(crate) type FirstUsers = Vec<(String, bool)>; /// The first users of a new swarm, from the genesis node's options: those of -/// `bootstrap_users`, each may do everything; unset, the users of its htpasswd file -/// (`htpasswd`) may read and write the swarm's data, and those of them, or of the proxy's -/// (`--user-header`), in `protocol_writers` everything. Refused if nobody could manage -/// the swarm: a registry nobody may change would lock everyone out for good. -pub(crate) fn first_users( - bootstrap_users: &[String], - htpasswd: &[String], - protocol_writers: &[String], -) -> anyhow::Result { - let mut users: BTreeMap = BTreeMap::new(); +/// `bootstrap_users` may do everything, and the other users of its htpasswd file +/// (`htpasswd`) read and write the swarm's data. None without `bootstrap_users`: then +/// the swarm has no registry, and its users are all alike, as before there were +/// registries (`access.md`). +pub(crate) fn first_users(bootstrap_users: &[String], htpasswd: &[String]) -> FirstUsers { if bootstrap_users.is_empty() { - for name in htpasswd.iter().filter(|name| valid_name(name)) { - users.insert(name.clone(), false); - } - for name in protocol_writers.iter().filter(|name| valid_name(name)) { - users.insert(name.clone(), true); - } - } else { - for name in bootstrap_users { - users.insert(name.clone(), true); - } + return Vec::new(); } - if !users.values().any(|admin| *admin) { - anyhow::bail!( - "genesis: nobody could manage the new swarm's users; name one with bootstrap-users, or put one of htpasswd's users in protocol-writers (docs/access.md)" - ); + let mut users: BTreeMap = htpasswd + .iter() + .filter(|name| valid_name(name)) + .map(|name| (name.clone(), false)) + .collect(); + for name in bootstrap_users { + users.insert(name.clone(), true); } - Ok(users.into_iter().collect()) + users.into_iter().collect() } /// The capabilities of a first user (`first_users`): the swarm's data, and for one who @@ -272,20 +261,16 @@ mod tests { fn the_first_users() { let names = |list: &[&str]| list.iter().map(|n| (*n).to_owned()).collect::>(); assert_eq!( - first_users(&[], &names(&["alice", "bob"]), &names(&["alice"])).unwrap(), + first_users(&names(&["alice"]), &names(&["alice", "bob"])), vec![("alice".to_owned(), true), ("bob".to_owned(), false)] ); - // A protocol writer the proxy names, not in htpasswd. + // One the proxy names, not in htpasswd. assert_eq!( - first_users(&[], &names(&["bob"]), &names(&["carol"])).unwrap(), + first_users(&names(&["carol"]), &names(&["bob"])), vec![("bob".to_owned(), false), ("carol".to_owned(), true)] ); - assert_eq!( - first_users(&names(&["root"]), &names(&["alice"]), &names(&["alice"])).unwrap(), - vec![("root".to_owned(), true)] - ); - assert!(first_users(&[], &names(&["alice"]), &[]).is_err()); - assert!(first_users(&[], &[], &[]).is_err()); + // Without bootstrap users, no registry. + assert!(first_users(&[], &names(&["alice"])).is_empty()); let admin = Caps::new( first_caps(true) .into_iter() -- cgit v1.3.1