From 97ff21c74619269a8c7dc9d8ff1485200db58d8c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 9 Oct 2017 15:22:23 +0200 Subject: #8758 fix switching providers --- app/build.gradle | 5 ++ .../main/java/se/leap/bitmaskclient/eip/EIP.java | 1 + .../se/leap/bitmaskclient/eip/GatewaysManager.java | 11 ++- .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 2 +- .../test/java/se/leap/bitmaskclient/TestUtils.java | 26 +++++++ .../bitmaskclient/eip/GatewaysManagerTest.java | 84 ++++++++++++++++++++++ .../test/resources/eip-service-one-gateway.json | 42 +++++++++++ .../test/resources/eip-service-two-gateways.json | 69 ++++++++++++++++++ app/src/test/resources/secrets.json | 1 + 9 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 app/src/test/java/se/leap/bitmaskclient/TestUtils.java create mode 100644 app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java create mode 100644 app/src/test/resources/eip-service-one-gateway.json create mode 100644 app/src/test/resources/eip-service-two-gateways.json create mode 100644 app/src/test/resources/secrets.json (limited to 'app') diff --git a/app/build.gradle b/app/build.gradle index 97ce9c35..2614c6fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,12 +43,17 @@ android { debug { assets.srcDirs = ['src/debug/assets'] } + test { + resources.srcDirs += ['src/test/resources'] + } } } dependencies { + testCompile 'org.mockito:mockito-core:2.6.3' androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4' testCompile 'junit:junit:4.12' + testCompile 'org.json:json:20170516' compile 'com.jakewharton:butterknife:6.1.0' provided 'com.squareup.dagger:dagger-compiler:1.2.2' compile 'com.github.pedrovgs:renderers:1.5' diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 5b72a4e7..eb83814a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -170,6 +170,7 @@ public final class EIP extends IntentService { } private void updateGateways() { + gateways_manager.clearGatewaysAndProfiles(); gateways_manager.fromEipServiceJson(eip_definition); gatewaysToPreferences(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java index f41049c5..6a7e3d0b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -143,15 +143,20 @@ public class GatewaysManager { return result; } + protected void clearGatewaysAndProfiles() { + gateways.clear(); + ArrayList profiles = new ArrayList<>(profile_manager.getProfiles()); + for (VpnProfile profile : profiles) { + profile_manager.removeProfile(context, profile); + } + } + private void addGateway(Gateway gateway) { removeDuplicatedGateway(gateway); - gateways.add(gateway); VpnProfile profile = gateway.getProfile(); profile_manager.addProfile(profile); - //profile_manager.saveProfile(context, profile); - //profile_manager.saveProfileList(context); } private void removeDuplicatedGateway(Gateway gateway) { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java index 0b9c5832..10a95dfb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -56,7 +56,7 @@ public class VpnConfigGenerator { String key = keys.next().toString(); common_options += key + " "; - for (String word : general_configuration.getString(key).split(" ")) + for (String word : String.valueOf(general_configuration.get(key)).split(" ")) common_options += word + " "; common_options += new_line; diff --git a/app/src/test/java/se/leap/bitmaskclient/TestUtils.java b/app/src/test/java/se/leap/bitmaskclient/TestUtils.java new file mode 100644 index 00000000..96b11df6 --- /dev/null +++ b/app/src/test/java/se/leap/bitmaskclient/TestUtils.java @@ -0,0 +1,26 @@ +package se.leap.bitmaskclient; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * Created by cyberta on 08.10.17. + */ + +public class TestUtils { + + public static String getInputAsString(InputStream fileAsInputStream) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(fileAsInputStream)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + while (line != null) { + sb.append(line); + line = br.readLine(); + } + + return sb.toString(); + } + +} diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java new file mode 100644 index 00000000..e6a67392 --- /dev/null +++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java @@ -0,0 +1,84 @@ +package se.leap.bitmaskclient.eip; + +import android.content.Context; +import android.content.SharedPreferences; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.IOException; + +import se.leap.bitmaskclient.Provider; +import se.leap.bitmaskclient.TestUtils; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * Created by cyberta on 09.10.17. + */ +@RunWith(MockitoJUnitRunner.class) +public class GatewaysManagerTest { + + private GatewaysManager gatewaysManager; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mockContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private SharedPreferences sharedPreferences; + + @Before + public void setUp() throws IOException, JSONException { + + + JSONObject secrets = new JSONObject(getJsonStringFor("secrets.json")); + + when(sharedPreferences.getString(eq(Constants.PRIVATE_KEY), anyString())).thenReturn(secrets.getString(Constants.PRIVATE_KEY)); + when(sharedPreferences.getString(eq(Provider.CA_CERT), anyString())).thenReturn(secrets.getString(Provider.CA_CERT)); + when(sharedPreferences.getString(eq(Constants.CERTIFICATE), anyString())).thenReturn(secrets.getString(Constants.CERTIFICATE)); + when(mockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPreferences); + + + gatewaysManager = new GatewaysManager(mockContext, sharedPreferences); + } + + @Test + public void testFromEipServiceJson_emptyJson() throws Exception { + gatewaysManager.fromEipServiceJson(new JSONObject()); + assertEquals(0, gatewaysManager.size()); + } + + + @Test + public void testFromEipServiceJson_ignoreDuplicateGateways() throws Exception { + String eipServiceJson = TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-two-gateways.json")); + gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson)); + assertEquals(2, gatewaysManager.size()); + eipServiceJson = TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-one-gateway.json")); + gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson)); + assertEquals(2, gatewaysManager.size()); + } + + @Test + public void testClearGatewaysAndProfiles_resetGateways() throws Exception { + String eipServiceJson = TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-two-gateways.json")); + gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson)); + assertEquals(2, gatewaysManager.size()); + gatewaysManager.clearGatewaysAndProfiles(); + assertEquals(0, gatewaysManager.size()); + } + + private String getJsonStringFor(String filename) throws IOException { + return TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream(filename)); + } + +} \ No newline at end of file diff --git a/app/src/test/resources/eip-service-one-gateway.json b/app/src/test/resources/eip-service-one-gateway.json new file mode 100644 index 00000000..adf4ba18 --- /dev/null +++ b/app/src/test/resources/eip-service-one-gateway.json @@ -0,0 +1,42 @@ +{ + "gateways": [ + { + "capabilities": { + "adblock": false, + "filter_dns": false, + "limited": false, + "ports": [ + "443" + ], + "protocols": [ + "tcp", + "udp" + ], + "transport": [ + "openvpn" + ], + "user_ips": false + }, + "host": "millipede.demo.bitmask.net", + "ip_address": "198.252.153.84", + "location": "seattle__wa" + } + ], + "locations": { + "seattle__wa": { + "country_code": "US", + "hemisphere": "N", + "name": "Seattle, WA", + "timezone": "-7" + } + }, + "openvpn_configuration": { + "auth": "SHA1", + "cipher": "AES-128-CBC", + "keepalive": "10 30", + "tls-cipher": "DHE-RSA-AES128-SHA", + "tun-ipv6": true + }, + "serial": 1, + "version": 1 +} \ No newline at end of file diff --git a/app/src/test/resources/eip-service-two-gateways.json b/app/src/test/resources/eip-service-two-gateways.json new file mode 100644 index 00000000..78b49bae --- /dev/null +++ b/app/src/test/resources/eip-service-two-gateways.json @@ -0,0 +1,69 @@ +{ + "gateways": [ + { + "capabilities": { + "adblock": false, + "filter_dns": false, + "limited": false, + "ports": [ + "443" + ], + "protocols": [ + "tcp", + "udp" + ], + "transport": [ + "openvpn" + ], + "user_ips": false + }, + "host": "millipede.demo.bitmask.net", + "ip_address": "198.252.153.84", + "location": "seattle__wa" + }, + { + "capabilities": { + "adblock": false, + "filter_dns": false, + "limited": false, + "ports": [ + "443" + ], + "protocols": [ + "tcp", + "udp" + ], + "transport": [ + "openvpn" + ], + "user_ips": false + }, + "host": "otter.demo.bitmask.net", + "ip_address": "46.165.242.169", + "location": "frankfurt" + } + ], + "locations": { + "frankfurt": { + "country_code": "DE", + "hemisphere": "N", + "name": "Frankfurt", + "timezone": "+1" + }, + "seattle__wa": { + "country_code": "US", + "hemisphere": "N", + "name": "Seattle, WA", + "timezone": "-7" + } + }, + "openvpn_configuration": { + "auth": "SHA1", + "cipher": "AES-128-CBC", + "keepalive": "10 30", + "tls-cipher": "DHE-RSA-AES128-SHA", + "tun-ipv6": true + }, + "serial": 1, + "version": 1 +} \ No newline at end of file diff --git a/app/src/test/resources/secrets.json b/app/src/test/resources/secrets.json new file mode 100644 index 00000000..36ba5977 --- /dev/null +++ b/app/src/test/resources/secrets.json @@ -0,0 +1 @@ +{"ca_cert":"-----BEGIN CERTIFICATE-----\nMIIFbzCCA1egAwIBAgIBATANBgkqhkiG9w0BAQ0FADBKMRgwFgYDVQQDDA9CaXRt\nYXNrIFJvb3QgQ0ExEDAOBgNVBAoMB0JpdG1hc2sxHDAaBgNVBAsME2h0dHBzOi8v\nYml0bWFzay5uZXQwHhcNMTIxMTA2MDAwMDAwWhcNMjIxMTA2MDAwMDAwWjBKMRgw\nFgYDVQQDDA9CaXRtYXNrIFJvb3QgQ0ExEDAOBgNVBAoMB0JpdG1hc2sxHDAaBgNV\nBAsME2h0dHBzOi8vYml0bWFzay5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\nggIKAoICAQC1eV4YvayaU+maJbWrD4OHo3d7S1BtDlcvkIRS1Fw3iYDjsyDkZxai\ndHp4EUasfNQ+EVtXUvtk6170EmLco6Elg8SJBQ27trE6nielPRPCfX3fQzETRfvB\n7tNvGw4Jn2YKiYoMD79kkjgyZjkJ2r\/bEHUSevmR09BRp86syHZerdNGpXYhcQ84\nCA1+V+603GFIHnrP+uQDdssW93rgDNYu+exT+Wj6STfnUkugyjmPRPjL7wh0tzy+\nznCeLl4xiV3g9sjPnc7r2EQKd5uaTe3j71sDPF92KRk0SSUndREz+B1+Dbe\/RGk4\nMEqGFuOzrtsgEhPIX0hplhb0Tgz\/rtug+yTT7oJjBa3u20AAOQ38\/M99EfdeJvc4\nlPFF1XBBLh6X9UKF72an2NuANiX6XPySnJgZ7nZ09RiYZqVwu\/qt3DfvLfhboq+0\nbQvLUPXrVDr70onv5UDjpmEA\/cLmaIqqrduuTkFZOym65\/PfAPvpGnt7crQj\/Ibl\nDEDYZQmP7AS+6zBjoOzNjUGE5r40zWAR1RSi7zliXTu+yfsjXUIhUAWmYR6J3KxB\nlfsiHBQ+8dn9kC3YrUexWoOqBiqJOAJzZh5Y1tqgzfh+2nmHSB2dsQRs7rDRRlyy\nYMbkpzL9ZsOUO2eTP1mmar6YjCN+rggYjRrX71K2SpBG6b1zZxOG+wIDAQABo2Aw\nXjAdBgNVHQ4EFgQUuYGDLL2sswnYpHHvProt1JU+D48wDgYDVR0PAQH\/BAQDAgIE\nMAwGA1UdEwQFMAMBAf8wHwYDVR0jBBgwFoAUuYGDLL2sswnYpHHvProt1JU+D48w\nDQYJKoZIhvcNAQENBQADggIBADeG67vaFcbITGpi51264kHPYPEWaXUa5XYbtmBl\ncXYyB6hY5hv\/YNuVGJ1gWsDmdeXEyj0j2icGQjYdHRfwhrbEri+h1EZOm1cSBDuY\nk\/P5+ctHyOXx8IE79DBsZ6IL61UKIaKhqZBfLGYcWu17DVV6+LT+AKtHhOrv3TSj\nRnAcKnCbKqXLhUPXpK0eTjPYS2zQGQGIhIy9sQXVXJJJsGrPgMxna1Xw2JikBOCG\nhtD\/JKwt6xBmNwktH0GI\/LVtVgSp82Clbn9C4eZN9E5YbVYjLkIEDhpByeC71QhX\nEIQ0ZR56bFuJA\/CwValBqV\/G9gscTPQqd+iETp8yrFpAVHOW+YzSFbxjTEkBte1J\naF0vmbqdMAWLk+LEFPQRptZh0B88igtx6tV5oVd+p5IVRM49poLhuPNJGPvMj99l\nmlZ4+AeRUnbOOeAEuvpLJbel4rhwFzmUiGoeTVoPZyMevWcVFq6BMkS+jRR2w0jK\nG6b0v5XDHlcFYPOgUrtsOBFJVwbutLvxdk6q37kIFnWCd8L3kmES5q4wjyFK47Co\nJa8zlx64jmMZPg\/t3wWqkZgXZ14qnbyG5\/lGsj5CwVtfDljrhN0oCWK1FZaUmW3d\n69db12\/g4f6phldhxiWuGC\/W6fCW5kre7nmhshcltqAJJuU47iX+DarBFiIj816e\nyV8e\n-----END CERTIFICATE-----\n","cert":"-----BEGIN CERTIFICATE-----\nMIIEjDCCAnSgAwIBAgIQG6MBp\/cd9DlY+7cdvp3R3jANBgkqhkiG9w0BAQsFADBmMRAwDgYDVQQK\nDAdCaXRtYXNrMRwwGgYDVQQLDBNodHRwczovL2JpdG1hc2submV0MTQwMgYDVQQDDCtCaXRtYXNr\nIFJvb3QgQ0EgKGNsaWVudCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTE0MTIwNTAwMDAwMFoXDTE1\nMDMwNTAwMDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVEZDBwZDdkMzE4eTNtOHNkeXllaTFqYmZl\neDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANRNhZ4aCwdL5+OKObOKeI2rDqEwGnIr\nhL9wzo\/FXbwLfdW45Y9Mxwhh6xy2NkA1YUKCB8VNBKNXlBrGr1QriLbu1rItsJ2VVLqGluVV\/gO4\njcaPU+\/Wu0hMFKG28J\/dPvIGeNbjBWk6mxQAA5WIpRK9RTeQ88wVaGIZDDzIdivza2zpcyiPAyii\ndbkyXh7sLsKvbZB6wLrert6Y1ylR3SlkZP0LfdGAMAdkMyuXKOjgcSnUltR8HSBuZcSUlsTVM11n\nrYeGCYyPNNQ3UYatDW33UASgRDBorrmjhhKP7IW\/opdlnPk5ZrP3i0qI32\/boRe0EWZGXJvr4P3K\ndJ30uCECAwEAAaNvMG0wHQYDVR0OBBYEFK8bMVAM4GBB5sHptoIOAaIvlYueMAsGA1UdDwQEAwIH\ngDATBgNVHSUEDDAKBggrBgEFBQcDAjAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFId+E7bsWFsUWah9\nvZuPvZ7O+aJsMA0GCSqGSIb3DQEBCwUAA4ICAQAQOX81csVhvP422NKkZH7+g3npBpl+sEHedaGR\nxYPOu4HrA4TVF9h44sljRoRJyenGNdBZCXcLKHg889eePTf8Z5K3lTojp6hvwyA6tgxOMHT1kESW\nPfqnRw8mHfHJuE3g+4YNUMwggzwc\/VZATdV\/7M33sarVN9AUOHou9n9BizgCC+UnYlS+F2POumE3\nFbOhKo5uubI02MwBYlN2JVO2TBt1Q20w8wc6cU07Xi5Epp+1mkgFiOShkNtPcJmEyBWJhxDtSDOW\n2doqWYNqH2kq7B5R\/kyyfcpFJqAnBTV7xs+C5rTS1mW7LpxfdCUMbYuLCpyxpO3A\/DhAm8n47tUH\nlBtmo8Avdb8VdFpYiGBpB0o9kTFcsWFb2GkWFBduGfSEB8jUI7QtqhgZqocAKK\/cweSRV8FwyUcn\nR0prRm3QEi9fbXqEddzjSY9y\/lqWYzT7u+IOAQpKroeZ4wzgYperDNOUFuYk1rP7yuvjP2pV5rcN\nyPoBP60TPVWMRM4WJm6nTogAz2qBrFsf\/XwT\/ajzbsjT6HNB7QbRE+wkFkqspoXG5Agp7KQ8lW3L\nSKCDGOQJz7VIE85pD0tg7QEXBEw8oaRZtMjQ0Gvs25mxXAKka4wGasaWfYH6d0E+iKYcWn86V1rH\nK2ZoknT+Nno5jgjFuUR3fZseNizEfx7BteooKQ==\n-----END CERTIFICATE-----","Constants.PRIVATE_KEY":"-----BEGIN RSA PRIVATE KEY-----\nMIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDUTYWeGgsHS+fjijmziniNqw6h\nMBpyK4S\/cM6PxV28C33VuOWPTMcIYesctjZANWFCggfFTQSjV5Qaxq9UK4i27tayLbCdlVS6hpbl\nVf4DuI3Gj1Pv1rtITBShtvCf3T7yBnjW4wVpOpsUAAOViKUSvUU3kPPMFWhiGQw8yHYr82ts6XMo\njwMoonW5Ml4e7C7Cr22QesC63q7emNcpUd0pZGT9C33RgDAHZDMrlyjo4HEp1JbUfB0gbmXElJbE\n1TNdZ62HhgmMjzTUN1GGrQ1t91AEoEQwaK65o4YSj+yFv6KXZZz5OWaz94tKiN9v26EXtBFmRlyb\n6+D9ynSd9LghAgMBAAECggEBANPHLRXkhsHVj1EkzqBx7gXr8CEMmiTvknFh9zvltrZhhDoRQjWr\nchPDkcRHY2Cznvy4N0YyqQDD2ULIlZdSAgPxxothFoBruWSD47yMBmLx08ORsDpcqt\/YvPAATJI8\nIpFNsXcyaXBp\/M57oRemgnxp\/8UJPJmFdWX99H4hvffh\/jdj7POgYiWUaAl37XTYZKZ4nzKU2wpL\nEDLj9RKPz9gG7CYp2zrLC9LaAsrXVrKwPBw6g+XwbClaqFj97db3mrY4lr6mTo89qmus1AU+fBDH\n3Xlpmc8JwB+30TvhRNKrpLx9cEjuEj7K1gm8Y4dWCjPi+lNbtAyUBcgPJFa\/81ECgYEA7pLoBU\/Y\nZYjyHFca8FvDBcBh6haHfqJr9doXWtgjDrbi3o2n5wHqfKhFWOH6vPEQozkOVeX1ze6HOiRmGBpW\nr+r7x8TD25L7I6HJw3M351RWOAfkF0w\/RTVdetcTgduQtfN1u6BDhYSVceXMjyQYx7MhfETWI8Gh\nKSYm8OEDYiUCgYEA489fmbrCcUnXzpTsbswJ5NmSoEXbcX8cLxnQuzE0z9GHhQdrMjOpXR76reTW\n6jcuudarNcwRUYSWWhjCDKHhpx4HhasWPaHgr7jIzcRw8yZSJRSxKr8sl1qh6g7s47JcmfXOMWLt\nyuyE933XrT19Th4ODZHY40Uv35mPjMi9d00CgYEAyRNAQtndBRa7GG\/B4Ls2T+6pl+aNJIo4e+no\nrURlp800wWabEPRocdBRQmyULBLxduBr2LIMzhgwGSz8b2wji\/l9ZA3PFY135bxClVzSzUIjuO3N\nrGUzHl2wAAyuAFDSUshzfkPBJRNt8aVBF5PQ3t93ZYmPAmv8LPZe875yX5ECgYEAsUEcwK\/ZNW7g\ndQPZR4iJNkC4Xu6cBZ6Cnn92swBheEYvLSoNlX0vDZ7aLE3\/jzQqrjzC8NP8sbH5jtbuvgeDXZX3\nAmGRp5j6C6A61ihAPmEVz3ZfN8SSfJ3vl\/\/PAIg6lyz0J+cy4Q7RkwSeuVQ72Hl4M8TEvmmKC3Af\nispy6Y0CgYEAgl1o2lo+ACyk+oVQPaaPqK3d7WOBFp4eR2nXFor\/vsx9igQOlZUgzRDQsR8jo1o9\nefOSBf87igrZGgssys89pWa2dnXnz5PMmzkKr6bw4D9Ez6u6Puc9UZhGw\/8wDYg6fSosdB9utspm\nM698ycef7jBNMDgmhpSvfw5GctoNQ4s=\n-----END RSA PRIVATE KEY-----"} -- cgit v1.2.3