diff --git a/src/main.rs b/src/main.rs index 359836d..cb73083 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ mod op; mod op7_metadata; use op::{ - find_items, load_all_accounts, load_all_vaults, AccountDetails, ItemOverview, VaultDetails, + load_all_accounts, load_all_items, load_all_vaults, AccountDetails, ItemDetails, VaultDetails, }; use op7_metadata::write_items; @@ -58,7 +58,7 @@ 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 items_by_vault: HashMap> = HashMap::new(); println!( "Exporting bookmarks for accounts {:?}", @@ -88,7 +88,7 @@ fn generate_opbookmarks(account_user_uuids: &Vec, export_path: &std::pat // Collect the items for each vault for (account, vaults) in vaults_by_account.iter() { for vault in vaults.iter() { - let items = find_items(&account.id, &vault.id); + let items = load_all_items(&account.id, &vault.id); match items { Ok(items) => { diff --git a/src/op.rs b/src/op.rs index 7ec8ccb..8d2de78 100644 --- a/src/op.rs +++ b/src/op.rs @@ -57,19 +57,19 @@ pub struct ItemOverview { pub struct ItemDetails { pub id: String, pub title: String, - pub tags: Vec, + pub tags: Option>, pub version: usize, pub vault: VaultOverview, pub category: String, pub last_edited_by: String, pub created_at: String, pub updated_at: String, - pub urls: Vec, + pub urls: Option>, } #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct OPURL { - pub primary: bool, + pub primary: Option, pub href: String, } @@ -257,6 +257,36 @@ pub fn get_vault(account_id: &String, vault_id: &String) -> Result Result, Error> { + let items = find_items(&account_id, &vault_id); + + match items { + Ok(items) => { + let mut details: Vec = vec![]; + for item in items.iter() { + let item_details = get_item(&account_id, &vault_id, &item.id); + + match item_details { + Ok(d) => details.push(d), + Err(e) => { + eprint!( + "Error loading item {} in vault {} for account {}: {:?}", + item.id, vault_id, 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_items(account_id: &String, vault_id: &String) -> Result, Error> { let output = Command::new("op") .arg("--format") @@ -283,15 +313,15 @@ pub fn find_items(account_id: &String, vault_id: &String) -> Result Result { let output = Command::new("op") .arg("--account") - .arg(account.url.clone()) + .arg(account_id) .arg("--vault") - .arg(vault.id.clone()) + .arg(vault_id) .arg("--format") .arg("json") .arg("item") diff --git a/src/op7_metadata.rs b/src/op7_metadata.rs index 5d97d7d..d7b7ea8 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, VaultDetails}; +use crate::op::{AccountDetails, ItemDetails, VaultDetails}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] @@ -45,7 +45,7 @@ pub struct OP7ItemMetaData { pub fn write_items( export_path: &std::path::PathBuf, - items: &Vec, + items: &Vec, vault: &VaultDetails, account: &AccountDetails, ) { @@ -97,10 +97,21 @@ fn write_file(path: std::path::PathBuf, contents: String) { } fn create_op7_metadata( - item: &ItemOverview, + item: &ItemDetails, vault: &VaultDetails, account_id: &String, ) -> OP7ItemMetaData { + let website_urls = match &item.urls { + Some(urls) => { + let mut result: Vec = vec![]; + for url in urls.iter() { + result.push(url.href.clone()); + } + result + } + None => vec![], + }; + return OP7ItemMetaData { uuid: item.id.clone(), item_description: format!("Login from {}", &vault.name.clone()), @@ -109,7 +120,7 @@ fn create_op7_metadata( vault_uuid: vault.id.clone(), category_plural_name: item.category.clone(), // TODO: Map SECURE_NOTE, etc profile_uuid: account_id.clone(), - website_urls: vec![], + website_urls: website_urls, category_singular_name: item.category.clone(), category_uuid: "001".to_string(), account_name: "".to_string(), // TODO: Not sure anyone uses this?