diff options
author | Jesse Luehrs <doy@tozt.net> | 2020-05-27 03:20:53 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2020-05-27 03:27:16 -0400 |
commit | 6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c (patch) | |
tree | 566735e913a7e302a3d2ee3e439208752a77ac2e /src | |
parent | bc137a1f4c7c4026effa9eec06a1f0d594d21b2a (diff) | |
download | rbw-6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c.tar.gz rbw-6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c.zip |
parse login error correctly
Diffstat (limited to 'src')
-rw-r--r-- | src/api.rs | 54 | ||||
-rw-r--r-- | src/error.rs | 3 |
2 files changed, 48 insertions, 9 deletions
@@ -46,8 +46,12 @@ struct ConnectPasswordRes { #[derive(serde::Deserialize, Debug)] struct ConnectErrorRes { + error: String, + error_description: String, #[serde(rename = "ErrorModel")] - error_model: ConnectErrorResErrorModel, + error_model: Option<ConnectErrorResErrorModel>, + #[serde(rename = "TwoFactorProviders")] + two_factor_providers: Option<Vec<u32>>, } #[derive(serde::Deserialize, Debug)] @@ -432,14 +436,7 @@ impl Client { )) } else { let code = res.status().as_u16(); - let error_res: ConnectErrorRes = res.json_with_path().await?; - if error_res.error_model.message - == "Username or password is incorrect. Try again" - { - Err(Error::IncorrectPassword) - } else { - Err(Error::RequestFailed { status: code }) - } + Err(classify_login_error(&res.json_with_path().await?, code)) } } @@ -862,3 +859,42 @@ impl Client { format!("{}{}", self.identity_url, path) } } + +fn classify_login_error(error_res: &ConnectErrorRes, code: u16) -> Error { + match error_res.error.as_str() { + "invalid_grant" => match error_res.error_description.as_str() { + "invalid_username_or_password" => { + return Error::IncorrectPassword; + } + "Two factor required." => { + match error_res.two_factor_providers.as_ref() { + Some(providers) => { + return Error::TwoFactorRequired { + providers: providers.clone(), + }; + } + _ => {} + } + } + _ => {} + }, + "" => { + // bitwarden_rs returns an empty error and error_description for + // this case, for some reason + if error_res.error_description == "" { + if let Some(error_model) = error_res.error_model.as_ref() { + match error_model.message.as_str() { + "Username or password is incorrect. Try again" => { + return Error::IncorrectPassword; + } + _ => {} + } + } + } + } + _ => {} + } + + log::warn!("unexpected error received during login: {:?}", error_res); + Error::RequestFailed { status: code } +} diff --git a/src/error.rs b/src/error.rs index 3030079..ea57665 100644 --- a/src/error.rs +++ b/src/error.rs @@ -156,6 +156,9 @@ pub enum Error { #[snafu(display("error spawning pinentry"))] Spawn { source: tokio::io::Error }, + #[snafu(display("two factor required"))] + TwoFactorRequired { providers: Vec<u32> }, + #[snafu(display("error writing to pinentry stdin"))] WriteStdin { source: tokio::io::Error }, } |