use clap::Clap;
use colored::*;
use itertools::Itertools;
use onep_api::OnePassword;
use term_table::{
row::Row,
table_cell::{Alignment, TableCell},
Table, TableStyle,
};
#[derive(Clap, Debug)]
#[clap(author, version)]
enum Opt {
#[clap(alias = "list")]
Ls {
#[clap(long, short = 'i')]
show_uuids: bool,
#[clap(long, short = 'n')]
show_account_names: bool,
},
Totp { uuid: String },
Search { terms: String },
#[clap(alias = "get")]
Show { uuid: String },
}
fn main() {
let imp = onep_api_op::OnepasswordOp {};
match Opt::parse() {
Opt::Ls {
show_uuids,
show_account_names,
} => {
let account = imp.account();
let vaults = imp.vaults();
let results = imp.search(None);
let mut results_grouped: Vec<(_, Vec<_>)> = Vec::new();
for (key, group) in &results.into_iter().group_by(|v| v.vault_uuid.clone()) {
results_grouped.push((key, group.collect()));
}
println!("{} ({})", account.name, account.domain);
let vault_count = results_grouped.len() - 1;
for (current_vault_index, (vault, group)) in results_grouped.into_iter().enumerate() {
let vault = vaults
.iter()
.find(|v| v.uuid == vault)
.map(|v| v.name.clone())
.unwrap_or_else(|| format!("Unknown Vault ({})", vault));
println!(
"{} {}",
if current_vault_index < vault_count {
"├──"
} else {
"└──"
},
vault.blue()
);
let line_start = if current_vault_index < vault_count {
"│"
} else {
" "
};
let item_count = group.len() - 1;
for (current_item_index, result) in group.into_iter().enumerate() {
println!(
"{} {} {}",
line_start,
if current_item_index < item_count {
"├──"
} else {
"└──"
},
result.title.trim()
);
let prefix = if current_item_index < item_count {
"│ "
} else {
" "
};
if show_account_names && !result.account_info.trim().is_empty() {
println!(
"{} {} {}",
line_start,
prefix,
result.account_info.trim().green()
);
}
if show_uuids {
println!("{} {} {}", line_start, prefix, result.uuid.yellow());
}
}
}
}
Opt::Totp { uuid } => println!("{}", imp.totp(&uuid).trim()),
Opt::Search { terms } => {
for result in imp.search(Some(&terms)) {
println!("[{}]", result.title.green());
println!("{}", result.account_info);
println!("{}", result.uuid);
println!();
}
}
Opt::Show { uuid } => {
let result = imp.get(&uuid).unwrap();
let mut table = Table::new();
table.style = TableStyle::extended();
table.add_row(Row::new(vec![TableCell::new_with_alignment(
result.title,
2,
Alignment::Center,
)]));
for field in result.fields {
table.add_row(Row::new(vec![
TableCell::new(field.name),
TableCell::new_with_alignment(field.value, 1, Alignment::Right),
]));
}
println!("{}", table.render());
for section in result.sections {
if section.fields.is_empty() {
continue;
}
let mut table = Table::new();
table.style = TableStyle::extended();
if !section.name.is_empty() {
table.add_row(Row::new(vec![TableCell::new_with_alignment(
section.name,
2,
Alignment::Center,
)]));
}
for field in section.fields {
table.add_row(Row::new(vec![
TableCell::new(field.name),
TableCell::new_with_alignment(field.value, 1, Alignment::Right),
]));
}
println!("{}", table.render());
}
}
}
}