use colored::Colorize;
use std::path::PathBuf;
use anyhow::anyhow;
use clap::{Parser, Subcommand};
use ed25519_dalek::SigningKey;
use provenance_rs::{sign, verify, Base64SigningKey};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
#[clap(alias = "c")]
Sign {
#[arg(short = 'd', long)]
document: PathBuf,
#[arg(short = 'k', long)]
signing_key: String,
#[arg(short = 'u', long)]
url: String,
#[arg(short = 'o', long)]
out: PathBuf,
},
#[clap(alias = "v")]
Verify {
path: PathBuf,
},
}
fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Sign {
document,
signing_key,
url,
out,
} => {
let doc = std::fs::read_to_string(document.clone())?;
let signing_key: SigningKey = Base64SigningKey(signing_key).try_into()?;
let output = sign(&doc, signing_key, &url);
std::fs::write(out.clone(), output)?;
eprintln!(
"[{}] added provenance to {document:?} {}",
"Success".green().bold(),
format!("(output written to {out:?})").dimmed()
);
}
Commands::Verify { path } => {
let signed_doc = std::fs::read_to_string(path.clone())?;
match verify(&signed_doc) {
Ok((signer_details, _remainder)) => {
eprintln!(
"[{}] '{}' has confirmed authorship of {path:?}",
"Success".green().bold(),
signer_details.verification_url,
);
}
Err(_) => {
return Err(anyhow!(
"[{}] couldn't verify {path:?}",
"Failure".red().bold()
))
}
}
}
};
Ok(())
}