From f26be552c20e8db05ce9e0aad9d61ab6e4e2bf48 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Mon, 20 May 2024 17:10:43 +0100 Subject: [PATCH] cli: improve rad id allow list UX The previous implementation of using the `--allow` option in `rad id update` would be an absolute list, rather than additive. That is, if there were existing DIDs not passed in via `--allow` then they would be remove. Change this behaviour to check the existing value of the document's allow list, and add to it if `--allow` is specified. To enable the user to also remove a DID, the `--disallow` option is also added. The correct usage of these options is improved by checking the validity of the `--visibility` option being used, the current state of the repository's privacy, and the use of the `--allow` and `--disallow` options. Signed-off-by: Fintan Halpenny X-Clacks-Overhead: GNU Terry Pratchett --- radicle-cli/examples/rad-id-private.md | 101 +++++++++++++++++++++++++ radicle-cli/src/commands/id.rs | 90 +++++++++++++++++++--- radicle-cli/tests/commands.rs | 24 ++++++ 3 files changed, 206 insertions(+), 9 deletions(-) create mode 100644 radicle-cli/examples/rad-id-private.md diff --git a/radicle-cli/examples/rad-id-private.md b/radicle-cli/examples/rad-id-private.md new file mode 100644 index 00000000..b09a34a8 --- /dev/null +++ b/radicle-cli/examples/rad-id-private.md @@ -0,0 +1,101 @@ +When we are working with a private repository, we can modify the list of peers +we allow by using the `rad id` command with its `--allow` and `--disallow` +options. Both options can be specified multiple times in the same command line call: + +Here we will add Bob and Eve's DIDs to the `allow`list: + +``` +$ rad id update --title "Allow Bob & Eve" --description "" --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --allow did:key:z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z -q +... +$ rad inspect --identity +{ + "payload": { + "xyz.radicle.project": { + "defaultBranch": "master", + "description": "radicle heartwood protocol & stack", + "name": "heartwood" + } + }, + "delegates": [ + "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi" + ], + "threshold": 1, + "visibility": { + "type": "private", + "allow": [ + "did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk", + "did:key:z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z" + ] + } +} +``` + +To remove a peer's DID, we can use the `--disallow` option. Let's remove both of them again: + +``` +$ rad id update --title "Remove allow list" --description "" --disallow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --disallow did:key:z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z +... +$ rad inspect --identity +{ + "payload": { + "xyz.radicle.project": { + "defaultBranch": "master", + "description": "radicle heartwood protocol & stack", + "name": "heartwood" + } + }, + "delegates": [ + "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi" + ], + "threshold": 1, + "visibility": { + "type": "private" + } +} +``` + +Note that using both `--disallow` and `--allow` with the same DID will result in +an error: + +``` (fails) +$ rad id update --title "Remove allow list" --description "" --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --disallow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk +✗ Error: `--allow` and `--disallow` must not overlap: ["did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk"] +``` + +Allowing or disallowing the same peer twice will result in an error the second +call, since there is no update specified: + +``` +$ rad id update --title "Allow Bob" --description "" --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk -q +... +``` +``` (fails) +$ rad id update --title "Allow Bob" --description "" --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk -q +✗ Error: no update specified +✗ Hint: an update to the identity must be specified, run `rad id update -h` to see the available options +``` + +If we attempt to change the list while also changing the repository to `public`, +then the command will fail since there is no longer an allow list to work with: + +``` (fails) +$ rad id update --visibility public --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk +✗ Error: `--allow` and `--disallow` cannot be used with `--visibility public` +``` + +Let's change the repository to `public`: + +``` +$ rad id update --title "IPO" --description "" --visibility public -q +... +``` + +Now, if we attempt to change the `allow` list we also get an error with a +helpful hint: + +``` (fails) +$ rad id update --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk +✗ Error: `--allow` and `--disallow` should only be used for private repositories +✗ Hint: use `--visibility private` to make the repository private, or perhaps you meant to use `--delegate`/`--rescind` +``` + diff --git a/radicle-cli/src/commands/id.rs b/radicle-cli/src/commands/id.rs index 77729bfe..215b2f84 100644 --- a/radicle-cli/src/commands/id.rs +++ b/radicle-cli/src/commands/id.rs @@ -1,3 +1,5 @@ +use std::collections::BTreeSet; +use std::str::FromStr; use std::{ffi::OsString, io}; use anyhow::{anyhow, Context}; @@ -32,7 +34,8 @@ Usage rad id update [--title ] [--description ] [--delegate ] [--rescind ] [--threshold ] [--visibility ] - [--allow ] [--no-confirm] [--payload ...] + [--allow ] [--disallow ] + [--no-confirm] [--payload ...] [