aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-05-27 03:20:53 -0400
committerJesse Luehrs <doy@tozt.net>2020-05-27 03:27:16 -0400
commit6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c (patch)
tree566735e913a7e302a3d2ee3e439208752a77ac2e /src
parentbc137a1f4c7c4026effa9eec06a1f0d594d21b2a (diff)
downloadrbw-6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c.tar.gz
rbw-6f5e4bcd777670ebe0f6bc56ef04d1769bf30a1c.zip
parse login error correctly
Diffstat (limited to 'src')
-rw-r--r--src/api.rs54
-rw-r--r--src/error.rs3
2 files changed, 48 insertions, 9 deletions
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<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 },
}