diff options
8 files changed, 186 insertions, 55 deletions
| diff --git a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java index a92f8f96..d521a3a9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java @@ -21,6 +21,7 @@ import butterknife.InjectView;  import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;  import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;  import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT;  public abstract class AbstractProviderDetailActivity extends ButterKnifeActivity { @@ -83,6 +84,7 @@ public abstract class AbstractProviderDetailActivity extends ButterKnifeActivity                      } else {                          Log.d(TAG, "use anonymously selected");                          intent = new Intent(getApplicationContext(), MainActivity.class); +                        intent.setAction(ACTION_SHOW_VPN_FRAGMENT);                      }                      intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);                      startActivity(intent); diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index 0e861059..ccdf5064 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -16,6 +16,7 @@   */  package se.leap.bitmaskclient; +import android.content.SharedPreferences;  import android.support.annotation.NonNull;  import android.util.Log; @@ -28,8 +29,9 @@ import java.io.ByteArrayInputStream;  import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException;  import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL;  import java.security.KeyFactory;  import java.security.KeyStore;  import java.security.KeyStoreException; @@ -45,6 +47,7 @@ import java.security.spec.InvalidKeySpecException;  import java.security.spec.PKCS8EncodedKeySpec;  import static android.R.attr.name; +import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;  /**   * Stores constants, and implements auxiliary methods used across all Bitmask Android classes. @@ -256,4 +259,33 @@ public class ConfigHelper {      public static KeyStore getKeystore() {          return keystore_trusted;      } + + +    public static String getCurrentProviderName(@NonNull SharedPreferences preferences) { +        try { +            JSONObject providerDefintion = new JSONObject(preferences.getString(Provider.KEY, "")); +            return providerDefintion.getString(Provider.DOMAIN); +        } catch (JSONException e) { +            e.printStackTrace(); +        } +        return null; +    } + +    public static boolean providerInSharedPreferences(@NonNull SharedPreferences preferences) { +        return preferences.getBoolean(PROVIDER_CONFIGURED, false); +    } + +    public static Provider getSavedProviderFromSharedPreferences(@NonNull SharedPreferences preferences) { +        Provider provider = new Provider(); +        try { +            provider.setUrl(new URL(preferences.getString(Provider.MAIN_URL, ""))); +            provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); +            provider.setCACert(preferences.getString(Provider.CA_CERT, "")); +        } catch (MalformedURLException | JSONException e) { +            e.printStackTrace(); +        } + +        return provider; +    } +  } diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 82ff9db8..5ccb48b5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -18,7 +18,6 @@ package se.leap.bitmaskclient;  import android.annotation.SuppressLint;  import android.app.AlertDialog; -import android.content.Context;  import android.content.DialogInterface;  import android.content.Intent;  import android.content.SharedPreferences; @@ -42,8 +41,8 @@ import java.util.List;  import java.util.Map;  import butterknife.InjectView; -import se.leap.bitmaskclient.fragments.AboutFragment;  import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.fragments.AboutFragment;  import se.leap.bitmaskclient.userstatus.SessionDialog;  import se.leap.bitmaskclient.userstatus.User;  import se.leap.bitmaskclient.userstatus.UserStatusFragment; diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java index 41e496bb..40a9052c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java @@ -1,7 +1,9 @@  package se.leap.bitmaskclient; +import android.content.Intent;  import android.os.Bundle; +import android.support.v4.app.Fragment;  import android.support.v4.app.FragmentTransaction;  import android.support.v4.widget.DrawerLayout;  import android.support.v7.app.AppCompatActivity; @@ -16,6 +18,7 @@ public class MainActivity extends AppCompatActivity {      private static Provider provider = new Provider();      private static FragmentManagerEnhanced fragmentManager; +    public final static String ACTION_SHOW_VPN_FRAGMENT = "action_show_vpn_fragment";      /**       * Fragment managing the behaviors, interactions and presentation of the navigation drawer. @@ -37,6 +40,7 @@ public class MainActivity extends AppCompatActivity {                  R.id.navigation_drawer,                  (DrawerLayout) findViewById(R.id.drawer_layout)); +        handleIntentAction(getIntent());      }      public static void sessionDialog(Bundle resultData) { @@ -48,4 +52,34 @@ public class MainActivity extends AppCompatActivity {          }      } +    @Override +    protected void onNewIntent(Intent intent) { +        super.onNewIntent(intent); +        setIntent(intent); +        handleIntentAction(intent); +    } + +    private void handleIntentAction(Intent intent) { +        if (intent == null || intent.getAction() == null) { +            return; +        } + +        Fragment fragment = null; + +        switch (intent.getAction()) { +            case ACTION_SHOW_VPN_FRAGMENT: +                fragment = new VpnFragment(); +                break; +            default: +                break; +        } + +        if (fragment != null) { +            fragmentManager.beginTransaction() +                    .replace(R.id.container, fragment) +                    .commit(); +        } +    } + +  } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java index c61b078f..1ed64559 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java @@ -16,6 +16,8 @@ import butterknife.OnClick;  import se.leap.bitmaskclient.userstatus.SessionDialog;  import se.leap.bitmaskclient.userstatus.User; +import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT; +  /**   * Created by fupduck on 09.01.18.   */ @@ -109,6 +111,7 @@ public abstract class ProviderCredentialsBaseActivity extends ButterKnifeActivit                  //MainActivity.sessionDialog(resultData);              } else if (resultCode == ProviderAPI.SUCCESSFUL_LOGIN) {                  Intent intent = new Intent(activity, MainActivity.class); +                intent.setAction(ACTION_SHOW_VPN_FRAGMENT);                  activity.startActivity(intent);              } else if (resultCode == ProviderAPI.FAILED_LOGIN) {                  //MainActivity.sessionDialog(resultData); diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java index 43d7f152..bb01ddc0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java @@ -15,7 +15,9 @@ import java.lang.annotation.RetentionPolicy;  import de.blinkt.openvpn.core.VpnStatus;  import se.leap.bitmaskclient.userstatus.User; +import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE;  import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION; +import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;  import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;  /** @@ -71,9 +73,8 @@ public class StartActivity extends Activity {          VpnStatus.initLogCache(getApplicationContext().getCacheDir());          User.init(getString(R.string.default_username)); -        // go to Dashboard -        Intent intent = new Intent(this, MainActivity.class); -        startActivity(intent); +        prepareEIP(); +      }      /** @@ -141,4 +142,31 @@ public class StartActivity extends Activity {          preferences.edit().putInt(PREFERENCES_APP_VERSION, versionCode).apply();      } +    private void prepareEIP() { +        boolean provider_exists = ConfigHelper.providerInSharedPreferences(preferences); +        if (provider_exists) { +            Provider provider = ConfigHelper.getSavedProviderFromSharedPreferences(preferences); +            if(!provider.isConfigured()) { +                configureLeapProvider(); +            } else { +                Log.d(TAG, "vpn provider is configured"); + +                //buildDashboard(getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false)); +//                user_status_fragment.restoreSessionStatus(savedInstanceState); +                Intent intent = new Intent(this, MainActivity.class); +                intent.setAction(MainActivity.ACTION_SHOW_VPN_FRAGMENT); +                startActivity(intent); +            } +        } else { +            configureLeapProvider(); +        } +    } + +    private void configureLeapProvider() { +        if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { +            getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); +        } +        startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); +    } +  } diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index 84c407d7..dbe99dce 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -6,7 +6,6 @@ import android.content.Intent;  import android.content.SharedPreferences;  import android.content.res.Configuration;  import android.os.Bundle; -import android.preference.PreferenceManager;  import android.support.v4.app.Fragment;  import android.support.v4.app.FragmentManager;  import android.support.v4.view.GravityCompat; @@ -27,15 +26,14 @@ import android.widget.ArrayAdapter;  import android.widget.ListView;  import android.widget.Toast; +import se.leap.bitmaskclient.ConfigHelper;  import se.leap.bitmaskclient.ConfigurationWizard; -import se.leap.bitmaskclient.Provider;  import se.leap.bitmaskclient.R;  import se.leap.bitmaskclient.VpnFragment;  import se.leap.bitmaskclient.fragments.AboutFragment;  import se.leap.bitmaskclient.fragments.LogFragment; -import se.leap.bitmaskclient.userstatus.User; -import se.leap.bitmaskclient.userstatus.UserStatusFragment; +import static android.content.Context.MODE_PRIVATE;  import static se.leap.bitmaskclient.BitmaskApp.getRefWatcher;  import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;  import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; @@ -48,11 +46,6 @@ import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;  public class NavigationDrawerFragment extends Fragment {      /** -     * Remember the position of the selected item. -     */ -    private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position"; - -    /**       * Per the design guidelines, you should show the drawer on launch until the user manually       * expands it. This shared preference tracks this.       */ @@ -68,8 +61,8 @@ public class NavigationDrawerFragment extends Fragment {      private ListView mDrawerSettingsListView;      private ListView mDrawerAccountsListView;      private View mFragmentContainerView; +    private ArrayAdapter<String> accountListAdapter; -    private int mCurrentSelectedPosition = 0;      private boolean mFromSavedInstanceState;      private boolean mUserLearnedDrawer; @@ -86,20 +79,8 @@ public class NavigationDrawerFragment extends Fragment {          // Read in the flag indicating whether or not the user has demonstrated awareness of the          // drawer. See PREF_USER_LEARNED_DRAWER for details. -        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); -        mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false); - -        preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); - -        if (savedInstanceState != null) { -            mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION); -            mFromSavedInstanceState = true; -        } - -        // Select either the default item (0) or the last selected item. -        if (mDrawerSettingsListView != null) { -            selectItem(mDrawerSettingsListView, mCurrentSelectedPosition); -        } +        preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); +        mUserLearnedDrawer = preferences.getBoolean(PREF_USER_LEARNED_DRAWER, false);      }      @Override @@ -143,12 +124,10 @@ public class NavigationDrawerFragment extends Fragment {                  android.R.layout.simple_list_item_activated_1,                  android.R.id.text1,                  new String[]{ -                        getString(R.string.vpn_fragment_title),                          getString(R.string.switch_provider_menu_option),                          getString(R.string.log_fragment_title),                          getString(R.string.about_fragment_title),                  })); -        mDrawerSettingsListView.setItemChecked(mCurrentSelectedPosition, true);          mDrawerAccountsListView = mDrawerView.findViewById(R.id.accountList);          mDrawerAccountsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @@ -158,14 +137,21 @@ public class NavigationDrawerFragment extends Fragment {              }          }); -        mDrawerAccountsListView.setAdapter(new ArrayAdapter<String>( -                actionBar.getThemedContext(), + + +        accountListAdapter = new ArrayAdapter<>(actionBar.getThemedContext(),                  android.R.layout.simple_list_item_activated_1, -                android.R.id.text1, -                new String[]{ -                        User.userName(), -                })); -        mDrawerAccountsListView.setItemChecked(mCurrentSelectedPosition, true); +                android.R.id.text1); + +        String providerName = ConfigHelper.getCurrentProviderName(preferences); +        if (providerName == null) { +            //TODO: ADD A header to the ListView containing a useful message. +            //TODO 2: disable switchProvider +        } else { +            accountListAdapter.add(providerName); +        } + +        mDrawerAccountsListView.setAdapter(accountListAdapter);          mFragmentContainerView = activity.findViewById(fragmentId);          mDrawerLayout = drawerLayout; @@ -205,9 +191,7 @@ public class NavigationDrawerFragment extends Fragment {                      // The user manually opened the drawer; store this flag to prevent auto-showing                      // the navigation drawer automatically in the future.                      mUserLearnedDrawer = true; -                    SharedPreferences sp = PreferenceManager -                            .getDefaultSharedPreferences(getActivity()); -                    sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply(); +                    preferences.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();                  }                  getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu() @@ -229,11 +213,9 @@ public class NavigationDrawerFragment extends Fragment {          });          mDrawerLayout.addDrawerListener(mDrawerToggle); -        selectItem(mDrawerSettingsListView, 0);      }      private void selectItem(AdapterView<?> list, int position) { -        mCurrentSelectedPosition = position;          if (list != null) {              ((ListView) list).setItemChecked(position, true);          } @@ -256,7 +238,6 @@ public class NavigationDrawerFragment extends Fragment {      @Override      public void onSaveInstanceState(Bundle outState) {          super.onSaveInstanceState(outState); -        outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);      }      @Override @@ -314,31 +295,26 @@ public class NavigationDrawerFragment extends Fragment {          Fragment fragment = null;          if (parent == mDrawerAccountsListView) { -            mTitle = User.userName(); -            fragment = new UserStatusFragment(); -            Bundle bundle = new Bundle(); -            bundle.putBoolean(Provider.ALLOW_REGISTRATION, new Provider().allowsRegistration()); -            fragment.setArguments(bundle); +            mTitle = getString(R.string.vpn_fragment_title); +            fragment = new VpnFragment();          } else {              Log.d("Drawer", String.format("Selected position %d", position));              switch (position) { -                case 1: +                case 0:                      // TODO STOP VPN                      // if (provider.hasEIP()) eip_fragment.stopEipIfPossible();                      preferences.edit().clear().apply();                      startActivityForResult(new Intent(getActivity(), ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER);                      break; -                case 2: +                case 1:                      mTitle = getString(R.string.log_fragment_title);                      fragment = new LogFragment();                      break; -                case 3: +                case 2:                      mTitle = getString(R.string.about_fragment_title);                      fragment = new AboutFragment();                      break;                  default: -                    mTitle = getString(R.string.vpn_fragment_title); -                    fragment = new VpnFragment();                      break;              }          } diff --git a/app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java b/app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java new file mode 100644 index 00000000..a9a5733d --- /dev/null +++ b/app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java @@ -0,0 +1,57 @@ +package se.leap.bitmaskclient; + +import android.content.SharedPreferences; + +import org.junit.Before; +import org.junit.Test; + +import se.leap.bitmaskclient.testutils.MockSharedPreferences; +import se.leap.bitmaskclient.testutils.TestSetupHelper; + +import static org.junit.Assert.*; +import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; +import static se.leap.bitmaskclient.testutils.TestSetupHelper.getInputAsString; + +/** + * Created by cyberta on 17.01.18. + */ +public class ConfigHelperTest { + +    private SharedPreferences mockPreferences; + + +    @Before +    public void setup() { +        mockPreferences = new MockSharedPreferences(); +    } + +    @Test +    public void providerInSharedPreferences_notInPreferences_returnsFalse() throws Exception { +        assertFalse(ConfigHelper.providerInSharedPreferences(mockPreferences)); +    } + +    @Test +    public void providerInSharedPreferences_inPreferences_returnsTrue() throws Exception { +        mockPreferences.edit().putBoolean(PROVIDER_CONFIGURED, true).apply(); +        assertTrue(ConfigHelper.providerInSharedPreferences(mockPreferences)); +    } + +    @Test +    public void getSavedProviderFromSharedPreferences_notInPreferences_returnsDefaultProvider() throws Exception { +        Provider provider = ConfigHelper.getSavedProviderFromSharedPreferences(mockPreferences); +        assertFalse(provider.isConfigured()); +    } + +    @Test +    public void getSavedProviderFromSharedPreferences_notInPreferences_returnsConfiguredProvider() throws Exception { +        mockPreferences.edit() +                .putString(Provider.KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json"))) +                .putString(Provider.MAIN_URL, "https://riseup.net") +                .putString(Provider.CA_CERT, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem"))) +                .apply(); +        Provider provider = ConfigHelper.getSavedProviderFromSharedPreferences(mockPreferences); +        assertTrue(provider.isConfigured()); +    } + + +}
\ No newline at end of file | 
