aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-05-03 04:07:03 -0400
committerJesse Luehrs <doy@tozt.net>2020-05-03 04:09:34 -0400
commitdbdd8a78951f8a44630abcceb7b13d0d823ee074 (patch)
tree64c69f16279876c71ba22a55ef6dd255289aaaef /src/bin
parent6ebf7d55e4c553870306a70092cfb677c17429b9 (diff)
downloadrbw-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.rs56
-rw-r--r--src/bin/rbw/commands.rs73
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"))
}