Skip to content

Commit

Permalink
cli: allow saving collector credential to file; update help text (#617)
Browse files Browse the repository at this point in the history
* cli: allow saving collector credential to file; update help text

* Review feedback
  • Loading branch information
inahga authored Nov 27, 2023
1 parent 0a68e16 commit fbfa12d
Showing 1 changed file with 40 additions and 10 deletions.
50 changes: 40 additions & 10 deletions cli/src/collector_credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ use crate::{CliResult, DetermineAccountId, Error, Output};
use base64::{engine::general_purpose::STANDARD, Engine};
use clap::Subcommand;
use divviup_client::{Decode, DivviupClient, HpkeConfig, Uuid};
use std::{borrow::Cow, path::PathBuf};
use std::{borrow::Cow, env::current_dir, fs::File, io::Write, path::PathBuf};
use trillium_tokio::tokio::fs;

#[cfg(feature = "hpke")]
use hpke_dispatch::{Aead, Kdf, Kem};

#[derive(Subcommand, Debug)]
pub enum CollectorCredentialAction {
/// list hpke configs for the target account
/// list collector credentials for the target account
List,
/// list hpke configs for the target account
/// create a new collector credential using the public key from a dap-encoded hpke config file
Create {
#[arg(
long,
Expand All @@ -33,14 +33,14 @@ pub enum CollectorCredentialAction {
/// if `file` is provided and `name` is not, the filename will be used
name: Option<String>,
},
/// delete a hpke config by id
/// delete a collector credential by uuid
Delete { collector_credential_id: Uuid },

#[cfg(feature = "hpke")]
/// create a new hpke config and upload the public key to divviup
/// generate a new collector credential and upload the public key to divviup
///
/// the private key will be output to stdout
/// but not recorded anywhere else
/// the private key will be output to stdout or a local file, but will not be recorded anywhere
/// else
Generate {
#[arg(short, long, default_value = "x25519-sha256")]
/// key encapsulation mechanism
Expand All @@ -64,6 +64,15 @@ pub enum CollectorCredentialAction {
/// an optional display name to identify this hpke config
#[arg(long, short)]
name: Option<String>,

/// save the generated credential to a file in the current directory
///
/// if `name` is not provided, the filename will be `collector-credential-{id}.json`
/// where `id` is the id of the newly generated credential.
///
/// if `name` is provided, the filename will be `file.json`
#[arg(long, short, action)]
save: bool,
},
}

Expand Down Expand Up @@ -123,6 +132,7 @@ impl CollectorCredentialAction {
aead,
name,
id,
save,
} => {
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use serde_json::json;
Expand All @@ -148,16 +158,36 @@ impl CollectorCredentialAction {
.create_collector_credential(account_id, &hpke_config, Some(&name))
.await?;
let token = collector_credential.token.as_ref().cloned().unwrap();
output.display(collector_credential);
output.display(json!({
let credential = json!({
"id": config_id,
"public_key": URL_SAFE_NO_PAD.encode(public_key),
"private_key": URL_SAFE_NO_PAD.encode(private_key),
"kem": kem,
"kdf": kdf,
"aead": aead,
"token": token
}));
});

output.display(collector_credential);

// The collector credential is always written to file in JSON encoding, regardless
// of the output settings of this CLI. The credential file should be treated as
// opaque, so we don't grant user control over its encoding.
if save {
let path = current_dir()?.with_file_name(name).with_extension("json");
let mut file = File::create(path.clone())?;
file.write_all(&serde_json::to_vec_pretty(&credential).unwrap())?;
println!(
"\nSaved new collector credential to {}. Keep this file safe!",
path.display()
);
} else {
println!(
"\nNew collector credential generated. Copy and paste the following text \
into a file or your password manager:",
);
println!("{}", serde_json::to_string_pretty(&credential).unwrap());
}
}
}
Ok(())
Expand Down

0 comments on commit fbfa12d

Please sign in to comment.