diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2018-10-15 16:07:21 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2018-10-23 10:44:05 +0100 |
| commit | c0632541d77a22e543d1549e5569a25c4d040d7e (patch) | |
| tree | 9e5f27c603d6a0d75fede50a608d59613aa8515a | |
| parent | bef533403920cfc08a9f705cbbc1b5c27f6e6517 (diff) | |
| download | mullvadvpn-c0632541d77a22e543d1549e5569a25c4d040d7e.tar.xz mullvadvpn-c0632541d77a22e543d1549e5569a25c4d040d7e.zip | |
Added auth_failed module to mullvad-types
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | mullvad-types/Cargo.toml | 2 | ||||
| -rw-r--r-- | mullvad-types/src/auth_failed.rs | 103 | ||||
| -rw-r--r-- | mullvad-types/src/lib.rs | 6 |
4 files changed, 113 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock index fb18677e07..b518ba0a83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1044,8 +1044,10 @@ version = "0.1.0" dependencies = [ "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "mullvad-paths 0.1.0", + "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/mullvad-types/Cargo.toml b/mullvad-types/Cargo.toml index 74d5645859..0f67cb1eb7 100644 --- a/mullvad-types/Cargo.toml +++ b/mullvad-types/Cargo.toml @@ -12,6 +12,8 @@ serde = "1.0" serde_json = "1.0" error-chain = "0.12" log = "0.4" +regex = "1" +lazy_static = "1.1.0" talpid-types = { path = "../talpid-types" } mullvad-paths = { path = "../mullvad-paths" } diff --git a/mullvad-types/src/auth_failed.rs b/mullvad-types/src/auth_failed.rs new file mode 100644 index 0000000000..d53de2d136 --- /dev/null +++ b/mullvad-types/src/auth_failed.rs @@ -0,0 +1,103 @@ +use regex::Regex; + +#[derive(Debug)] +pub struct AuthFailed { + reason: AuthFailedInner, +} + +#[derive(Debug)] +enum AuthFailedInner { + InvalidAccount, + ExpiredAccount, + TooManyConnectons, + Unknown(String, String), +} + +// These strings should match up with gui/packages/desktop/src/renderer/lib/auth-failure.js +const INVALID_ACCOUNT_MSG: &str = "You've logged in with an account number that is not valid. Please log out and try another one."; +const EXPIRED_ACCOUNT_MSG: &str = "You have no more VPN time left on this account. Please log in on our website to buy more credit."; +const TOO_MANY_CONNECTIONS_MSG: &str = "This account has too many simultaneous connections. Disconnect another device or try connecting again shortly."; + +impl AuthFailedInner { + fn from_str(input: &str) -> AuthFailedInner { + use self::AuthFailedInner::*; + match parse_string(input) { + Some(("INVALID_ACCOUNT", _)) => InvalidAccount, + Some(("EXPIRED_ACCOUNT", _)) => ExpiredAccount, + Some(("TOO_MANY_CONNECTIONS", _)) => TooManyConnectons, + Some((unknown_reason, message)) => { + warn!( + "Received AUTH_FAILED message with unknown reason: {}", + input + ); + Unknown(unknown_reason.to_string(), message.to_string()) + } + None => { + warn!("Received invalid AUTH_FAILED message: {}", input); + Unknown("UNKNOWN".to_string(), input.to_string()) + } + } + } +} + +impl AuthFailed { + pub fn from_str(reason: &str) -> AuthFailed { + AuthFailed { + reason: AuthFailedInner::from_str(reason), + } + } +} + +impl ::std::fmt::Display for AuthFailed { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + use self::AuthFailedInner::*; + match self.reason { + InvalidAccount => write!(f, "{}", INVALID_ACCOUNT_MSG), + ExpiredAccount => write!(f, "{}", EXPIRED_ACCOUNT_MSG), + TooManyConnectons => write!(f, "{}", TOO_MANY_CONNECTIONS_MSG), + Unknown(_, ref reason) => write!(f, "{}", reason), + } + } +} + +// Expects to take a string like "[INVALID_ACCOUNT] This is not a valid Mullvad account". +// The example input string would be split into: +// * "INVALID_ACCOUNT" - the ID of the failure reason. +// * "This is not a valid Mullvad account" - the human readable message of the failure reason. +// In the case that the message has preceeding whitespace, it will be trimmed. +fn parse_string<'a>(reason: &'a str) -> Option<(&'a str, &'a str)> { + lazy_static! { + static ref REASON_REGEX: Regex = Regex::new(r"^\[(\w+)\]\s*(.*)$").unwrap(); + } + let captures = REASON_REGEX.captures(reason)?; + let reason = captures.get(1).map(|m| m.as_str())?; + let message = captures.get(2).map(|m| m.as_str())?; + Some((reason, message)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parsing() { + let tests = vec![ + (Some(("INVALID_ACCOUNT", "This is not a valid Mullvad account" )), + "[INVALID_ACCOUNT] This is not a valid Mullvad account"), + (Some(("EXPIRED_ACCOUNT", "This account has no time left")), + "[EXPIRED_ACCOUNT] This account has no time left"), + (Some(("TOO_MANY_CONNECTIONS", "This Mullvad account is already used by the maximum number of simultaneous connections")), + "[TOO_MANY_CONNECTIONS] This Mullvad account is already used by the maximum number of simultaneous connections"), + (None, "[Incomplete String"), + (Some(("REASON_REASON", "")), "[REASON_REASON]"), + (Some(("REASON_REASON", "A")), "[REASON_REASON]A"), + (None, "incomplete]"), + (None, ""), + ]; + + for (expected_output, input) in tests.iter() { + assert_eq!(*expected_output, parse_string(input)); + } + } + +} diff --git a/mullvad-types/src/lib.rs b/mullvad-types/src/lib.rs index ff7628b9ad..749da41353 100644 --- a/mullvad-types/src/lib.rs +++ b/mullvad-types/src/lib.rs @@ -7,6 +7,7 @@ //! the License, or (at your option) any later version. extern crate chrono; +extern crate regex; extern crate serde; #[macro_use] extern crate serde_derive; @@ -20,7 +21,12 @@ extern crate log; #[macro_use] extern crate error_chain; +#[macro_use] +extern crate lazy_static; + + pub mod account; +pub mod auth_failed; pub mod location; pub mod relay_constraints; pub mod relay_list; |
