index : bitwarden-ssh-agent.git

ascending towards madness

author holly sparkles <sparkles@holly.sh> 2023-08-01 19:49:26.0 +00:00:00
committer holly sparkles <sparkles@holly.sh> 2023-08-01 19:49:26.0 +00:00:00
commit
c8d3b54a6f6dcf00910971c0bbadaa95076d1668 [patch]
tree
fc97730c2a4b361a19c3cc4044a06f0e143f70d2
parent
6bb5927fa9832fb3b3edd5414df262f2f4a7b9f1
download
c8d3b54a6f6dcf00910971c0bbadaa95076d1668.tar.gz

feat!: add listing items from ssh key folders BREAKING CHANGE: `exec_interactive_command` is now `exec_piped_command`



Diff

 src/bwutil.rs | 23 +++++++++++++++++------
 src/main.rs   | 10 ++++++++--
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/src/bwutil.rs b/src/bwutil.rs
index 36597fb..0e007e5 100644
--- a/src/bwutil.rs
+++ b/src/bwutil.rs
@@ -62,7 +62,7 @@ pub fn get_session_token() -> Result<String> {
		operation.push_str("login")
	}

	let success: Output = exec_interactive_command("bw", 
	let success: Output = exec_piped_command("bw", 
			["--raw", &operation].to_vec());
	if success.status.success() {			
		token.push_str(&String::from_utf8(success.stdout)?);
@@ -73,7 +73,7 @@ pub fn get_session_token() -> Result<String> {

/// Search Bitwarden for folders matching `folder_name` and return the results.
pub fn exec_folder_search(session: &str, folder_name: &str) -> Result<Vec<BitwardenFolder>> {
	let folders: Output = exec_interactive_command("bw", 
	let folders: Output = exec_piped_command("bw", 
			["list", "folders", "--search", &folder_name, "--session", &session].to_vec());
	let result: String = String::from_utf8_lossy(&folders.stdout).to_string();
	if result.is_empty() {
@@ -84,19 +84,30 @@ pub fn exec_folder_search(session: &str, folder_name: &str) -> Result<Vec<Bitwar
	}
}

// List items in a folder matching `folder_id` and return the results
pub fn exec_list_folder_items(session: &str, folder_id: &str) -> Result<Vec<BitwardenItem>> {
	let items = exec_piped_command("bw", 
			["list", "items", "--folderid", &folder_id, "--session", &session].to_vec());
	let result = String::from_utf8_lossy(&items.stdout).to_string();
	if result.is_empty() {
		Err(anyhow!("Could not authenticate."))
	}
	else {
		Ok(serde_json::from_str(&result).with_context(|| "Could not deserialize item search results.")?)
	}
}

/// Execute an interactive command.
/// 
/// The resulting output will be returned as `Output`. This is a modified version of:
/// 
/// https://users.rust-lang.org/t/command-if-a-child-process-is-asking-for-input-how-to-forward-the-question-to-the-user/37490/3
fn exec_interactive_command(cmd: &str, args: Vec<&str>) -> Output {
fn exec_piped_command(cmd: &str, args: Vec<&str>) -> Output {
    let cli_command = match Command::new(cmd)
        .args(&args)
        .stdin(Stdio::inherit())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
    {
	{
        Err(err) => panic!("Error spawning: {}", err),
        Ok(process) => process,
    };
diff --git a/src/main.rs b/src/main.rs
index 1d6ba4e..b815b4c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -37,8 +37,14 @@ fn main() -> Result<()> {

	let session_token: String = check_session_token(&args)?;
	if !session_token.is_empty() {
		let result = bwutil::exec_folder_search(&session_token, &args.folder)?;
		println!("{:#?}", result);
		let folders = bwutil::exec_folder_search(&session_token, &args.folder)?;
		// Retrieve items from each folder since there may be multiple folders with the same name.
		for folder in folders {
			let folder_items = bwutil::exec_list_folder_items(&session_token, &folder.id)?;
			for item in folder_items {
				println!("{:#?}", item);
			}
		}
	}

	Ok(())