diff options
author | Jesse Luehrs <doy@tozt.net> | 2020-05-03 04:07:03 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2020-05-03 04:09:34 -0400 |
commit | dbdd8a78951f8a44630abcceb7b13d0d823ee074 (patch) | |
tree | 64c69f16279876c71ba22a55ef6dd255289aaaef /src/bin | |
parent | 6ebf7d55e4c553870306a70092cfb677c17429b9 (diff) | |
download | rbw-dbdd8a78951f8a44630abcceb7b13d0d823ee074.tar.gz rbw-dbdd8a78951f8a44630abcceb7b13d0d823ee074.zip |
allow storing password databases from different servers
this should allow easy switching of servers by just `rbw config set
base_url`
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/rbw-agent/actions.rs | 56 | ||||
-rw-r--r-- | src/bin/rbw/commands.rs | 73 |
2 files changed, 71 insertions, 58 deletions
diff --git a/src/bin/rbw-agent/actions.rs b/src/bin/rbw-agent/actions.rs index 3ca6d51..4e76d4b 100644 --- a/src/bin/rbw-agent/actions.rs +++ b/src/bin/rbw-agent/actions.rs @@ -5,12 +5,7 @@ pub async fn login( state: std::sync::Arc<tokio::sync::RwLock<crate::agent::State>>, tty: Option<&str>, ) -> anyhow::Result<()> { - let email = config_email() - .await - .context("failed to read email from config")?; - let mut db = rbw::db::Db::load_async(&email) - .await - .unwrap_or_else(|_| rbw::db::Db::new()); + let mut db = load_db().await.unwrap_or_else(|_| rbw::db::Db::new()); if db.needs_login() { let url_str = config_base_url() @@ -27,6 +22,8 @@ pub async fn login( )); }; + let email = config_email().await?; + for i in 1_u8..=3 { let err = if i > 1 { Some(format!("Incorrect password (attempt {}/3)", i)) @@ -56,9 +53,7 @@ pub async fn login( db.refresh_token = Some(refresh_token); db.iterations = Some(iterations); db.protected_key = Some(protected_key); - db.save_async(&email) - .await - .context("failed to save local database")?; + save_db(&db).await?; break; } @@ -93,13 +88,7 @@ pub async fn unlock( tty: Option<&str>, ) -> anyhow::Result<()> { if state.read().await.needs_unlock() { - let email = config_email() - .await - .context("failed to read email from config")?; - - let db = rbw::db::Db::load_async(&email) - .await - .context("failed to load local database")?; + let db = load_db().await?; let iterations = if let Some(iterations) = db.iterations { iterations @@ -124,6 +113,8 @@ pub async fn unlock( )); }; + let email = config_email().await?; + for i in 1u8..=3 { let err = if i > 1 { Some(format!("Incorrect password (attempt {}/3)", i)) @@ -184,12 +175,7 @@ pub async fn lock( } pub async fn sync(sock: &mut crate::sock::Sock) -> anyhow::Result<()> { - let email = config_email() - .await - .context("failed to read email from config")?; - let mut db = rbw::db::Db::load_async(&email) - .await - .context("failed to load local database")?; + let mut db = load_db().await?; let access_token = if let Some(access_token) = &db.access_token { access_token.clone() @@ -214,9 +200,7 @@ pub async fn sync(sock: &mut crate::sock::Sock) -> anyhow::Result<()> { db.protected_private_key = Some(protected_private_key); db.protected_org_keys = protected_org_keys; db.entries = entries; - db.save_async(&email) - .await - .context("failed to save database")?; + save_db(&db).await?; respond_ack(sock).await?; @@ -327,6 +311,28 @@ async fn config_email() -> anyhow::Result<String> { } } +async fn load_db() -> anyhow::Result<rbw::db::Db> { + let config = rbw::config::Config::load_async().await?; + if let Some(email) = &config.email { + rbw::db::Db::load_async(&config.server_name(), &email) + .await + .context("failed to load password database") + } else { + Err(anyhow::anyhow!("failed to find email address in config")) + } +} + +async fn save_db(db: &rbw::db::Db) -> anyhow::Result<()> { + let config = rbw::config::Config::load_async().await?; + if let Some(email) = &config.email { + db.save_async(&config.server_name(), &email) + .await + .context("failed to save password database") + } else { + Err(anyhow::anyhow!("failed to find email address in config")) + } +} + async fn config_base_url() -> anyhow::Result<String> { let config = rbw::config::Config::load_async() .await diff --git a/src/bin/rbw/commands.rs b/src/bin/rbw/commands.rs index 51d0453..a6e98c7 100644 --- a/src/bin/rbw/commands.rs +++ b/src/bin/rbw/commands.rs @@ -107,10 +107,7 @@ pub fn list(fields: &[&str]) -> anyhow::Result<()> { unlock()?; - let email = config_email()?; - let db = rbw::db::Db::load(&email) - .context("failed to load password database")?; - + let db = load_db()?; let mut ciphers: Vec<DecryptedCipher> = db .entries .iter() @@ -146,9 +143,7 @@ pub fn list(fields: &[&str]) -> anyhow::Result<()> { pub fn get(name: &str, user: Option<&str>, full: bool) -> anyhow::Result<()> { unlock()?; - let email = config_email()?; - let db = rbw::db::Db::load(&email) - .context("failed to load password database")?; + let db = load_db()?; let desc = format!( "{}{}", @@ -182,8 +177,7 @@ pub fn add( ) -> anyhow::Result<()> { unlock()?; - let email = config_email()?; - let mut db = rbw::db::Db::load(&email)?; + let mut db = load_db()?; // unwrap is safe here because the call to unlock above is guaranteed to // populate these or error let mut access_token = db.access_token.as_ref().unwrap().clone(); @@ -216,7 +210,7 @@ pub fn add( if let Some(new_access_token) = new_access_token { access_token = new_access_token.clone(); db.access_token = Some(new_access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } let folders: Vec<(String, String)> = folders @@ -239,7 +233,7 @@ pub fn add( if let Some(new_access_token) = new_access_token { access_token = new_access_token.clone(); db.access_token = Some(new_access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } folder_id = Some(id); } @@ -256,7 +250,7 @@ pub fn add( folder_id.as_deref(), )? { db.access_token = Some(access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } crate::actions::sync()?; @@ -278,8 +272,7 @@ pub fn generate( if let Some(name) = name { unlock()?; - let email = config_email()?; - let mut db = rbw::db::Db::load(&email)?; + let mut db = load_db()?; // unwrap is safe here because the call to unlock above is guaranteed // to populate these or error let mut access_token = db.access_token.as_ref().unwrap().clone(); @@ -302,7 +295,7 @@ pub fn generate( if let Some(new_access_token) = new_access_token { access_token = new_access_token.clone(); db.access_token = Some(new_access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } let folders: Vec<(String, String)> = folders @@ -327,7 +320,7 @@ pub fn generate( if let Some(new_access_token) = new_access_token { access_token = new_access_token.clone(); db.access_token = Some(new_access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } folder_id = Some(id); } @@ -344,7 +337,7 @@ pub fn generate( folder_id.as_deref(), )? { db.access_token = Some(access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } crate::actions::sync()?; @@ -356,9 +349,7 @@ pub fn generate( pub fn edit(name: &str, username: Option<&str>) -> anyhow::Result<()> { unlock()?; - let email = config_email()?; - let mut db = rbw::db::Db::load(&email) - .context("failed to load password database")?; + let mut db = load_db()?; let access_token = db.access_token.as_ref().unwrap(); let refresh_token = db.refresh_token.as_ref().unwrap(); @@ -409,7 +400,7 @@ pub fn edit(name: &str, username: Option<&str>) -> anyhow::Result<()> { &history, )? { db.access_token = Some(access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } crate::actions::sync()?; @@ -419,9 +410,7 @@ pub fn edit(name: &str, username: Option<&str>) -> anyhow::Result<()> { pub fn remove(name: &str, username: Option<&str>) -> anyhow::Result<()> { unlock()?; - let email = config_email()?; - let mut db = rbw::db::Db::load(&email) - .context("failed to load password database")?; + let mut db = load_db()?; let access_token = db.access_token.as_ref().unwrap(); let refresh_token = db.refresh_token.as_ref().unwrap(); @@ -440,7 +429,7 @@ pub fn remove(name: &str, username: Option<&str>) -> anyhow::Result<()> { rbw::actions::remove(&access_token, &refresh_token, &entry.id)? { db.access_token = Some(access_token); - db.save(&email).context("failed to save database")?; + save_db(&db)?; } crate::actions::sync()?; @@ -451,9 +440,7 @@ pub fn remove(name: &str, username: Option<&str>) -> anyhow::Result<()> { pub fn history(name: &str, username: Option<&str>) -> anyhow::Result<()> { unlock()?; - let email = config_email()?; - let db = rbw::db::Db::load(&email) - .context("failed to load password database")?; + let db = load_db()?; let desc = format!( "{}{}", @@ -482,8 +469,7 @@ pub fn lock() -> anyhow::Result<()> { pub fn purge() -> anyhow::Result<()> { stop_agent()?; - let email = config_email()?; - rbw::db::Db::remove(&email).context("failed to remove database")?; + remove_db()?; Ok(()) } @@ -755,10 +741,31 @@ fn parse_editor(contents: &str) -> (Option<String>, Option<String>) { (password, notes) } -fn config_email() -> anyhow::Result<String> { +fn load_db() -> anyhow::Result<rbw::db::Db> { + let config = rbw::config::Config::load()?; + if let Some(email) = &config.email { + rbw::db::Db::load(&config.server_name(), &email) + .context("failed to load password database") + } else { + Err(anyhow::anyhow!("failed to find email address in config")) + } +} + +fn save_db(db: &rbw::db::Db) -> anyhow::Result<()> { + let config = rbw::config::Config::load()?; + if let Some(email) = &config.email { + db.save(&config.server_name(), &email) + .context("failed to save password database") + } else { + Err(anyhow::anyhow!("failed to find email address in config")) + } +} + +fn remove_db() -> anyhow::Result<()> { let config = rbw::config::Config::load()?; - if let Some(email) = config.email { - Ok(email) + if let Some(email) = &config.email { + rbw::db::Db::remove(&config.server_name(), &email) + .context("failed to remove password database") } else { Err(anyhow::anyhow!("failed to find email address in config")) } |