diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-10-01 21:18:01 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-10-01 21:18:01 -0300 |
| commit | 4bba94686852e0973de4a711ed7cb477bfd123b1 (patch) | |
| tree | 1835222385dd9bc98b092769a8c0052c98464d4e | |
| parent | fb69385fbc9c999c5ac5301830d08f67192cef2e (diff) | |
| parent | efe7471e22a2fe2f7ea3da9bbb2d5bac5218f2c1 (diff) | |
| download | mullvadvpn-4bba94686852e0973de4a711ed7cb477bfd123b1.tar.xz mullvadvpn-4bba94686852e0973de4a711ed7cb477bfd123b1.zip | |
Merge branch 'login-on-api-error'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/LoginFragment.kt | 14 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt | 4 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt | 8 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/model/GetAccountDataResult.kt | 8 | ||||
| -rw-r--r-- | mullvad-jni/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-jni/src/into_java.rs | 42 | ||||
| -rw-r--r-- | mullvad-jni/src/lib.rs | 21 |
9 files changed, 81 insertions, 19 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b8ba3c91b..4a28bf39b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Line wrap the file at 100 chars. Th #### Android - Add settings button in launch and login screens. - Add support for Android Lollipop. +- Allow logging in without connectivity. ### Removed - Remove support for `MULLVAD_LOCALE` environment variable. diff --git a/Cargo.lock b/Cargo.lock index 0c28150f5f..efa201d429 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1287,6 +1287,7 @@ dependencies = [ "ipnetwork 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/LoginFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/LoginFragment.kt index 5561043791..21d1713b6f 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/LoginFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/LoginFragment.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import net.mullvad.mullvadvpn.model.GetAccountDataResult class LoginFragment : Fragment() { private lateinit var parentActivity: MainActivity @@ -99,13 +100,14 @@ class LoginFragment : Fragment() { loginJob?.cancel() loginJob = GlobalScope.async(Dispatchers.Default) { val daemon = parentActivity.daemon.await() - val accountData = daemon.getAccountData(accountToken) + val accountDataResult = daemon.getAccountData(accountToken) - if (accountData != null) { - daemon.setAccount(accountToken) - true - } else { - false + when (accountDataResult) { + is GetAccountDataResult.Ok, is GetAccountDataResult.RpcError -> { + daemon.setAccount(accountToken) + true + } + else -> false } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt index a906b9a9c9..fe1ba2bc71 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt @@ -1,8 +1,8 @@ package net.mullvad.mullvadvpn -import net.mullvad.mullvadvpn.model.AccountData import net.mullvad.mullvadvpn.model.AppVersionInfo import net.mullvad.mullvadvpn.model.GeoIpLocation +import net.mullvad.mullvadvpn.model.GetAccountDataResult import net.mullvad.mullvadvpn.model.KeygenEvent import net.mullvad.mullvadvpn.model.PublicKey import net.mullvad.mullvadvpn.model.RelayList @@ -28,7 +28,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { external fun connect() external fun disconnect() external fun generateWireguardKey(): KeygenEvent? - external fun getAccountData(accountToken: String): AccountData? + external fun getAccountData(accountToken: String): GetAccountDataResult external fun getCurrentLocation(): GeoIpLocation? external fun getCurrentVersion(): String external fun getRelayLocations(): RelayList diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt index 8494d8ff82..5a08abefc1 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.MullvadDaemon +import net.mullvad.mullvadvpn.model.GetAccountDataResult import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat @@ -54,7 +55,12 @@ class AccountCache(val settingsListener: SettingsListener, val daemon: Deferred< private fun fetchAccountExpiry() = GlobalScope.launch(Dispatchers.Default) { val accountNumber = this@AccountCache.accountNumber val accountData = accountNumber?.let { account -> - daemon.await().getAccountData(account) + val result = daemon.await().getAccountData(account) + + when (result) { + is GetAccountDataResult.Ok -> result.accountData + else -> null + } } synchronized(this@AccountCache) { diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/GetAccountDataResult.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/GetAccountDataResult.kt new file mode 100644 index 0000000000..386288676f --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/GetAccountDataResult.kt @@ -0,0 +1,8 @@ +package net.mullvad.mullvadvpn.model + +sealed class GetAccountDataResult { + class Ok(val accountData: AccountData) : GetAccountDataResult() + class InvalidAccount : GetAccountDataResult() + class RpcError : GetAccountDataResult() + class OtherError : GetAccountDataResult() +} diff --git a/mullvad-jni/Cargo.toml b/mullvad-jni/Cargo.toml index ba264c99fa..30b26af6fe 100644 --- a/mullvad-jni/Cargo.toml +++ b/mullvad-jni/Cargo.toml @@ -15,6 +15,7 @@ futures = "0.1" ipnetwork = "0.15" jni = "0.13" jsonrpc-client-core = "0.5" +jsonrpc-core = "8" lazy_static = "1" log = "0.4" log-panics = "2" diff --git a/mullvad-jni/src/into_java.rs b/mullvad-jni/src/into_java.rs index ac2e1e73dc..a013f98d30 100644 --- a/mullvad-jni/src/into_java.rs +++ b/mullvad-jni/src/into_java.rs @@ -1,4 +1,4 @@ -use crate::get_class; +use crate::{daemon_interface, get_class}; use ipnetwork::IpNetwork; use jni::{ objects::{JList, JObject, JString, JValue}, @@ -774,3 +774,43 @@ impl<'env> IntoJava<'env> for TunnelState { .expect("Failed to create TunnelState sub-class variant Java object") } } + +impl<'env> IntoJava<'env> for Result<AccountData, daemon_interface::Error> { + type JavaType = JObject<'env>; + + fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType { + match self { + Ok(data) => { + let class = get_class("net/mullvad/mullvadvpn/model/GetAccountDataResult$Ok"); + let java_account_data = env.auto_local(data.into_java(&env)); + let parameters = [JValue::Object(java_account_data.as_obj())]; + + env.new_object( + &class, + "(Lnet/mullvad/mullvadvpn/model/AccountData;)V", + ¶meters, + ) + .expect("Failed to create GetAccountDataResult.Ok Java object") + } + Err(error) => { + let class_name = match error { + daemon_interface::Error::RpcError(jsonrpc_client_core::Error( + jsonrpc_client_core::ErrorKind::JsonRpcError(jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(-200), + .. + }), + _, + )) => "net/mullvad/mullvadvpn/model/GetAccountDataResult$InvalidAccount", + daemon_interface::Error::RpcError(_) => { + "net/mullvad/mullvadvpn/model/GetAccountDataResult$RpcError" + } + _ => "net/mullvad/mullvadvpn/model/GetAccountDataResult$OtherError", + }; + let class = get_class(class_name); + + env.new_object(&class, "()V", &[]) + .expect("Failed to create a GetAccountDataResult error sub-class Java object") + } + } + } +} diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index 2899da982c..c1d85a5a6c 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -51,6 +51,10 @@ const CLASSES_TO_LOAD: &[&str] = &[ "net/mullvad/mullvadvpn/model/Constraint$Only", "net/mullvad/mullvadvpn/model/Endpoint", "net/mullvad/mullvadvpn/model/GeoIpLocation", + "net/mullvad/mullvadvpn/model/GetAccountDataResult$Ok", + "net/mullvad/mullvadvpn/model/GetAccountDataResult$InvalidAccount", + "net/mullvad/mullvadvpn/model/GetAccountDataResult$RpcError", + "net/mullvad/mullvadvpn/model/GetAccountDataResult$OtherError", "net/mullvad/mullvadvpn/model/InetNetwork", "net/mullvad/mullvadvpn/model/KeygenEvent$NewKey", "net/mullvad/mullvadvpn/model/KeygenEvent$Failure", @@ -310,17 +314,16 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getAccountData< accountToken: JString, ) -> JObject<'env> { let account = String::from_java(&env, accountToken); + let result = DAEMON_INTERFACE.get_account_data(account); - match DAEMON_INTERFACE.get_account_data(account) { - Ok(data) => data.into_java(&env), - Err(error) => { - log::error!( - "{}", - error.display_chain_with_msg("Failed to get account data") - ); - JObject::null() - } + if let Err(ref error) = &result { + log::error!( + "{}", + error.display_chain_with_msg("Failed to get account data") + ); } + + result.into_java(&env) } #[no_mangle] |
