cli: `rad self` improvements
* Add `--home` flag
* Organize the information better
Now looks like this:
DID did🔑z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
└╴Node ID (NID) z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
SSH running (823)
├╴Key (hash) SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA
└╴Key (full) ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
Home [..]
├╴Storage [..]/storage
├╴Keys [..]/keys
└╴Node [..]/node
This commit is contained in:
parent
613e3e5269
commit
0f3212a1b2
|
|
@ -7,7 +7,7 @@ $ rad auth
|
||||||
Initializing your radicle 👾 identity
|
Initializing your radicle 👾 identity
|
||||||
|
|
||||||
✓ Creating your Ed25519 keypair...
|
✓ Creating your Ed25519 keypair...
|
||||||
✓ Your Radicle ID is did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi. This identifies your device.
|
✓ Your Radicle DID is did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi. This identifies your device.
|
||||||
|
|
||||||
To create a radicle project, run `rad init` from a git repository.
|
To create a radicle project, run `rad init` from a git repository.
|
||||||
```
|
```
|
||||||
|
|
@ -15,12 +15,6 @@ To create a radicle project, run `rad init` from a git repository.
|
||||||
You can get the above information at all times using the `self` command:
|
You can get the above information at all times using the `self` command:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ rad self
|
$ rad self --did
|
||||||
DID did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
Node ID (NID) z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
|
||||||
Key (hash) SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA
|
|
||||||
Key (full) ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
|
|
||||||
Storage (git) [..]/storage
|
|
||||||
Storage (keys) [..]/keys
|
|
||||||
Node (socket) [..]/node/control.sock
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,15 @@ device and node.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ rad self
|
$ rad self
|
||||||
DID did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
DID did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
Node ID (NID) z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
└╴Node ID (NID) z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
Key (hash) SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA
|
SSH not running
|
||||||
Key (full) ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
|
├╴Key (hash) SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA
|
||||||
Storage (git) [..]
|
└╴Key (full) ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
|
||||||
Storage (keys) [..]
|
Home [..]/home/alice/.radicle
|
||||||
Node (socket) [..]
|
├╴Storage [..]/home/alice/.radicle/storage
|
||||||
|
├╴Keys [..]/home/alice/.radicle/keys
|
||||||
|
└╴Node [..]/home/alice/.radicle/node
|
||||||
```
|
```
|
||||||
|
|
||||||
If you need to display only your DID, Node ID, or SSH Public Key, you can use
|
If you need to display only your DID, Node ID, or SSH Public Key, you can use
|
||||||
|
|
@ -29,3 +31,8 @@ z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
$ rad self --ssh-key
|
$ rad self --ssh-key
|
||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ rad self --home
|
||||||
|
[..]/home/alice/.radicle
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ pub fn init(options: Options) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
term::success!(
|
term::success!(
|
||||||
"Your Radicle ID is {}. This identifies your device.",
|
"Your Radicle DID is {}. This identifies your device.",
|
||||||
term::format::highlight(profile.did())
|
term::format::highlight(profile.did())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ Options
|
||||||
|
|
||||||
--nid Show your Node ID (NID)
|
--nid Show your Node ID (NID)
|
||||||
--did Show your DID
|
--did Show your DID
|
||||||
|
--home Show your Radicle home
|
||||||
--ssh-key Show your public key in OpenSSH format
|
--ssh-key Show your public key in OpenSSH format
|
||||||
--ssh-fingerprint Show your public key fingerprint in OpenSSH format
|
--ssh-fingerprint Show your public key fingerprint in OpenSSH format
|
||||||
--help Show help
|
--help Show help
|
||||||
|
|
@ -30,6 +31,7 @@ Options
|
||||||
enum Show {
|
enum Show {
|
||||||
NodeId,
|
NodeId,
|
||||||
Did,
|
Did,
|
||||||
|
Home,
|
||||||
SshKey,
|
SshKey,
|
||||||
SshFingerprint,
|
SshFingerprint,
|
||||||
All,
|
All,
|
||||||
|
|
@ -55,6 +57,9 @@ impl Args for Options {
|
||||||
Long("did") if show.is_none() => {
|
Long("did") if show.is_none() => {
|
||||||
show = Some(Show::Did);
|
show = Some(Show::Did);
|
||||||
}
|
}
|
||||||
|
Long("home") if show.is_none() => {
|
||||||
|
show = Some(Show::Home);
|
||||||
|
}
|
||||||
Long("ssh-key") if show.is_none() => {
|
Long("ssh-key") if show.is_none() => {
|
||||||
show = Some(Show::SshKey);
|
show = Some(Show::SshKey);
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +92,9 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
Show::Did => {
|
Show::Did => {
|
||||||
term::print(profile.did());
|
term::print(profile.did());
|
||||||
}
|
}
|
||||||
|
Show::Home => {
|
||||||
|
term::print(profile.home().display());
|
||||||
|
}
|
||||||
Show::SshKey => {
|
Show::SshKey => {
|
||||||
term::print(ssh::fmt::key(profile.id()));
|
term::print(ssh::fmt::key(profile.id()));
|
||||||
}
|
}
|
||||||
|
|
@ -110,38 +118,56 @@ fn all(profile: &Profile) -> anyhow::Result<()> {
|
||||||
|
|
||||||
let node_id = profile.id();
|
let node_id = profile.id();
|
||||||
table.push([
|
table.push([
|
||||||
term::format::style("Node ID (NID)").to_string(),
|
term::format::style("└╴Node ID (NID)").to_string(),
|
||||||
term::format::tertiary(node_id).to_string(),
|
term::format::tertiary(node_id).to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
let ssh_agent = match ssh::agent::Agent::connect() {
|
||||||
|
Ok(c) => term::format::positive(format!(
|
||||||
|
"running ({})",
|
||||||
|
c.pid().map(|p| p.to_string()).unwrap_or(String::from("?"))
|
||||||
|
)),
|
||||||
|
Err(e) if e.is_not_running() => term::format::yellow(String::from("not running")),
|
||||||
|
Err(e) => term::format::negative(format!("error: {e}")),
|
||||||
|
};
|
||||||
|
table.push([
|
||||||
|
term::format::style("SSH").to_string(),
|
||||||
|
ssh_agent.to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
let ssh_short = ssh::fmt::fingerprint(node_id);
|
let ssh_short = ssh::fmt::fingerprint(node_id);
|
||||||
table.push([
|
table.push([
|
||||||
term::format::style("Key (hash)").to_string(),
|
term::format::style("├╴Key (hash)").to_string(),
|
||||||
term::format::tertiary(ssh_short).to_string(),
|
term::format::tertiary(ssh_short).to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let ssh_long = ssh::fmt::key(node_id);
|
let ssh_long = ssh::fmt::key(node_id);
|
||||||
table.push([
|
table.push([
|
||||||
term::format::style("Key (full)").to_string(),
|
term::format::style("└╴Key (full)").to_string(),
|
||||||
term::format::tertiary(ssh_long).to_string(),
|
term::format::tertiary(ssh_long).to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
let home = profile.home();
|
||||||
|
table.push([
|
||||||
|
term::format::style("Home").to_string(),
|
||||||
|
term::format::tertiary(home.display()).to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
let storage_path = profile.home.storage();
|
let storage_path = profile.home.storage();
|
||||||
table.push([
|
table.push([
|
||||||
term::format::style("Storage (git)").to_string(),
|
term::format::style("├╴Storage").to_string(),
|
||||||
term::format::tertiary(storage_path.display()).to_string(),
|
term::format::tertiary(storage_path.display()).to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let keys_path = profile.home.keys();
|
let keys_path = profile.home.keys();
|
||||||
table.push([
|
table.push([
|
||||||
term::format::style("Storage (keys)").to_string(),
|
term::format::style("├╴Keys").to_string(),
|
||||||
term::format::tertiary(keys_path.display()).to_string(),
|
term::format::tertiary(keys_path.display()).to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let socket_path = profile.socket();
|
|
||||||
table.push([
|
table.push([
|
||||||
term::format::style("Node (socket)").to_string(),
|
term::format::style("└╴Node").to_string(),
|
||||||
term::format::tertiary(socket_path.display()).to_string(),
|
term::format::tertiary(profile.home.node().display()).to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
table.print();
|
table.print();
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ impl Environment {
|
||||||
/// Create a new profile in this environment.
|
/// Create a new profile in this environment.
|
||||||
/// This should be used when a running node is not required.
|
/// This should be used when a running node is not required.
|
||||||
pub fn profile(&mut self, name: &str) -> Profile {
|
pub fn profile(&mut self, name: &str) -> Profile {
|
||||||
let home = Home::new(self.tmp().join("home").join(name)).unwrap();
|
let home = Home::new(self.tmp().join("home").join(name).join(".radicle")).unwrap();
|
||||||
let storage = Storage::open(home.storage()).unwrap();
|
let storage = Storage::open(home.storage()).unwrap();
|
||||||
let keystore = Keystore::new(&home.keys());
|
let keystore = Keystore::new(&home.keys());
|
||||||
let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32]));
|
let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32]));
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::io::{Read, Write};
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
|
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
@ -51,12 +52,18 @@ pub struct AgentClient<S> {
|
||||||
stream: S,
|
stream: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-4.1
|
|
||||||
impl<S> AgentClient<S> {
|
impl<S> AgentClient<S> {
|
||||||
/// Connect to an SSH agent via the provided stream (on Unix, usually a Unix-domain socket).
|
/// Connect to an SSH agent via the provided stream (on Unix, usually a Unix-domain socket).
|
||||||
pub fn connect(stream: S) -> Self {
|
pub fn connect(stream: S) -> Self {
|
||||||
AgentClient { stream }
|
AgentClient { stream }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the agent PID.
|
||||||
|
pub fn pid(&self) -> Option<u32> {
|
||||||
|
std::env::var("SSH_AGENT_PID")
|
||||||
|
.ok()
|
||||||
|
.and_then(|v| u32::from_str(&v).ok())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ClientStream: Sized + Send + Sync {
|
pub trait ClientStream: Sized + Send + Sync {
|
||||||
|
|
@ -76,7 +83,7 @@ pub trait ClientStream: Sized + Send + Sync {
|
||||||
Err(Error::Io(io_err)) if io_err.kind() == std::io::ErrorKind::NotFound => {
|
Err(Error::Io(io_err)) if io_err.kind() == std::io::ErrorKind::NotFound => {
|
||||||
Err(Error::BadAuthSock)
|
Err(Error::BadAuthSock)
|
||||||
}
|
}
|
||||||
err => err,
|
other => other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue