summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-10-01 21:18:01 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-10-01 21:18:01 -0300
commit4bba94686852e0973de4a711ed7cb477bfd123b1 (patch)
tree1835222385dd9bc98b092769a8c0052c98464d4e
parentfb69385fbc9c999c5ac5301830d08f67192cef2e (diff)
parentefe7471e22a2fe2f7ea3da9bbb2d5bac5218f2c1 (diff)
downloadmullvadvpn-4bba94686852e0973de4a711ed7cb477bfd123b1.tar.xz
mullvadvpn-4bba94686852e0973de4a711ed7cb477bfd123b1.zip
Merge branch 'login-on-api-error'
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.lock1
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/LoginFragment.kt14
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt4
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt8
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/GetAccountDataResult.kt8
-rw-r--r--mullvad-jni/Cargo.toml1
-rw-r--r--mullvad-jni/src/into_java.rs42
-rw-r--r--mullvad-jni/src/lib.rs21
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",
+ &parameters,
+ )
+ .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]