From 6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 27 May 2020 03:20:53 -0400 Subject: parse login error correctly --- src/api.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++--------- src/error.rs | 3 +++ 2 files changed, 48 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/api.rs b/src/api.rs index d531836..c434069 100644 --- a/src/api.rs +++ b/src/api.rs @@ -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, + #[serde(rename = "TwoFactorProviders")] + two_factor_providers: Option>, } #[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 }, + #[snafu(display("error writing to pinentry stdin"))] WriteStdin { source: tokio::io::Error }, } -- cgit v1.2.3-54-g00ecf