use std::env;
use gumdrop::Options;
use anyhow::Result;
mod util;
mod bwutil;
const SESSION_ENV_KEY: &str = "BW_SESSION";
const BW_FIELD_KEY_FILENAME: &str = "private";
const BW_FIELD_KEY_PASSPHRASE: &str = "passphrase";
fn main() -> Result<()> {
let args: util::Cli = util::Cli::parse_args_default_or_exit();
if args.version {
println!("{}", &util::get_version_string()?);
return Ok(());
}
let session_token: String = check_session_token(&args)?;
if !session_token.is_empty() {
let folders = bwutil::exec_folder_search(&session_token, &args.folder)?;
for folder in folders {
let folder_items = bwutil::exec_list_folder_items(&session_token, &folder.id)?;
for item in folder_items {
if let Some(fields) = &item.fields {
let mut key_filename = String::new();
let mut key_passphrase = String::new();
for field in fields {
if field.name.to_lowercase().eq(&String::from(BW_FIELD_KEY_FILENAME).to_lowercase()) {
key_filename.push_str(&field.value);
}
if field.name.to_lowercase().eq(&String::from(BW_FIELD_KEY_PASSPHRASE).to_lowercase()) {
key_passphrase.push_str(&field.value);
}
}
if let Some(attachments) = &item.attachments {
for attachment in attachments {
if attachment.file_name.eq(&key_filename) {
println!("{:#?}", item);
}
}
}
}
}
}
}
Ok(())
}
fn check_session_token(args: &util::Cli) -> Result<String> {
println!("Getting Bitwarden session...");
let mut session_token: String = String::new();
if args.session.trim().is_empty() {
let env_key = env::var(SESSION_ENV_KEY);
match env_key {
Ok(key) => {
println!("{} is set. Reusing existing session.", SESSION_ENV_KEY);
session_token.push_str(&key);
},
Err(_) => {
println!("{} is not set. Attempting to login.", SESSION_ENV_KEY);
let token: &String = &bwutil::get_session_token()?;
if !token.is_empty() {
println!("Successfully unlocked. To re-use this session, run:");
println!("export {}=\"{}\"", SESSION_ENV_KEY, token);
}
session_token.push_str(token)
}
}
}
else {
session_token.push_str(&args.session);
}
Ok(session_token)
}