diff options
author | Justus Winter <justus@pep-project.org> | 2018-01-09 17:00:30 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-01-11 14:50:58 +0100 |
commit | 6f1a94f2dd0c7cb7c5e264d4c620a48c1b72152c (patch) | |
tree | f2bb9b3563c05585725c6408cde33df9d7ab26d3 /tool | |
parent | a3e1899cb4f52c4b87b7165afe1923d2f023f09d (diff) |
store: Implement iteration over stores, bindings, and keys.
- Also add corresponding commands to the tool.
Diffstat (limited to 'tool')
-rw-r--r-- | tool/Cargo.toml | 1 | ||||
-rw-r--r-- | tool/src/main.rs | 82 | ||||
-rw-r--r-- | tool/src/usage.rs | 97 |
3 files changed, 180 insertions, 0 deletions
diff --git a/tool/Cargo.toml b/tool/Cargo.toml index 3becea63..f0118c1a 100644 --- a/tool/Cargo.toml +++ b/tool/Cargo.toml @@ -9,6 +9,7 @@ sequoia-core = { path = "../core" } sequoia-net = { path = "../net" } sequoia-store = { path = "../store" } clap = "2.27.1" +prettytable-rs = "0.6.7" [[bin]] name = "sq" diff --git a/tool/src/main.rs b/tool/src/main.rs index dd791252..0df05a36 100644 --- a/tool/src/main.rs +++ b/tool/src/main.rs @@ -1,8 +1,13 @@ /// A command-line frontend for Sequoia. extern crate clap; +#[macro_use] +extern crate prettytable; use clap::{Arg, App, SubCommand, AppSettings}; +use prettytable::Table; +use prettytable::cell::Cell; +use prettytable::row::Row; use std::fs::File; use std::io; use std::process::exit; @@ -113,6 +118,8 @@ fn real_main() -> Result<()> { .arg(Arg::with_name("name").value_name("NAME") .required(true) .help("Name of the store")) + .subcommand(SubCommand::with_name("list") + .about("Lists keys in the store")) .subcommand(SubCommand::with_name("add") .about("Add a key identified by fingerprint") .arg(Arg::with_name("label").value_name("LABEL") @@ -160,6 +167,18 @@ fn real_main() -> Result<()> { .arg(Arg::with_name("label").value_name("LABEL") .required(true) .help("Label to use")))) + .subcommand(SubCommand::with_name("list") + .about("Lists key stores and known keys") + .subcommand(SubCommand::with_name("stores") + .about("Lists key stores") + .arg(Arg::with_name("prefix").value_name("PREFIX") + .help("List only stores with the given domain prefix"))) + .subcommand(SubCommand::with_name("bindings") + .about("Lists all bindings in all key stores") + .arg(Arg::with_name("prefix").value_name("PREFIX") + .help("List only bindings from stores with the given domain prefix"))) + .subcommand(SubCommand::with_name("keys") + .about("Lists all keys in the common key pool"))) .get_matches(); let policy = match matches.value_of("policy") { @@ -271,6 +290,9 @@ fn real_main() -> Result<()> { .expect("Failed to open store"); match m.subcommand() { + ("list", Some(_)) => { + list_bindings(&store); + }, ("add", Some(m)) => { let fp = Fingerprint::from_hex(m.value_of("fingerprint").unwrap()) .expect("Malformed fingerprint"); @@ -333,6 +355,53 @@ fn real_main() -> Result<()> { }, } }, + ("list", Some(m)) => { + match m.subcommand() { + ("stores", Some(m)) => { + let mut table = Table::new(); + table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE); + table.set_titles(row!["domain", "name", "network policy", "# of entries"]); + + for item in Store::list(&ctx, m.value_of("prefix").unwrap_or("")) + .expect("Failed to iterate over stores") { + table.add_row(Row::new(vec![ + Cell::new(&item.domain), + Cell::new(&item.name), + Cell::new(&format!("{:?}", item.network_policy)), + Cell::new(&format!("{}", item.entries))]) + ); + } + + table.printstd(); + }, + ("bindings", Some(m)) => { + for item in Store::list(&ctx, m.value_of("prefix").unwrap_or("")) + .expect("Failed to iterate over stores") { + println!("Domain {:?} Name {:?}:", item.domain, item.name); + list_bindings(&item.store); + } + }, + ("keys", Some(_)) => { + let mut table = Table::new(); + table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE); + table.set_titles(row!["fingerprint", "# of bindings"]); + + for item in Store::list_keys(&ctx) + .expect("Failed to iterate over keys") { + table.add_row(Row::new(vec![ + Cell::new(&item.fingerprint.to_string()), + Cell::new(&format!("{}", item.bindings))]) + ); + } + + table.printstd(); + }, + _ => { + eprintln!("No list subcommand given."); + exit(1); + }, + } + }, _ => { eprintln!("No subcommand given."); exit(1); @@ -342,4 +411,17 @@ fn real_main() -> Result<()> { return Ok(()) } +fn list_bindings(store: &Store) { + let mut table = Table::new(); + table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE); + table.set_titles(row!["label", "fingerprint"]); + for item in store.iter().expect("Failed to iterate over bindings") { + table.add_row(Row::new(vec![ + Cell::new(&item.label), + Cell::new(&item.fingerprint.to_string())])); + } + table.printstd(); +} + + fn main() { real_main().expect("An error occured"); } diff --git a/tool/src/usage.rs b/tool/src/usage.rs index 07cdc099..213ac00b 100644 --- a/tool/src/usage.rs +++ b/tool/src/usage.rs @@ -22,6 +22,7 @@ //! enarmor Applies ASCII Armor to a file //! help Prints this message or the help of the given subcommand(s) //! keyserver Interacts with keyservers +//! list Lists key stores and known keys //! store Interacts with key stores //! ``` //! @@ -135,6 +136,70 @@ //! -i, --input <FILE> Sets the input file to use //! ``` //! +//! ## Subcommand list +//! +//! ```text +//! Lists key stores and known keys +//! +//! USAGE: +//! sq list [SUBCOMMAND] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! SUBCOMMANDS: +//! bindings Lists all bindings in all key stores +//! help Prints this message or the help of the given subcommand(s) +//! keys Lists all keys in the common key pool +//! stores Lists key stores +//! ``` +//! +//! ### Subcommand list bindings +//! +//! ```text +//! Lists all bindings in all key stores +//! +//! USAGE: +//! sq list bindings [PREFIX] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! ARGS: +//! <PREFIX> List only bindings from stores with the given domain prefix +//! ``` +//! +//! ### Subcommand list keys +//! +//! ```text +//! Lists all keys in the common key pool +//! +//! USAGE: +//! sq list keys +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! ``` +//! +//! ### Subcommand list stores +//! +//! ```text +//! Lists key stores +//! +//! USAGE: +//! sq list stores [PREFIX] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! ARGS: +//! <PREFIX> List only stores with the given domain prefix +//! ``` +//! //! ## Subcommand store //! //! ```text @@ -152,9 +217,11 @@ //! //! SUBCOMMANDS: //! add Add a key identified by fingerprint +//! delete Deletes bindings or stores //! export Exports a key //! help Prints this message or the help of the given subcommand(s) //! import Imports a key +//! list Lists keys in the store //! stats Get stats for the given label //! ``` //! @@ -175,6 +242,23 @@ //! <FINGERPRINT> Key to add //! ``` //! +//! ### Subcommand store delete +//! +//! ```text +//! Deletes bindings or stores +//! +//! USAGE: +//! sq store <NAME> delete [FLAGS] [LABEL] +//! +//! FLAGS: +//! -h, --help Prints help information +//! --the-store Delete the whole store +//! -V, --version Prints version information +//! +//! ARGS: +//! <LABEL> Delete binding with this label +//! ``` +//! //! ### Subcommand store export //! //! ```text @@ -215,6 +299,19 @@ //! <LABEL> Label to use //! ``` //! +//! ### Subcommand store list +//! +//! ```text +//! Lists keys in the store +//! +//! USAGE: +//! sq store <NAME> list +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! ``` +//! //! ### Subcommand store stats //! //! ```text |