diff --git a/bin/cli/src/command/key.rs b/bin/cli/src/command/key.rs index 00fb02cfd..25d42694e 100644 --- a/bin/cli/src/command/key.rs +++ b/bin/cli/src/command/key.rs @@ -1,25 +1,63 @@ use anyhow::Context; use colored::Colorize; -use komodo_client::entities::config::cli::args::key::KeyCommand; +use komodo_client::entities::config::cli::args::key::{ + KeyCommand, KeyOutputFormat, KeyPair, +}; pub async fn handle(command: &KeyCommand) -> anyhow::Result<()> { match command { - KeyCommand::Generate => { + KeyCommand::Generate { format } => { let keys = noise::Base64KeyPair::generate() .context("Failed to generate key pair")?; - println!("\nPublic Key: {}", keys.public_key.green().bold()); - println!( - "Private Key: {}{}", - "base64:".red().bold(), - keys.private_key.red().bold() - ); + match format { + KeyOutputFormat::Standard => { + println!( + "\nPublic Key: {}", + keys.public_key.green().bold() + ); + // Prefixed with 'base64:' so Core / Periphery know to parse + // private key as base64. + println!( + "Private Key: {}{}", + "base64:".red().bold(), + keys.private_key.red().bold() + ); + } + KeyOutputFormat::Json => { + print_json(&keys.private_key, &keys.public_key)? + } + } + Ok(()) } - KeyCommand::Compute { private_key } => { + KeyCommand::Compute { + private_key, + format, + } => { let public_key = noise::compute_public_key(private_key) .context("Failed to compute public key")?; - println!("\nPublic Key: {}", public_key.green().bold()); + match format { + KeyOutputFormat::Standard => { + println!("\nPublic Key: {}", public_key.green().bold()); + } + KeyOutputFormat::Json => { + print_json(private_key, &public_key)? + } + } Ok(()) } } } + +fn print_json( + private_key: &str, + public_key: &str, +) -> anyhow::Result<()> { + let json = serde_json::to_string_pretty(&KeyPair { + private_key, + public_key, + }) + .context("Failed to serialize JSON")?; + println!("{json}"); + Ok(()) +} diff --git a/client/core/rs/src/entities/config/cli/args/key.rs b/client/core/rs/src/entities/config/cli/args/key.rs index c09d90882..40dfa6d44 100644 --- a/client/core/rs/src/entities/config/cli/args/key.rs +++ b/client/core/rs/src/entities/config/cli/args/key.rs @@ -1,10 +1,16 @@ +use serde::Serialize; + #[derive(Debug, Clone, clap::Subcommand)] pub enum KeyCommand { /// Generate a new public / private key pair /// for use with Core - Periphery authentication. /// (aliases: `gen`, `g`) #[clap(alias = "gen", alias = "g")] - Generate, + Generate { + /// Specify the format of the output. + #[arg(long, short = 'f', default_value_t = KeyOutputFormat::Standard)] + format: KeyOutputFormat, + }, /// Compute the public key for a given private key. /// (aliases: `comp`, `c`) @@ -12,5 +18,28 @@ pub enum KeyCommand { Compute { /// Pass the private key private_key: String, + /// Specify the format of the output. + #[arg(long, short = 'f', default_value_t = KeyOutputFormat::Standard)] + format: KeyOutputFormat, }, } + +#[derive( + Debug, Clone, Copy, Default, strum::Display, clap::ValueEnum, +)] +#[strum(serialize_all = "lowercase")] +pub enum KeyOutputFormat { + /// Readable output format. Default. (alias: `t`) + #[default] + #[clap(alias = "s")] + Standard, + /// Json output format. (alias: `j`) + #[clap(alias = "j")] + Json, +} + +#[derive(Serialize)] +pub struct KeyPair<'a> { + pub private_key: &'a str, + pub public_key: &'a str, +}