summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2024-01-25 23:37:53 +0100
committercyBerta <cyberta@riseup.net>2024-01-25 23:37:53 +0100
commit9bba7b29a416b2617af033a778ef13a512024502 (patch)
tree3370a57949d0ada3fab5fd54d42a118d9e0d5e9b
parentbe8535ff9ab0968187acd008b8c01e1b8d9c336e (diff)
refactor ProviderApiConnector, allow to inject dummy implementations for unit tests
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java134
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java13
2 files changed, 94 insertions, 53 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java
index 35ad9cd2..cc875c79 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java
@@ -18,6 +18,8 @@
package se.leap.bitmaskclient.providersetup;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+
import android.util.Pair;
import java.io.IOException;
@@ -26,6 +28,9 @@ import java.util.List;
import java.util.Locale;
import java.util.Scanner;
+import javax.net.ssl.SSLHandshakeException;
+
+import de.blinkt.openvpn.core.NativeUtils;
import de.blinkt.openvpn.core.VpnStatus;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
@@ -39,72 +44,103 @@ import okhttp3.Response;
public class ProviderApiConnector {
- private static final MediaType JSON
- = MediaType.parse("application/json; charset=utf-8");
+ public interface ProviderApiConnectorInterface {
+ boolean delete(OkHttpClient okHttpClient, String deleteUrl) throws RuntimeException, IOException;
+ boolean canConnect(@NonNull OkHttpClient okHttpClient, String url) throws RuntimeException, IOException;
+ String requestStringFromServer(@NonNull String url, @NonNull String requestMethod, String jsonString, @NonNull List<Pair<String, String>> headerArgs, @NonNull OkHttpClient okHttpClient) throws RuntimeException, IOException;
+
+ }
+ public static class DefaultProviderApiCpnnector implements ProviderApiConnectorInterface {
+
+ @Override
+ public boolean delete(OkHttpClient okHttpClient, String deleteUrl) {
+ try {
+ Request.Builder requestBuilder = new Request.Builder()
+ .url(deleteUrl)
+ .delete();
+ Request request = requestBuilder.build();
+
+ Response response = okHttpClient.newCall(request).execute();
+ //response code 401: already logged out
+ if (response.isSuccessful() || response.code() == 401) {
+ return true;
+ }
+ } catch (IOException | RuntimeException e) {
+ return false;
+ }
+
+ return false;
+ }
- public static boolean delete(OkHttpClient okHttpClient, String deleteUrl) {
- try {
+ @Override
+ public boolean canConnect(@NonNull OkHttpClient okHttpClient, String url) throws RuntimeException, IOException {
Request.Builder requestBuilder = new Request.Builder()
- .url(deleteUrl)
- .delete();
+ .url(url)
+ .method("GET", null);
Request request = requestBuilder.build();
Response response = okHttpClient.newCall(request).execute();
- //response code 401: already logged out
- if (response.isSuccessful() || response.code() == 401) {
- return true;
+ if (!response.isSuccessful()) {
+ VpnStatus.logWarning("[API] API request failed canConnect(): " + url);
}
- } catch (IOException | RuntimeException e) {
- return false;
+ return response.isSuccessful();
}
- return false;
- }
+ @Override
+ public String requestStringFromServer(@NonNull String url, @NonNull String requestMethod, String jsonString, @NonNull List<Pair<String, String>> headerArgs, @NonNull OkHttpClient okHttpClient) throws RuntimeException, IOException {
+ RequestBody jsonBody = jsonString != null ? RequestBody.create(JSON, jsonString) : null;
+ Request.Builder requestBuilder = new Request.Builder()
+ .url(url)
+ .method(requestMethod, jsonBody);
+ for (Pair<String, String> keyValPair : headerArgs) {
+ requestBuilder.addHeader(keyValPair.first, keyValPair.second);
+ }
- public static boolean canConnect(@NonNull OkHttpClient okHttpClient, String url) throws RuntimeException, IOException {
- Request.Builder requestBuilder = new Request.Builder()
- .url(url)
- .method("GET", null);
- Request request = requestBuilder.build();
-
- Response response = okHttpClient.newCall(request).execute();
- if (!response.isSuccessful()) {
- VpnStatus.logWarning("[API] API request failed canConnect(): " + url);
+ //TODO: move to getHeaderArgs()?
+ String locale = Locale.getDefault().getLanguage() + Locale.getDefault().getCountry();
+ requestBuilder.addHeader("Accept-Language", locale);
+ Request request = requestBuilder.build();
+
+ Response response = okHttpClient.newCall(request).execute();
+ if (!response.isSuccessful()) {
+ VpnStatus.logWarning("[API] API request failed: " + url);
+ }
+
+ if (response.body() != null) {
+ InputStream inputStream = response.body().byteStream();
+ Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
+ if (scanner.hasNext()) {
+ String result = scanner.next();
+ response.body().close();
+ return result;
+ }
+ }
+ return null;
}
- return response.isSuccessful();
+ }
+ private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+ private static ProviderApiConnectorInterface instance = new DefaultProviderApiCpnnector();
+ @VisibleForTesting
+ public ProviderApiConnector(ProviderApiConnectorInterface connectorInterface) {
+ if (!NativeUtils.isUnitTest()) {
+ throw new IllegalStateException("ProviderApiConnector injected with ProviderApiConnectorInterface outside of an unit test");
+ }
+ instance = connectorInterface;
}
- public static String requestStringFromServer(@NonNull String url, @NonNull String request_method, String jsonString, @NonNull List<Pair<String, String>> headerArgs, @NonNull OkHttpClient okHttpClient) throws RuntimeException, IOException {
- RequestBody jsonBody = jsonString != null ? RequestBody.create(JSON, jsonString) : null;
- Request.Builder requestBuilder = new Request.Builder()
- .url(url)
- .method(request_method, jsonBody);
- for (Pair<String, String> keyValPair : headerArgs) {
- requestBuilder.addHeader(keyValPair.first, keyValPair.second);
- }
+ public static boolean delete(OkHttpClient okHttpClient, String deleteUrl) throws RuntimeException, IOException {
+ return instance.delete(okHttpClient, deleteUrl);
+ }
- //TODO: move to getHeaderArgs()?
- String locale = Locale.getDefault().getLanguage() + Locale.getDefault().getCountry();
- requestBuilder.addHeader("Accept-Language", locale);
- Request request = requestBuilder.build();
+ public static boolean canConnect(@NonNull OkHttpClient okHttpClient, String url) throws RuntimeException, IOException {
+ return instance.canConnect(okHttpClient, url);
- Response response = okHttpClient.newCall(request).execute();
- if (!response.isSuccessful()) {
- VpnStatus.logWarning("[API] API request failed: " + url);
- }
+ }
- if (response.body() != null) {
- InputStream inputStream = response.body().byteStream();
- Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
- if (scanner.hasNext()) {
- String result = scanner.next();
- response.body().close();
- return result;
- }
- }
- return null;
+ public static String requestStringFromServer(@NonNull String url, @NonNull String requestMethod, String jsonString, @NonNull List<Pair<String, String>> headerArgs, @NonNull OkHttpClient okHttpClient) throws RuntimeException, IOException {
+ return instance.requestStringFromServer(url, requestMethod, jsonString, headerArgs, okHttpClient);
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
index 05c5448a..1f737b0c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
@@ -45,6 +45,7 @@ import static se.leap.bitmaskclient.base.models.Provider.CA_CERT;
import static se.leap.bitmaskclient.base.models.Provider.GEOIP_URL;
import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_API_IP;
import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_IP;
+import static se.leap.bitmaskclient.base.utils.ConfigHelper.getTorTimeout;
import static se.leap.bitmaskclient.base.utils.RSAHelper.parseRsaKeyFromString;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.getDomainFromMainURL;
import static se.leap.bitmaskclient.base.utils.CertificateHelper.getFingerprintFromCertificate;
@@ -380,7 +381,7 @@ public abstract class ProviderApiManagerBase {
if (TorStatusObservable.getStatus() == ON) {
return;
}
- TorStatusObservable.waitUntil(this::isTorOnOrCancelled, 180);
+ TorStatusObservable.waitUntil(this::isTorOnOrCancelled, getTorTimeout());
}
private boolean isTorOnOrCancelled() {
@@ -1138,9 +1139,13 @@ public abstract class ProviderApiManagerBase {
String deleteUrl = provider.getApiUrlWithVersion() + "/logout";
- if (ProviderApiConnector.delete(okHttpClient, deleteUrl)) {
- LeapSRPSession.setToken("");
- return true;
+ try {
+ if (ProviderApiConnector.delete(okHttpClient, deleteUrl)) {
+ LeapSRPSession.setToken("");
+ return true;
+ }
+ } catch (IOException e) {
+ // eat me
}
return false;
}