diff options
author | Jesse Luehrs <doy@tozt.net> | 2020-04-18 16:13:17 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2020-04-18 16:13:17 -0400 |
commit | be6da4a9d82467690e7388bc69db4d9facf7a6b8 (patch) | |
tree | fc190e5cb6fd0b4d470eed50e7e6434c2e5690fb | |
parent | 50ab8aabcec26d07f4b4d9652dbceac1b89a6b22 (diff) | |
download | rbw-be6da4a9d82467690e7388bc69db4d9facf7a6b8.tar.gz rbw-be6da4a9d82467690e7388bc69db4d9facf7a6b8.zip |
refactor
-rw-r--r-- | src/actions.rs | 107 | ||||
-rw-r--r-- | src/bin/rbw-agent/actions.rs | 2 | ||||
-rw-r--r-- | src/bin/rbw/commands.rs | 8 |
3 files changed, 70 insertions, 47 deletions
diff --git a/src/actions.rs b/src/actions.rs index 634fa9a..0fea7df 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -46,18 +46,16 @@ pub async fn unlock( pub async fn sync( access_token: &str, refresh_token: &str, -) -> Result<(Option<String>, String, Vec<crate::db::Entry>)> { - let res = sync_once(access_token).await; - match res { - Ok((protected_key, ciphers)) => Ok((None, protected_key, ciphers)), - Err(crate::error::Error::RequestUnauthorized) => { - let access_token = - exchange_refresh_token_async(refresh_token).await?; - let (protected_key, ciphers) = sync_once(&access_token).await?; - Ok((Some(access_token), protected_key, ciphers)) - } - Err(e) => Err(e), - } +) -> Result<(Option<String>, (String, Vec<crate::db::Entry>))> { + with_exchange_refresh_token_async( + access_token, + refresh_token, + |access_token| { + let access_token = access_token.to_string(); + Box::pin(async move { sync_once(&access_token).await }) + }, + ) + .await } async fn sync_once( @@ -76,16 +74,10 @@ pub fn add( username: Option<&str>, password: Option<&str>, notes: Option<&str>, -) -> Result<Option<String>> { - match add_once(access_token, name, username, password, notes) { - Ok(()) => Ok(None), - Err(crate::error::Error::RequestUnauthorized) => { - let access_token = exchange_refresh_token(refresh_token)?; - add_once(&access_token, name, username, password, notes)?; - Ok(Some(access_token)) - } - Err(e) => Err(e), - } +) -> Result<(Option<String>, ())> { + with_exchange_refresh_token(access_token, refresh_token, |access_token| { + add_once(access_token, name, username, password, notes) + }) } fn add_once( @@ -110,16 +102,10 @@ pub fn edit( username: Option<&str>, password: Option<&str>, notes: Option<&str>, -) -> Result<Option<String>> { - match edit_once(access_token, id, name, username, password, notes) { - Ok(()) => Ok(None), - Err(crate::error::Error::RequestUnauthorized) => { - let access_token = exchange_refresh_token(refresh_token)?; - edit_once(&access_token, id, name, username, password, notes)?; - Ok(Some(access_token)) - } - Err(e) => Err(e), - } +) -> Result<(Option<String>, ())> { + with_exchange_refresh_token(access_token, refresh_token, |access_token| { + edit_once(access_token, id, name, username, password, notes) + }) } fn edit_once( @@ -141,16 +127,10 @@ pub fn remove( access_token: &str, refresh_token: &str, id: &str, -) -> Result<Option<String>> { - match remove_once(access_token, id) { - Ok(()) => Ok(None), - Err(crate::error::Error::RequestUnauthorized) => { - let access_token = exchange_refresh_token(refresh_token)?; - remove_once(&access_token, id)?; - Ok(Some(access_token)) - } - Err(e) => Err(e), - } +) -> Result<(Option<String>, ())> { + with_exchange_refresh_token(access_token, refresh_token, |access_token| { + remove_once(access_token, id) + }) } fn remove_once(access_token: &str, id: &str) -> Result<()> { @@ -161,6 +141,49 @@ fn remove_once(access_token: &str, id: &str) -> Result<()> { Ok(()) } +fn with_exchange_refresh_token<F, T>( + access_token: &str, + refresh_token: &str, + f: F, +) -> Result<(Option<String>, T)> +where + F: Fn(&str) -> Result<T>, +{ + match f(access_token) { + Ok(t) => Ok((None, t)), + Err(crate::error::Error::RequestUnauthorized) => { + let access_token = exchange_refresh_token(refresh_token)?; + let t = f(&access_token)?; + Ok((Some(access_token), t)) + } + Err(e) => Err(e), + } +} + +async fn with_exchange_refresh_token_async<F, T>( + access_token: &str, + refresh_token: &str, + f: F, +) -> Result<(Option<String>, T)> +where + F: Fn( + &str, + ) -> std::pin::Pin< + Box<dyn std::future::Future<Output = Result<T>> + Send>, + >, +{ + match f(access_token).await { + Ok(t) => Ok((None, t)), + Err(crate::error::Error::RequestUnauthorized) => { + let access_token = + exchange_refresh_token_async(refresh_token).await?; + let t = f(&access_token).await?; + Ok((Some(access_token), t)) + } + Err(e) => Err(e), + } +} + fn exchange_refresh_token(refresh_token: &str) -> Result<String> { let config = crate::config::Config::load()?; let client = diff --git a/src/bin/rbw-agent/actions.rs b/src/bin/rbw-agent/actions.rs index 9875d5c..ac331ce 100644 --- a/src/bin/rbw-agent/actions.rs +++ b/src/bin/rbw-agent/actions.rs @@ -137,7 +137,7 @@ pub async fn sync(sock: &mut crate::sock::Sock) -> anyhow::Result<()> { } else { return Err(anyhow::anyhow!("failed to find refresh token in db")); }; - let (access_token, protected_key, entries) = + let (access_token, (protected_key, entries)) = rbw::actions::sync(&access_token, &refresh_token) .await .context("failed to sync database from server")?; diff --git a/src/bin/rbw/commands.rs b/src/bin/rbw/commands.rs index 42fb8ee..70f7ddf 100644 --- a/src/bin/rbw/commands.rs +++ b/src/bin/rbw/commands.rs @@ -135,7 +135,7 @@ pub fn add(name: &str, username: Option<&str>) -> anyhow::Result<()> { .map(|notes| crate::actions::encrypt(¬es)) .transpose()?; - if let Some(access_token) = rbw::actions::add( + if let (Some(access_token), ()) = rbw::actions::add( &access_token, &refresh_token, &name, @@ -177,7 +177,7 @@ pub fn generate( .transpose()?; let password = crate::actions::encrypt(&password)?; - if let Some(access_token) = rbw::actions::add( + if let (Some(access_token), ()) = rbw::actions::add( &access_token, &refresh_token, &name, @@ -231,7 +231,7 @@ pub fn edit(name: &str, username: Option<&str>) -> anyhow::Result<()> { .map(|notes| crate::actions::encrypt(¬es)) .transpose()?; - if let Some(access_token) = rbw::actions::edit( + if let (Some(access_token), ()) = rbw::actions::edit( &access_token, &refresh_token, &entry.id, @@ -268,7 +268,7 @@ pub fn remove(name: &str, username: Option<&str>) -> anyhow::Result<()> { let (entry, _) = find_entry(&db, name, username) .with_context(|| format!("couldn't find entry for '{}'", desc))?; - if let Some(access_token) = + if let (Some(access_token), ()) = rbw::actions::remove(&access_token, &refresh_token, &entry.id)? { db.access_token = Some(access_token); |