From 5ea927f89626cef98495b5fead628cdc01d2a39a Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 12 Jul 2019 13:28:36 +0200 Subject: replace 'Bitmask' in strings with variable for a better client customization --- .../se/leap/bitmaskclient/ProviderApiManager.java | 10 +++++-- .../java/de/blinkt/openvpn/core/VpnStatus.java | 4 +++ .../leap/bitmaskclient/OkHttpClientGenerator.java | 6 ++-- .../leap/bitmaskclient/ProviderApiManagerBase.java | 10 ++++--- .../se/leap/bitmaskclient/eip/VoidVpnService.java | 8 ++++-- .../se/leap/bitmaskclient/utils/ConfigHelper.java | 8 ++++++ app/src/main/res/values/strings.xml | 23 +++++---------- .../se/leap/bitmaskclient/ProviderApiManager.java | 3 +- .../leap/bitmaskclient/testutils/MockHelper.java | 33 +++++++++++++--------- app/src/test/resources/error_messages.json | 12 ++++---- 10 files changed, 67 insertions(+), 50 deletions(-) diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java index 3325d82b..1190d382 100644 --- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java +++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java @@ -62,6 +62,7 @@ import static se.leap.bitmaskclient.R.string.malformed_url; import static se.leap.bitmaskclient.R.string.setup_error_text; import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert; import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details; +import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString; /** * Created by cyberta on 04.01.18. @@ -281,7 +282,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { try { // try to download with provider CA on certificate error JSONObject responseErrorJson = new JSONObject(responseString); - if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) { + if (dangerOn && responseErrorJson.getString(ERRORS).equals( + getProviderFormattedString(resources, R.string.certificate_error))) { responseString = downloadWithoutCA(stringUrl); } } catch (JSONException e) { @@ -309,7 +311,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { try { // try to download with provider CA on certificate error JSONObject responseErrorJson = new JSONObject(responseString); - if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) { + if (dangerOn && responseErrorJson.getString(ERRORS).equals( + getProviderFormattedString(resources, R.string.certificate_error))) { responseString = downloadWithCommercialCA(urlString, dangerOn); } } catch (JSONException e) { @@ -344,7 +347,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { try { // danger danger: try to download without CA on certificate error JSONObject responseErrorJson = new JSONObject(responseString); - if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) { + if (dangerOn && responseErrorJson.getString(ERRORS).equals( + getProviderFormattedString(resources, R.string.certificate_error))) { responseString = downloadWithoutCA(urlString); } } catch (JSONException e) { diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index d52ebac1..fa28a875 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -20,6 +20,8 @@ import java.util.concurrent.CopyOnWriteArrayList; import se.leap.bitmaskclient.R; +import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString; + public class VpnStatus { @@ -103,6 +105,8 @@ public class VpnStatus { if (mLastStateresid == R.string.state_waitconnectretry) { return c.getString(R.string.state_waitconnectretry, mLaststatemsg); + } else if (mLastStateresid == R.string.void_vpn_establish) { + return getProviderFormattedString(c.getResources(), R.string.void_vpn_establish); } String prefix = c.getString(mLastStateresid); diff --git a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java index 7d1054f1..69270140 100644 --- a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java @@ -52,7 +52,7 @@ import static se.leap.bitmaskclient.R.string.error_io_exception_user_message; import static se.leap.bitmaskclient.R.string.error_no_such_algorithm_exception_user_message; import static se.leap.bitmaskclient.R.string.keyChainAccessError; import static se.leap.bitmaskclient.R.string.server_unreachable_message; -import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert; +import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString; /** * Created by cyberta on 08.01.18. @@ -92,7 +92,7 @@ public class OkHttpClientGenerator { } catch (IllegalArgumentException e) { e.printStackTrace(); // TODO ca cert is invalid - show better error ?! - addErrorMessageToJson(initError, resources.getString(certificate_error)); + addErrorMessageToJson(initError, getProviderFormattedString(resources, certificate_error)); } catch (IllegalStateException | KeyManagementException | KeyStoreException e) { e.printStackTrace(); addErrorMessageToJson(initError, String.format(resources.getString(keyChainAccessError), e.getLocalizedMessage())); @@ -102,7 +102,7 @@ public class OkHttpClientGenerator { } catch (CertificateException e) { e.printStackTrace(); // TODO ca cert is invalid - show better error ?! - addErrorMessageToJson(initError, resources.getString(certificate_error)); + addErrorMessageToJson(initError, getProviderFormattedString(resources, certificate_error)); } catch (UnknownHostException e) { e.printStackTrace(); addErrorMessageToJson(initError, resources.getString(server_unreachable_message)); diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java index 15c7457e..37adbe93 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java @@ -107,6 +107,7 @@ import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert; import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details; import static se.leap.bitmaskclient.R.string.warning_expired_provider_cert; import static se.leap.bitmaskclient.utils.ConfigHelper.getFingerprintFromCertificate; +import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString; import static se.leap.bitmaskclient.utils.ConfigHelper.parseRsaKeyFromString; import static se.leap.bitmaskclient.utils.PreferenceHelper.deleteProviderDetailsFromPreferences; import static se.leap.bitmaskclient.utils.PreferenceHelper.getFromPersistedProvider; @@ -237,8 +238,8 @@ public abstract class ProviderApiManagerBase { deleteProviderDetailsFromPreferences(preferences, provider.getDomain()); } - String formatErrorMessage(final int toastStringId) { - return formatErrorMessage(resources.getString(toastStringId)); + String formatErrorMessage(final int errorStringId) { + return formatErrorMessage(getProviderFormattedString(resources, errorStringId)); } private String formatErrorMessage(String errorMessage) { @@ -751,10 +752,11 @@ public abstract class ProviderApiManagerBase { Bundle setErrorResult(Bundle result, int errorMessageId, String errorId) { JSONObject errorJson = new JSONObject(); + String errorMessage = getProviderFormattedString(resources, errorMessageId); if (errorId != null) { - addErrorMessageToJson(errorJson, resources.getString(errorMessageId), errorId); + addErrorMessageToJson(errorJson, errorMessage, errorId); } else { - addErrorMessageToJson(errorJson, resources.getString(errorMessageId)); + addErrorMessageToJson(errorJson, errorMessage); } result.putString(ERRORS, errorJson.toString()); result.putBoolean(BROADCAST_RESULT_KEY, false); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index a896197c..f6e3df7c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -40,6 +40,7 @@ import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_BLOCKING_VPN; import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN; import static se.leap.bitmaskclient.Constants.EIP_IS_ALWAYS_ON; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString; public class VoidVpnService extends VpnService implements Observer, VpnNotificationManager.VpnServiceCallback { @@ -147,7 +148,7 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat private void establishBlockingVpn() { try { - VpnStatus.logInfo(getString(R.string.void_vpn_establish)); + VpnStatus.logInfo(getProviderFormattedString(getResources(), R.string.void_vpn_establish)); VpnStatus.updateStateString(STATE_ESTABLISH, "", R.string.void_vpn_establish, ConnectionStatus.LEVEL_BLOCKING); Builder builder = prepareBlockingVpnProfile(); @@ -180,9 +181,10 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat } if (eipStatus.isBlockingVpnEstablished()) { + String blockingMessage = getProviderFormattedString(getResources(), eipStatus.getLocalizedResId()); notificationManager.buildVoidVpnNotification( - getString(eipStatus.getLocalizedResId()), - getString(eipStatus.getLocalizedResId()), + blockingMessage, + blockingMessage, eipStatus.getLevel()); } else { notificationManager.stopNotifications(NOTIFICATION_CHANNEL_NEWSTATUS_ID); diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java index d1ac0eb3..da74c7c4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java @@ -17,8 +17,10 @@ package se.leap.bitmaskclient.utils; import android.content.Context; +import android.content.res.Resources; import android.os.Looper; import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import org.json.JSONException; import org.json.JSONObject; @@ -43,6 +45,7 @@ import java.util.Calendar; import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.ProviderAPI; +import se.leap.bitmaskclient.R; import static se.leap.bitmaskclient.Constants.DEFAULT_BITMASK; @@ -182,4 +185,9 @@ public class ConfigHelper { public static int getCurrentTimezone() { return Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; } + + public static String getProviderFormattedString(Resources resources, @StringRes int resourceId) { + String appName = resources.getString(R.string.app_name); + return resources.getString(resourceId, appName); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ba4ef949..551b7cb1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -49,11 +49,11 @@ Configuration Error Configure Exit - There was an error configuring Bitmask with your chosen provider.\n\nYou may choose to reconfigure, or exit and configure a provider upon next launch. + There was an error configuring %s with your chosen provider.\n\nYou may choose to reconfigure, or exit and configure a provider upon next launch. The server is unreachable, please try again. Security error, upgrade the app or choose another provider. - It doesn\'t seem to be a Bitmask provider. - This is not a trusted Bitmask provider. + It doesn\'t seem to be a %s provider. + This is not a trusted %s provider. The service is down. Configuring provider Your anonymous certificate was not downloaded @@ -72,29 +72,20 @@ It seems there is a problem with the provider. Please try another provider, or contact yours. Anonymous - is logged in. - logged out. - didn\'t log out. Try later, it may be a problem in the network or with the provider. Should it persist, wipe the Bitmask data from the Android settings. - have not logged in. - is logging in. Logging in Signing up - is logging out. - is being registered. Turn on Turn off Stop blocking Your traffic is securely routed through: No internet connection detected, when it comes back we\'ll route your traffic securely through: - Bitmask Log - Bitmask Log VPN Open navigation drawer Close navigation drawer Example action Settings - Bitmask blocks all outgoing internet traffic. + %s blocks all outgoing internet traffic. Failed to establish blocking VPN. Stopped blocking all outgoing internet traffic. Blocking traffic @@ -102,9 +93,9 @@ Update certificate Updating provider configuration failed. Updating provider configuration failed. Please log in to try again. - Stored provider details are corrupted. You can either update Bitmask (recommended) or update the provider details using a commercial CA certificate. - Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate. - Stored provider certificate is expired. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate. + Stored provider details are corrupted. You can either update %s (recommended) or update the provider details using a commercial CA certificate. + Stored provider certificate is invalid. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate. + Stored provider certificate is expired. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate. Downloading the VPN certificate failed. Try again or choose another provider. VPN certificate is invalid. Try to download a new one. The VPN certificate is invalid. Please log in to download a new one. diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java index 1372fc43..6d9671b1 100644 --- a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java @@ -46,6 +46,7 @@ import static se.leap.bitmaskclient.R.string.malformed_url; import static se.leap.bitmaskclient.R.string.setup_error_text; import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert; import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details; +import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString; /** * Implements the logic of the provider api http requests. The methods of this class need to be called from @@ -248,7 +249,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { try { // try to download with provider CA on certificate error JSONObject responseErrorJson = new JSONObject(responseString); - if (responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) { + if (responseErrorJson.getString(ERRORS).equals(getProviderFormattedString(resources, R.string.certificate_error))) { responseString = downloadWithProviderCA(provider.getCaCert(), stringUrl); } } catch (JSONException e) { diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java index c765ab1b..fa9f9252 100644 --- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java +++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java @@ -46,6 +46,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -373,6 +374,7 @@ public class MockHelper { when(ConfigHelper.getFingerprintFromCertificate(any(X509Certificate.class), anyString())).thenReturn(mockedFingerprint); when(ConfigHelper.checkErroneousDownload(anyString())).thenCallRealMethod(); when(ConfigHelper.parseX509CertificateFromString(anyString())).thenCallRealMethod(); + when(ConfigHelper.getProviderFormattedString(any(Resources.class), anyInt())).thenCallRealMethod(); } public static void mockPreferenceHelper(final Provider providerFromPrefs) { @@ -402,6 +404,7 @@ public class MockHelper { when(ConfigHelper.getFingerprintFromCertificate(any(X509Certificate.class), anyString())).thenReturn(mockedFingerprint); when(ConfigHelper.checkErroneousDownload(anyString())).thenCallRealMethod(); when(ConfigHelper.parseX509CertificateFromString(anyString())).thenCallRealMethod(); + when(ConfigHelper.getProviderFormattedString(any(Resources.class), anyInt())).thenCallRealMethod(); } public static void mockProviderApiConnector(final BackendMockProvider.TestBackendErrorCase errorCase) throws IOException { @@ -421,16 +424,16 @@ public class MockHelper { JSONObject errorMessages = new JSONObject(TestSetupHelper.getInputAsString(inputStream)); - when(mockedResources.getString(R.string.warning_corrupted_provider_details)). - thenReturn(errorMessages.getString("warning_corrupted_provider_details")); + when(mockedResources.getString(eq(R.string.warning_corrupted_provider_details), anyString())). + thenReturn(String.format(errorMessages.getString("warning_corrupted_provider_details"), "Bitmask")); when(mockedResources.getString(R.string.server_unreachable_message)). thenReturn(errorMessages.getString("server_unreachable_message")); when(mockedResources.getString(R.string.error_security_pinnedcertificate)). thenReturn(errorMessages.getString("error.security.pinnedcertificate")); - when(mockedResources.getString(R.string.malformed_url)). - thenReturn(errorMessages.getString("malformed_url")); - when(mockedResources.getString(R.string.certificate_error)). - thenReturn(errorMessages.getString("certificate_error")); + when(mockedResources.getString(eq(R.string.malformed_url), anyString())). + thenReturn(String.format(errorMessages.getString("malformed_url"), "Bitmask")); + when(mockedResources.getString(eq(R.string.certificate_error), anyString())). + thenReturn(String.format(errorMessages.getString("certificate_error"), "Bitmask")); when(mockedResources.getString(R.string.error_srp_math_error_user_message)). thenReturn(errorMessages.getString("error_srp_math_error_user_message")); when(mockedResources.getString(R.string.error_bad_user_password_user_message)). @@ -445,14 +448,16 @@ public class MockHelper { thenReturn(errorMessages.getString("error_json_exception_user_message")); when(mockedResources.getString(R.string.error_no_such_algorithm_exception_user_message)). thenReturn(errorMessages.getString("error_no_such_algorithm_exception_user_message")); - when(mockedResources.getString(R.string.warning_corrupted_provider_details)). - thenReturn(errorMessages.getString("warning_corrupted_provider_details")); - when(mockedResources.getString(R.string.warning_corrupted_provider_cert)). - thenReturn(errorMessages.getString("warning_corrupted_provider_cert")); - when(mockedResources.getString(R.string.warning_expired_provider_cert)). - thenReturn(errorMessages.getString("warning_expired_provider_cert")); - when(mockedResources.getString(R.string.setup_error_text)). - thenReturn(errorMessages.getString("setup_error_text")); + when(mockedResources.getString(eq(R.string.warning_corrupted_provider_details), anyString())). + thenReturn(String.format(errorMessages.getString("warning_corrupted_provider_details"), "Bitmask")); + when(mockedResources.getString(eq(R.string.warning_corrupted_provider_cert), anyString())). + thenReturn(String.format(errorMessages.getString("warning_corrupted_provider_cert"), "Bitmask")); + when(mockedResources.getString(eq(R.string.warning_expired_provider_cert), anyString())). + thenReturn(String.format(errorMessages.getString("warning_expired_provider_cert"), "Bitmask")); + when(mockedResources.getString(eq(R.string.setup_error_text), anyString())). + thenReturn(String.format(errorMessages.getString("setup_error_text"), "Bitmask")); + when(mockedResources.getString(R.string.app_name)). + thenReturn("Bitmask"); return mockedResources; } } diff --git a/app/src/test/resources/error_messages.json b/app/src/test/resources/error_messages.json index 8430d9e0..e3b92d78 100644 --- a/app/src/test/resources/error_messages.json +++ b/app/src/test/resources/error_messages.json @@ -1,8 +1,8 @@ { "server_unreachable_message": "Server is unreachable, please try again.", "error.security.pinnedcertificate": "Security error, update the app or choose another provider.", - "malformed_url": "It doesn't seem to be a Bitmask provider.", - "certificate_error": "This is not a trusted Bitmask provider.", + "malformed_url": "It doesn't seem to be a %s provider.", + "certificate_error": "This is not a trusted %s provider.", "error_srp_math_error_user_message": "Try again: server math error.", "error_bad_user_password_user_message": "Incorrect username or password.", "error_not_valid_password_user_message": "It should have at least 8 characters.", @@ -10,8 +10,8 @@ "error_io_exception_user_message": "Try again: I/O error", "error_json_exception_user_message": "Try again: Bad response from the server", "error_no_such_algorithm_exception_user_message": "Encryption algorithm not found. Please update your OS!", - "warning_corrupted_provider_details": "Stored provider details are corrupted. You can either update Bitmask (recommended) or update the provider details using a commercial CA certificate.", - "warning_corrupted_provider_cert": "Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.", - "warning_expired_provider_cert": "Stored provider certificate is expired. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.", - "setup_error_text": "There was an error configuring Bitmask with your chosen provider." + "warning_corrupted_provider_details": "Stored provider details are corrupted. You can either update %s (recommended) or update the provider details using a commercial CA certificate.", + "warning_corrupted_provider_cert": "Stored provider certificate is invalid. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.", + "warning_expired_provider_cert": "Stored provider certificate is expired. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.", + "setup_error_text": "There was an error configuring %s with your chosen provider." } \ No newline at end of file -- cgit v1.2.3