🐛 Fixes parsing bw output

This commit is contained in:
2026-07-20 10:41:53 +02:00
parent bfc24d312d
commit c7aacb1df6
3 changed files with 61 additions and 12 deletions
+4 -4
View File
@@ -1,6 +1,6 @@
use crate::sh; use crate::sh;
use serde::Deserialize; use serde::Deserialize;
use std::io::{Error, ErrorKind, Write, stdin, stdout}; use std::io::{Error, ErrorKind};
const EXECUTABLE: &str = "bw"; const EXECUTABLE: &str = "bw";
@@ -20,7 +20,7 @@ pub struct Item {
pub notes: Option<String>, pub notes: Option<String>,
pub favorite: bool, pub favorite: bool,
pub fields: Vec<ItemField>, pub fields: Vec<ItemField>,
pub login: Login, pub login: Option<Login>,
} }
#[derive(Deserialize, Clone)] #[derive(Deserialize, Clone)]
@@ -41,7 +41,7 @@ pub struct ItemField {
#[derive(Deserialize, Clone)] #[derive(Deserialize, Clone)]
pub struct Login { pub struct Login {
pub uris: Vec<LoginUri>, pub uris: Vec<LoginUri>,
pub username: String, pub username: Option<String>,
pub password: Option<String>, pub password: Option<String>,
pub totp: Option<String>, pub totp: Option<String>,
#[serde(rename = "passwordRevisionDate")] #[serde(rename = "passwordRevisionDate")]
@@ -77,7 +77,7 @@ pub struct Fido2Credential {
#[serde(rename = "rpName")] #[serde(rename = "rpName")]
pub rp_name: String, pub rp_name: String,
#[serde(rename = "userDisplayName")] #[serde(rename = "userDisplayName")]
pub user_display_name: String, pub user_display_name: Option<String>,
pub discoverable: String, pub discoverable: String,
#[serde(rename = "creationDate")] #[serde(rename = "creationDate")]
pub creation_date: String, pub creation_date: String,
+30 -6
View File
@@ -59,9 +59,11 @@ fn sync() -> Result<(), Error> {
} }
}; };
println!("getting pass logins");
let pass_items = pass::get_items(&vault)?; let pass_items = pass::get_items(&vault)?;
let mut pass_logins = pass::get_logins(pass_items); let mut pass_logins = pass::get_logins(pass_items);
println!("getting bw logins");
let mut bw_items = bw::get_items()?; let mut bw_items = bw::get_items()?;
println!(); println!();
@@ -72,6 +74,11 @@ fn sync() -> Result<(), Error> {
); );
for bw_item in bw_items.clone().iter() { for bw_item in bw_items.clone().iter() {
if let None = bw_item.login {
continue;
}
let bw_login = bw_item.login.clone().unwrap();
let mut pass_login: Option<&pass::LoginItem> = None; let mut pass_login: Option<&pass::LoginItem> = None;
'inner: for pass_login_iter in pass_logins.iter() { 'inner: for pass_login_iter in pass_logins.iter() {
@@ -86,7 +93,7 @@ fn sync() -> Result<(), Error> {
} }
let pass_login = pass_login.unwrap(); let pass_login = pass_login.unwrap();
let bw_password = bw_item.login.password.clone(); let bw_password = bw_login.password.clone();
// TODO: fix this // TODO: fix this
if let None = bw_password { if let None = bw_password {
continue; continue;
@@ -95,7 +102,12 @@ fn sync() -> Result<(), Error> {
let pass_password = pass_login.password.clone(); let pass_password = pass_login.password.clone();
let bw_user = bw_item.login.username.clone(); let bw_user = bw_login.username.clone();
if let None = bw_user {
continue;
}
let bw_user = bw_user.unwrap();
let pass_user = match pass_login.username.is_empty() { let pass_user = match pass_login.username.is_empty() {
true => pass_login.email.clone(), true => pass_login.email.clone(),
false => pass_login.username.clone(), false => pass_login.username.clone(),
@@ -115,6 +127,9 @@ fn sync() -> Result<(), Error> {
username: bw_user.clone(), username: bw_user.clone(),
email: bw_user.clone(), email: bw_user.clone(),
password: bw_password, password: bw_password,
notes: pass_login.notes.clone(),
urls: pass_login.urls.clone(),
totp: pass_login.totp.clone(),
}; };
pass::update(&vault, updated_pass_login, pass_user_is_actually_email); pass::update(&vault, updated_pass_login, pass_user_is_actually_email);
} }
@@ -138,17 +153,26 @@ fn sync() -> Result<(), Error> {
); );
for bw_item in bw_items { for bw_item in bw_items {
if let None = bw_item.login {
continue;
}
let login = bw_item.login.unwrap();
if let None = login.username {
continue;
}
let consent = ask_consent( let consent = ask_consent(
format!("Attempting to create {}:", bw_item.name), format!("Attempting to create {}:", bw_item.name),
format!("{}", bw_item.login.username), format!("{}", login.username.clone().unwrap()),
format!("{:?}", bw_item.login.password), format!("{:?}", login.password),
)?; )?;
if consent { if consent {
pass::create( pass::create(
&vault, &vault,
bw_item.name, bw_item.name,
bw_item.login.username, login.username.unwrap(),
bw_item.login.password.unwrap_or("".to_string()), login.password.unwrap_or("".to_string()),
); );
} }
} }
+27 -2
View File
@@ -31,6 +31,7 @@ pub struct Item {
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
pub struct ItemContent { pub struct ItemContent {
pub title: String, pub title: String,
pub note: String,
pub content: ItemContentContent, pub content: ItemContentContent,
} }
@@ -46,6 +47,8 @@ pub struct ItemLogin {
pub email: String, pub email: String,
pub username: String, pub username: String,
pub password: String, pub password: String,
pub urls: Vec<String>,
pub totp_uri: Option<String>,
} }
// our own custom structure, a counterpart to rbw::LoginItem // our own custom structure, a counterpart to rbw::LoginItem
@@ -56,6 +59,9 @@ pub struct LoginItem {
pub username: String, pub username: String,
pub email: String, pub email: String,
pub password: String, pub password: String,
pub urls: Option<Vec<String>>,
pub notes: String,
pub totp: Option<String>,
} }
pub fn check_pass() -> Result<(), Error> { pub fn check_pass() -> Result<(), Error> {
@@ -124,6 +130,9 @@ pub fn get_logins(items: Items) -> Vec<LoginItem> {
username: login.username, username: login.username,
email: login.email, email: login.email,
password: login.password, password: login.password,
notes: item.content.note.clone(),
urls: Some(login.urls),
totp: login.totp_uri,
} }
}) })
.collect() .collect()
@@ -135,9 +144,25 @@ pub fn update(vault: &String, item: LoginItem, user_is_actually_email: bool) {
} else { } else {
format!("usename={}", item.username) format!("usename={}", item.username)
}; };
let maybe_urls = if let Some(urls) = item.urls {
let mut it = "".to_string();
for url in urls {
it = format!("{} --field 'url={}'", it, url);
}
it
} else {
"".to_string()
};
let maybe_notes = if item.notes.is_empty() {
"".to_string()
} else {
format!("--field 'note={}'", item.notes)
};
let output = sh::sh(format!( let output = sh::sh(format!(
"{} item update --vault-name '{}' --item-id '{}' --field 'password={}' --field '{}'", "{} item update --vault-name '{}' --item-id '{}' --field 'password={}' --field '{}' {} {}",
EXECUTABLE, vault, item.id, item.password, user_field_update EXECUTABLE, vault, item.id, item.password, user_field_update, maybe_urls, maybe_notes
)); ));
println!("> {}", output); println!("> {}", output);
} }