From 5477a3615f30a3d945fb90fbdcece5be00852471 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Thu, 16 Feb 2023 12:40:15 +0000 Subject: [PATCH] radicle-cli: use Did across CLI The CLI commands and output use PublicKey, ActorId, and NodeId for peer identifiers. Instead Did should be standardised for use in CLI arguments and outputs. Signed-off-by: Fintan Halpenny X-Clacks-Overhead: GNU Terry Pratchett --- radicle-cli/examples/rad-auth.md | 5 +-- radicle-cli/examples/rad-delegate.md | 4 +-- radicle-cli/examples/rad-id-rebase.md | 6 ++-- radicle-cli/examples/rad-id.md | 6 ++-- radicle-cli/examples/rad-issue.md | 6 ++-- radicle-cli/src/commands/assign.rs | 16 ++++----- radicle-cli/src/commands/auth.rs | 2 +- radicle-cli/src/commands/delegate.rs | 52 ++++++++++++--------------- radicle-cli/src/commands/id.rs | 27 ++++++-------- radicle-cli/src/commands/issue.rs | 22 ++++++------ radicle-cli/src/commands/self.rs | 5 ++- radicle-cli/src/commands/unassign.rs | 14 +++----- radicle-cli/src/terminal/args.rs | 2 +- radicle/src/cob/issue.rs | 25 ++++++------- radicle/src/profile.rs | 5 +++ 15 files changed, 94 insertions(+), 103 deletions(-) diff --git a/radicle-cli/examples/rad-auth.md b/radicle-cli/examples/rad-auth.md index 9593563e..43267738 100644 --- a/radicle-cli/examples/rad-auth.md +++ b/radicle-cli/examples/rad-auth.md @@ -7,7 +7,7 @@ $ rad auth Initializing your 🌱 profile and identity ok Creating your 🌱 Ed25519 keypair... -ok Profile z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi created. +ok Profile did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi created. Your radicle Node ID is z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi. This identifies your device. @@ -18,7 +18,8 @@ You can get the above information at all times using the `self` command: ``` $ rad self -ID z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +ID did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +Node ID z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi Key (hash) SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA Key (full) AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1 Storage (git) [..]/storage diff --git a/radicle-cli/examples/rad-delegate.md b/radicle-cli/examples/rad-delegate.md index 886b8ec1..5f07b847 100644 --- a/radicle-cli/examples/rad-delegate.md +++ b/radicle-cli/examples/rad-delegate.md @@ -14,7 +14,7 @@ We want to add a new maintainer to the project to help out with the work. ``` -$ rad delegate add z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji +$ rad delegate add did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji Added delegate 'did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG' ok Update successful! ``` @@ -33,7 +33,7 @@ And finally, we no longer want to be part of the project so we pass on the torch and remove ourselves from the delegate set. ``` -$ rad delegate remove z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji +$ rad delegate remove did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji Removed delegate 'did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi' ok Update successful! ``` diff --git a/radicle-cli/examples/rad-id-rebase.md b/radicle-cli/examples/rad-id-rebase.md index d7ea7d8e..69c8ef75 100644 --- a/radicle-cli/examples/rad-id-rebase.md +++ b/radicle-cli/examples/rad-id-rebase.md @@ -5,7 +5,7 @@ First off, we will create two proposals -- we can imagine two delegates creating proposals concurrently. ``` -$ rad id edit --title "Add Alice" --description "Add Alice as a delegate" --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm +$ rad id edit --title "Add Alice" --description "Add Alice as a delegate" --delegates did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm ok Identity proposal '57332790a2eabc0b2fd8c7ff48c3579d5812d405' created 🌱 title: Add Alice description: Add Alice as a delegate @@ -47,7 +47,7 @@ Quorum Reached ``` ``` -$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --no-confirm +$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --no-confirm ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' created 🌱 title: Add Bob description: Add Bob as a delegate @@ -294,7 +294,7 @@ Quorum Reached We can now update the proposal to have both keys in the delegates set: ``` -$ rad id update c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4 --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm +$ rad id update c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4 --delegates did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' updated 🌱 ok Revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/6' title: Add Bob diff --git a/radicle-cli/examples/rad-id.md b/radicle-cli/examples/rad-id.md index 036645f6..3c82dbc5 100644 --- a/radicle-cli/examples/rad-id.md +++ b/radicle-cli/examples/rad-id.md @@ -9,11 +9,11 @@ delegate` command. For cases where `threshold > 1`, it is necessary to gather a quorum of signatures to update the Radicle identity. To do this, we use the `rad id` command. -Let's add Bob as a delegate using their key -`z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn`. +Let's add Bob as a delegate using their DID +`did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn`. ``` -$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm +$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm ok Identity proposal '06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39' created 🌱 title: Add Bob description: Add Bob as a delegate diff --git a/radicle-cli/examples/rad-issue.md b/radicle-cli/examples/rad-issue.md index 39c14975..15986bae 100644 --- a/radicle-cli/examples/rad-issue.md +++ b/radicle-cli/examples/rad-issue.md @@ -22,20 +22,20 @@ others to work on. This is to ensure work is not duplicated. Let's assign ourselves to this one. ``` -$ rad assign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +$ rad assign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi ``` It will now show in the list of issues assigned to us. ``` $ rad issue list --assigned -2b4650e3c66d568132034de0d02871a2fbf9c5b5 "flux capacitor underpowered" z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +2b4650e3c66d568132034de0d02871a2fbf9c5b5 "flux capacitor underpowered" did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi ``` Note: this can always be undone with the `unassign` subcommand. ``` -$ rad unassign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +$ rad unassign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi ``` Great, now we have communicated to the world about our car's defect. diff --git a/radicle-cli/src/commands/assign.rs b/radicle-cli/src/commands/assign.rs index a0e00ef2..232a3904 100644 --- a/radicle-cli/src/commands/assign.rs +++ b/radicle-cli/src/commands/assign.rs @@ -2,6 +2,7 @@ use std::ffi::OsString; use std::str::FromStr; use anyhow::anyhow; +use radicle::prelude::Did; use crate::terminal as term; use crate::terminal::args; @@ -16,7 +17,7 @@ pub const HELP: args::Help = args::Help { usage: r#" Usage - rad assign + rad assign Options @@ -27,7 +28,7 @@ Options #[derive(Debug)] pub struct Options { pub id: issue::IssueId, - pub peer: cob::ActorId, + pub peer: Did, } impl args::Args for Options { @@ -36,7 +37,7 @@ impl args::Args for Options { let mut parser = lexopt::Parser::from_args(args); let mut id: Option = None; - let mut peer: Option = None; + let mut peer: Option = None; while let Some(arg) = parser.next()? { match arg { @@ -52,12 +53,7 @@ impl args::Args for Options { id = Some(val); } else if peer.is_none() { - let val = val.to_string_lossy(); - let Ok(val) = cob::ActorId::from_str(&val) else { - return Err(anyhow!("invalid peer ID '{}'", val)); - }; - - peer = Some(val); + peer = Some(term::args::did(val)?); } else { return Err(anyhow!(arg.unexpected())); } @@ -90,7 +86,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { cob::store::Error::NotFound(_, _) => anyhow!("issue not found '{}'", options.id), _ => err.into(), })?; - issue.assign(vec![options.peer], &signer)?; + issue.assign(vec![*options.peer], &signer)?; Ok(()) } diff --git a/radicle-cli/src/commands/auth.rs b/radicle-cli/src/commands/auth.rs index d9dc4d71..228079b3 100644 --- a/radicle-cli/src/commands/auth.rs +++ b/radicle-cli/src/commands/auth.rs @@ -87,7 +87,7 @@ pub fn init(options: Options) -> anyhow::Result<()> { term::success!( "Profile {} created.", - term::format::highlight(profile.id().to_string()) + term::format::highlight(profile.did().to_string()) ); term::blank(); diff --git a/radicle-cli/src/commands/delegate.rs b/radicle-cli/src/commands/delegate.rs index 0257ab45..fc91a0d3 100644 --- a/radicle-cli/src/commands/delegate.rs +++ b/radicle-cli/src/commands/delegate.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Context as _}; use radicle::identity::Id; -use radicle_crypto::PublicKey; +use radicle::prelude::Did; use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; @@ -23,7 +23,7 @@ pub const HELP: Help = Help { usage: r#" Usage - rad delegate (add|remove) [--to ] + rad delegate (add|remove) [--to ] rad delegate list [] The `add` and `remove` commands are limited to managing delegates @@ -47,8 +47,8 @@ pub enum OperationName { #[derive(Debug, Eq, PartialEq)] pub enum Operation { - Add { id: Option, key: PublicKey }, - Remove { id: Option, key: PublicKey }, + Add { id: Option, did: Did }, + Remove { id: Option, did: Did }, List { id: Option }, } @@ -64,7 +64,7 @@ impl Args for Options { let mut parser = lexopt::Parser::from_args(args); let mut id: Option = None; let mut op: Option = None; - let mut key: Option = None; + let mut did: Option = None; while let Some(arg) = parser.next()? { match arg { @@ -81,27 +81,21 @@ impl Args for Options { unknown => anyhow::bail!("unknown operation '{}'", unknown), }, - Value(val) if op.is_some() => { - let val = val.to_string_lossy(); - - match op { - Some(OperationName::Add) | Some(OperationName::Remove) => { - if let Ok(val) = PublicKey::from_str(&val) { - key = Some(val); - } else { - return Err(anyhow!("invalid Public Key '{}'", val)); - } - } - Some(OperationName::List) => { - if let Ok(val) = Id::from_str(&val) { - id = Some(val); - } else { - return Err(anyhow!("invalid Project ID '{}'", val)); - } - } - None => continue, + Value(val) if op.is_some() => match op { + Some(OperationName::Add) | Some(OperationName::Remove) => { + did = Some(term::args::did(&val)?); } - } + Some(OperationName::List) => { + // TODO: create args::project_id function + let val = val.to_string_lossy(); + if let Ok(val) = Id::from_str(&val) { + id = Some(val); + } else { + return Err(anyhow!("invalid Project ID '{}'", val)); + } + } + None => continue, + }, _ => return Err(anyhow!(arg.unexpected())), } } @@ -110,11 +104,11 @@ impl Args for Options { OperationName::List => Operation::List { id }, OperationName::Add => Operation::Add { id, - key: key.ok_or_else(|| anyhow!("a delegate key must be provided"))?, + did: did.ok_or_else(|| anyhow!("a delegate DID must be provided"))?, }, OperationName::Remove => Operation::Remove { id, - key: key.ok_or_else(|| anyhow!("a delegate key must be provided"))?, + did: did.ok_or_else(|| anyhow!("a delegate DID must be provided"))?, }, }; @@ -127,8 +121,8 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { let storage = &profile.storage; match options.op { - Operation::Add { id, key } => add::run(&profile, storage, get_id(id)?, key)?, - Operation::Remove { id, key } => remove::run(&profile, storage, get_id(id)?, &key)?, + Operation::Add { id, did } => add::run(&profile, storage, get_id(id)?, *did)?, + Operation::Remove { id, did } => remove::run(&profile, storage, get_id(id)?, &did)?, Operation::List { id } => list::run(&profile, storage, get_id(id)?)?, } diff --git a/radicle-cli/src/commands/id.rs b/radicle-cli/src/commands/id.rs index d3b7091c..eff0cf66 100644 --- a/radicle-cli/src/commands/id.rs +++ b/radicle-cli/src/commands/id.rs @@ -4,9 +4,9 @@ use anyhow::{anyhow, Context as _}; use radicle::cob::identity::{self, Proposal, ProposalId, Proposals, Revision, RevisionId}; use radicle::git::Oid; use radicle::identity::Identity; -use radicle::prelude::Doc; +use radicle::prelude::{Did, Doc}; use radicle::storage::ReadStorage as _; -use radicle_crypto::{PublicKey, Verified}; +use radicle_crypto::Verified; use crate::terminal::args::{Args, Error, Help}; use crate::terminal::{self as term, Interactive}; @@ -19,7 +19,7 @@ pub const HELP: Help = Help { Usage rad id (update|edit) [--title|-t] [--description|-d] - [--delegates ] [--threshold ] + [--delegates ] [--threshold ] [--no-confirm] rad id list rad id (show|rebase) [--rev ] @@ -61,7 +61,7 @@ pub enum Operation { Edit { title: Option, description: Option, - delegates: Vec, + delegates: Vec, threshold: Option, }, Update { @@ -69,7 +69,7 @@ pub enum Operation { rev: Option, title: Option, description: Option, - delegates: Vec, + delegates: Vec, threshold: Option, }, Rebase { @@ -121,7 +121,7 @@ impl Args for Options { let mut rev: Option = None; let mut title: Option = None; let mut description: Option = None; - let mut delegates: Vec = Vec::new(); + let mut delegates: Vec = Vec::new(); let mut threshold: Option = None; let mut interactive = Interactive::Yes; let mut show_revisions = false; @@ -161,11 +161,8 @@ impl Args for Options { ); } Long("delegates") => { - let val = String::from(parser.value()?.to_string_lossy()); - delegates.push( - PublicKey::from_str(&val) - .map_err(|_| anyhow!("invalid Public Key '{}'", val))?, - ) + let did = term::args::did(&parser.value()?)?; + delegates.push(did); } Long("threshold") => { threshold = Some(parser.value()?.to_string_lossy().parse()?); @@ -277,9 +274,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { let proposed = { let mut proposed = previous.doc.clone(); proposed.threshold = threshold.unwrap_or(proposed.threshold); - proposed - .delegates - .extend(delegates.into_iter().map(|k| k.into())); + proposed.delegates.extend(delegates); proposed }; @@ -320,9 +315,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { let proposed = { let mut proposed = revision.proposed.clone(); proposed.threshold = threshold.unwrap_or(revision.proposed.threshold); - proposed - .delegates - .extend(delegates.into_iter().map(|k| k.into())); + proposed.delegates.extend(delegates); proposed }; diff --git a/radicle-cli/src/commands/issue.rs b/radicle-cli/src/commands/issue.rs index f4870515..6d93bb7a 100644 --- a/radicle-cli/src/commands/issue.rs +++ b/radicle-cli/src/commands/issue.rs @@ -3,6 +3,7 @@ use std::ffi::OsString; use std::str::FromStr; use anyhow::{anyhow, Context as _}; +use radicle::prelude::Did; use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; @@ -22,7 +23,7 @@ Usage rad issue rad issue delete - rad issue list [--assigned ] + rad issue list [--assigned ] rad issue open [--title ] [--description <text>] rad issue react <id> [--emoji <char>] rad issue show <id> @@ -38,7 +39,7 @@ Options pub struct Metadata { title: String, labels: Vec<Tag>, - assignees: Vec<cob::ActorId>, + assignees: Vec<Did>, } #[derive(Default, Debug, PartialEq, Eq)] @@ -57,7 +58,7 @@ pub enum OperationName { pub enum Assigned { #[default] Me, - Peer(cob::ActorId), + Peer(Did), } #[derive(Debug, PartialEq, Eq)] @@ -135,10 +136,7 @@ impl Args for Options { } Long("assigned") | Short('a') if assigned.is_none() => { if let Ok(val) = parser.value() { - let val = val.to_string_lossy(); - let Ok(peer) = cob::ActorId::from_str(&val) else { - return Err(anyhow!("invalid peer ID '{}'", val)); - }; + let peer = term::args::did(&val)?; assigned = Some(Assigned::Peer(peer)); } else { assigned = Some(Assigned::Me); @@ -265,7 +263,11 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { &meta.title, description.trim(), meta.labels.as_slice(), - meta.assignees.as_slice(), + meta.assignees + .into_iter() + .map(cob::ActorId::from) + .collect::<Vec<_>>() + .as_slice(), &signer, )?; } @@ -273,7 +275,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { Operation::List { assigned } => { let assignee = match assigned { Some(Assigned::Me) => Some(*profile.id()), - Some(Assigned::Peer(id)) => Some(id), + Some(Assigned::Peer(id)) => Some(id.into()), None => None, }; @@ -282,7 +284,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { let (id, issue, _) = result?; let assigned: Vec<_> = issue.assigned().collect(); - if Some(true) == assignee.map(|a| !assigned.contains(&&a)) { + if Some(true) == assignee.map(|a| !assigned.contains(&Did::from(a))) { continue; } diff --git a/radicle-cli/src/commands/self.rs b/radicle-cli/src/commands/self.rs index 021895ac..4771de76 100644 --- a/radicle-cli/src/commands/self.rs +++ b/radicle-cli/src/commands/self.rs @@ -77,8 +77,11 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { fn all(profile: &Profile) -> anyhow::Result<()> { let mut table = term::Table::default(); + let did = profile.did(); + table.push(["ID", &term::format::tertiary(did)]); + let node_id = profile.id(); - table.push(["ID", &term::format::tertiary(node_id)]); + table.push(["Node ID", &term::format::tertiary(node_id)]); let ssh_short = ssh::fmt::fingerprint(node_id); table.push(["Key (hash)", &term::format::tertiary(ssh_short)]); diff --git a/radicle-cli/src/commands/unassign.rs b/radicle-cli/src/commands/unassign.rs index 5529ab04..49e109f9 100644 --- a/radicle-cli/src/commands/unassign.rs +++ b/radicle-cli/src/commands/unassign.rs @@ -2,6 +2,7 @@ use std::ffi::OsString; use std::str::FromStr; use anyhow::anyhow; +use radicle::prelude::Did; use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; @@ -27,7 +28,7 @@ Options #[derive(Debug)] pub struct Options { pub id: issue::IssueId, - pub peer: cob::ActorId, + pub peer: Did, } impl Args for Options { @@ -36,7 +37,7 @@ impl Args for Options { let mut parser = lexopt::Parser::from_args(args); let mut id: Option<issue::IssueId> = None; - let mut peer: Option<cob::ActorId> = None; + let mut peer: Option<Did> = None; while let Some(arg) = parser.next()? { match arg { @@ -52,12 +53,7 @@ impl Args for Options { id = Some(val); } else if peer.is_none() { - let val = val.to_string_lossy(); - let Ok(val) = cob::ActorId::from_str(&val) else { - return Err(anyhow!("invalid peer ID '{}'", val)); - }; - - peer = Some(val); + peer = Some(term::args::did(val)?); } else { return Err(anyhow!(arg.unexpected())); } @@ -90,7 +86,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { cob::store::Error::NotFound(_, _) => anyhow!("issue '{}' not found", options.id), _ => err.into(), })?; - issue.unassign(vec![options.peer], &signer)?; + issue.unassign(vec![*options.peer], &signer)?; Ok(()) } diff --git a/radicle-cli/src/terminal/args.rs b/radicle-cli/src/terminal/args.rs index c6b56ea4..7329aeb0 100644 --- a/radicle-cli/src/terminal/args.rs +++ b/radicle-cli/src/terminal/args.rs @@ -74,7 +74,7 @@ pub fn finish(unparsed: Vec<OsString>) -> anyhow::Result<()> { Ok(()) } -pub fn did(val: OsString) -> anyhow::Result<Did> { +pub fn did(val: &OsString) -> anyhow::Result<Did> { let val = val.to_string_lossy(); let Ok(peer) = Did::from_str(&val) else { if crypto::PublicKey::from_str(&val).is_ok() { diff --git a/radicle/src/cob/issue.rs b/radicle/src/cob/issue.rs index cd0741ae..902089da 100644 --- a/radicle/src/cob/issue.rs +++ b/radicle/src/cob/issue.rs @@ -16,6 +16,7 @@ use crate::cob::thread; use crate::cob::thread::{CommentId, Thread}; use crate::cob::{store, ActorId, ObjectId, OpId, TypeName}; use crate::crypto::{PublicKey, Signer}; +use crate::prelude::Did; use crate::storage::git as storage; /// Issue operation. @@ -152,8 +153,8 @@ impl store::FromHistory for Issue { } impl Issue { - pub fn assigned(&self) -> impl Iterator<Item = &ActorId> { - self.assignees.iter() + pub fn assigned(&self) -> impl Iterator<Item = Did> + '_ { + self.assignees.iter().map(Did::from) } pub fn title(&self) -> &str { @@ -516,21 +517,21 @@ mod test { let id = issue.id; let issue = issues.get(&id).unwrap().unwrap(); - let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>(); + let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>(); assert_eq!(1, assignees.len()); - assert!(assignees.contains(&assignee)); + assert!(assignees.contains(&Did::from(assignee))); let mut issue = issues.get_mut(&id).unwrap(); issue.assign([assignee_two], &signer).unwrap(); let id = issue.id; let issue = issues.get(&id).unwrap().unwrap(); - let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>(); + let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>(); assert_eq!(2, assignees.len()); - assert!(assignees.contains(&assignee)); - assert!(assignees.contains(&assignee_two)); + assert!(assignees.contains(&Did::from(assignee))); + assert!(assignees.contains(&Did::from(assignee_two))); } #[test] @@ -556,11 +557,11 @@ mod test { let id = issue.id; let issue = issues.get(&id).unwrap().unwrap(); - let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>(); + let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>(); assert_eq!(2, assignees.len()); - assert!(assignees.contains(&assignee)); - assert!(assignees.contains(&assignee_two)); + assert!(assignees.contains(&Did::from(assignee))); + assert!(assignees.contains(&Did::from(assignee_two))); } #[test] @@ -641,10 +642,10 @@ mod test { let id = issue.id; let issue = issues.get(&id).unwrap().unwrap(); - let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>(); + let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>(); assert_eq!(1, assignees.len()); - assert!(assignees.contains(&assignee_two)); + assert!(assignees.contains(&Did::from(assignee_two))); } #[test] diff --git a/radicle/src/profile.rs b/radicle/src/profile.rs index c5d8b4c3..2302fe1c 100644 --- a/radicle/src/profile.rs +++ b/radicle/src/profile.rs @@ -19,6 +19,7 @@ use crate::crypto::ssh::agent::Agent; use crate::crypto::ssh::{keystore, Keystore, Passphrase}; use crate::crypto::{PublicKey, Signer}; use crate::node; +use crate::prelude::Did; use crate::storage::git::transport; use crate::storage::git::Storage; @@ -103,6 +104,10 @@ impl Profile { &self.public_key } + pub fn did(&self) -> Did { + Did::from(self.public_key) + } + pub fn signer(&self) -> Result<Box<dyn Signer>, Error> { if let Some(passphrase) = env::read_passphrase() { let signer = keystore::MemorySigner::load(&self.keystore, passphrase)?;