diff --git a/src/main.rs b/src/main.rs index e08ea8a..359836d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,9 @@ mod op; mod op7_metadata; -use op::{find_items, find_vaults, load_all_accounts, AccountDetails, ItemOverview, VaultOverview}; +use op::{ + find_items, load_all_accounts, load_all_vaults, AccountDetails, ItemOverview, VaultDetails, +}; use op7_metadata::write_items; use clap::Parser; @@ -55,8 +57,8 @@ fn generate_opbookmarks(account_user_uuids: &Vec, export_path: &std::pat } let accounts = accounts.unwrap(); - let mut vaults_by_account: HashMap> = HashMap::new(); - let mut items_by_vault: HashMap> = HashMap::new(); + let mut vaults_by_account: HashMap> = HashMap::new(); + let mut items_by_vault: HashMap> = HashMap::new(); println!( "Exporting bookmarks for accounts {:?}", @@ -68,7 +70,7 @@ fn generate_opbookmarks(account_user_uuids: &Vec, export_path: &std::pat // Collect the vaults for each account for account in accounts.iter() { - let vaults = find_vaults(&account.id); + let vaults = load_all_vaults(&account.id); match vaults { Ok(vaults) => { diff --git a/src/op.rs b/src/op.rs index 3d62f0a..7ec8ccb 100644 --- a/src/op.rs +++ b/src/op.rs @@ -33,7 +33,6 @@ pub struct VaultDetails { pub attribute_version: usize, pub content_version: usize, - pub items: usize, #[serde(rename = "type")] pub vault_type: String, @@ -182,6 +181,36 @@ pub fn get_account(user_id: &String) -> Result { serde_json::from_slice(json.as_slice()).map_err(|e| Error::Deserialize(e)) } +pub fn load_all_vaults(account_id: &String) -> Result, Error> { + let vaults = find_vaults(&account_id); + + match vaults { + Ok(vaults) => { + let mut details: Vec = vec![]; + for vault in vaults.iter() { + let ad = get_vault(&account_id, &vault.id); + + match ad { + Ok(ad) => details.push(ad), + Err(e) => { + eprint!( + "Error loading vault details for account {}: {:?}", + account_id, e + ); + return Err(Error::OPCLI(format!( + "Failed to load details for account {}", + account_id + ))); + } + } + } + + Ok(details) + } + Err(e) => Err(e), + } +} + pub fn find_vaults(account_id: &String) -> Result, Error> { let output = Command::new("op") .arg("--format") @@ -205,12 +234,12 @@ pub fn find_vaults(account_id: &String) -> Result, Error> { } // op --account BXRGOJ2Z5JB4RMA7FUYUURELUE --format json vault get jnnjfdrzr5rawkimmsvp3zzzxe -pub fn get_vault(account: &AccountOverview, vault_id: String) -> Result { +pub fn get_vault(account_id: &String, vault_id: &String) -> Result { let output = Command::new("op") .arg("--format") .arg("json") .arg("--account") - .arg(account.user_uuid.clone()) + .arg(account_id) .arg("vault") .arg("get") .arg(vault_id) diff --git a/src/op7_metadata.rs b/src/op7_metadata.rs index 3a9c2b7..5d97d7d 100644 --- a/src/op7_metadata.rs +++ b/src/op7_metadata.rs @@ -1,5 +1,5 @@ /// Create metadata files that conform to the format used by 1Password 7 -use crate::op::{AccountDetails, ItemOverview, VaultOverview}; +use crate::op::{AccountDetails, ItemOverview, VaultDetails}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] @@ -46,7 +46,7 @@ pub struct OP7ItemMetaData { pub fn write_items( export_path: &std::path::PathBuf, items: &Vec, - vault: &VaultOverview, + vault: &VaultDetails, account: &AccountDetails, ) { let mut path = export_path.clone(); @@ -98,14 +98,14 @@ fn write_file(path: std::path::PathBuf, contents: String) { fn create_op7_metadata( item: &ItemOverview, - vault: &VaultOverview, + vault: &VaultDetails, account_id: &String, ) -> OP7ItemMetaData { return OP7ItemMetaData { uuid: item.id.clone(), - item_description: format!("Login from {}", &vault.name.clone().unwrap()), + item_description: format!("Login from {}", &vault.name.clone()), item_title: item.title.clone(), - vault_name: vault.name.clone().unwrap().clone(), + vault_name: vault.name.clone().clone(), vault_uuid: vault.id.clone(), category_plural_name: item.category.clone(), // TODO: Map SECURE_NOTE, etc profile_uuid: account_id.clone(),