From df4daee410e66bf08721421364c1c3b5b771922d Mon Sep 17 00:00:00 2001 From: Teo Stocco Date: Sat, 4 May 2024 14:59:07 +0200 Subject: [PATCH] fix: json support in 1p (#78) --- Cargo.toml | 6 ++--- lade.yml | 1 + sdk/Cargo.toml | 4 +-- sdk/src/providers/onepassword.rs | 45 ++++++++++---------------------- 4 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b05f89f..ace0b50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ resolver = "2" [package] name = "lade" -version = "0.11.2-beta.1" +version = "0.11.2" edition = "2021" description = "Automatically load secrets from your preferred vault as environment variables, and clear them once your shell command is over." license = "MPL-2.0" @@ -20,11 +20,11 @@ self_update = { version = "0.40.0", features = [ "compression-zip-deflate", "compression-zip-bzip2", ] } -serde = { version = "1.0.198", features = ["derive"] } +serde = { version = "1.0.200", features = ["derive"] } serde_yaml = "0.9.34" clap = { version = "4.5.4", features = ["derive"] } regex = "1.10.4" -lade-sdk = { path = "./sdk", version = "0.11.2-beta.1" } +lade-sdk = { path = "./sdk", version = "0.11.2" } tokio = { version = "1", features = ["full"] } indexmap = { version = "2.2.6", features = ["serde"] } clap-verbosity-flag = "2.2.0" diff --git a/lade.yml b/lade.yml index 8b28a58..2a6e8bf 100644 --- a/lade.yml +++ b/lade.yml @@ -21,6 +21,7 @@ D2: op://my.1password.eu/Personal/Lade/password D3: op://my.1password.eu/Personal/Lade/with space D4: op://my.1password.eu/Personal/Lade/file + D5: op://my.1password.eu/Personal/Lade/json ^echo e: # export VAULT_TOKEN=token diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 9cf0e63..e39edd1 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lade-sdk" -version = "0.11.2-beta.1" +version = "0.11.2" edition = "2021" description = "Lade SDK" license = "MPL-2.0" @@ -17,7 +17,7 @@ log = "0.4.21" once_cell = "1.19.0" regex = "1.10.4" rust-ini = "0.21.0" -serde = { version = "1.0.198", features = ["derive"] } +serde = { version = "1.0.200", features = ["derive"] } serde_json = "1.0.116" serde_yaml = "0.9.34" tempfile = "3.10.1" diff --git a/sdk/src/providers/onepassword.rs b/sdk/src/providers/onepassword.rs index 140a12a..5c809ed 100644 --- a/sdk/src/providers/onepassword.rs +++ b/sdk/src/providers/onepassword.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, path::Path}; -use anyhow::{anyhow, bail, Result}; +use anyhow::{bail, Result}; use async_process::{Command, Stdio}; use async_trait::async_trait; use futures::{future::try_join_all, AsyncWriteExt}; @@ -24,6 +24,8 @@ impl OnePassword { } } +static SEP: &str = "'Km5Ge8AbNc+QSBauOIN0jg'"; + #[async_trait] impl Provider for OnePassword { fn add(&mut self, value: String) -> Result<()> { @@ -54,10 +56,9 @@ impl Provider for OnePassword { return Ok(HashMap::new()); } - let json = &vars - .iter() - .map(|(k, v)| (k, v.replace(&format!("{host}/"), "").replace("%20", " "))) - .collect::>(); + let input = &vars.values() + .map(|v| v.replace(&format!("{host}/"), "").replace("%20", " ")) + .join(SEP); let cmd = &["op", "inject", "--account", &host.to_string()]; debug!("Lade run: {}", cmd.join(" ")); @@ -69,11 +70,11 @@ impl Provider for OnePassword { .stdin(Stdio::piped()) .spawn()?; - debug!("stdin: {:?}", json); + debug!("stdin: {:?}", input); let mut stdin = process.stdin.take().expect("Failed to open stdin"); stdin - .write_all(serde_json::to_string(&json)?.as_bytes()) + .write_all(input.as_bytes()) .await?; drop(stdin); @@ -88,33 +89,15 @@ impl Provider for OnePassword { }; let output = String::from_utf8_lossy(&child.stdout).trim().replace('\n', "\\n"); - let loaded = - serde_json::from_str::(&output).map_err(|err| { - let stderr = String::from_utf8_lossy(&child.stderr); - if stderr.contains("could not resolve item UUID") { - anyhow!( - "One item does not seem to exist in the vault: {stderr}", - ) - } else { - anyhow!("1Password error: {err} (stderr: {stderr})",) - } - - })?; + debug!("stdout: {:?}", output); + let loaded = output.split(SEP).collect::>(); let hydration = vars - .iter() - .map(|(key, value)| { - let var = match (loaded.get(key), json.get(key)) { - (Some(loaded), Some(original)) if loaded == original => None, - (Some(loaded), _) => Some(loaded), - _ => None, - }; - + .iter().zip_eq(loaded) + .map(|((_, key), value)| { ( - value.clone(), - var - .unwrap_or_else(|| panic!("Variable not found in 1Password: {}", key)) - .clone(), + key.clone(), + value.to_string(), ) }) .collect::();