diff options
14 files changed, 413 insertions, 234 deletions
diff --git a/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java index 27984147..ed2a063c 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -95,7 +95,6 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download outState.putString(PROGRESSBAR_TEXT, progressbar_description.getText().toString()); if(selected_provider != null) outState.putParcelable(Provider.KEY, selected_provider); - outState.putParcelable(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); super.onSaveInstanceState(outState); } @@ -112,7 +111,6 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download if(savedInstanceState != null) restoreState(savedInstanceState); - else setUpProviderAPIResultReceiver(); } @@ -121,8 +119,14 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download provider_name = savedInstanceState.getString(Provider.NAME, ""); selected_provider = savedInstanceState.getParcelable(Provider.KEY); progress = savedInstanceState.getInt(PROGRESSBAR_NUMBER, -1); - providerAPI_result_receiver = savedInstanceState.getParcelable(ProviderAPI.RECEIVER_KEY); - providerAPI_result_receiver.setReceiver(this); + + if(fragment_manager.findFragmentByTag(ProviderDetailFragment.TAG) == null && setting_up_provider) { + if (selected_provider != null) + onItemSelectedUi(selected_provider); + if (progress > 0) + mProgressBar.setProgress(progress); + } + } @Override @@ -211,7 +215,8 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download setResult(RESULT_OK); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { hideProgressBar(); - + cancelSettingUpProvider(); + Toast.makeText(getApplicationContext(), R.string.provider_problem, Toast.LENGTH_LONG).show(); setResult(RESULT_CANCELED, mConfigState); } else if(resultCode == AboutActivity.VIEWED) { // Do nothing, right now @@ -356,6 +361,7 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download DialogFragment newFragment = ProviderDetailFragment.newInstance(); newFragment.show(fragment_transaction, ProviderDetailFragment.TAG); + setting_up_provider = false; } } diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index 0650f0ad..9ce0e99f 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -49,8 +49,8 @@ public class ProviderAPI extends IntentService { TAG = ProviderAPI.class.getSimpleName(), SET_UP_PROVIDER = "setUpProvider", DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON", - SRP_REGISTER = "srpRegister", - SRP_AUTH = "srpAuth", + SIGN_UP = "srpRegister", + LOG_IN = "srpAuth", LOG_OUT = "logOut", DOWNLOAD_CERTIFICATE = "downloadUserAuthedCertificate", PARAMETERS = "parameters", @@ -118,11 +118,11 @@ public class ProviderAPI extends IntentService { return "{ \"" + ERRORS + "\" : \""+getResources().getString(toast_string_id)+"\" }"; } - @Override - protected void onHandleIntent(Intent command) { - final ResultReceiver receiver = command.getParcelableExtra(RECEIVER_KEY); - String action = command.getAction(); - Bundle parameters = command.getBundleExtra(PARAMETERS); + @Override + protected void onHandleIntent(Intent command) { + final ResultReceiver receiver = command.getParcelableExtra(RECEIVER_KEY); + String action = command.getAction(); + Bundle parameters = command.getBundleExtra(PARAMETERS); if(provider_api_url == null) { try { JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, "no provider")); @@ -133,42 +133,48 @@ public class ProviderAPI extends IntentService { } } - if(action.equalsIgnoreCase(SET_UP_PROVIDER)) { - Bundle result = setUpProvider(parameters); - if(go_ahead) { - if(result.getBoolean(RESULT_KEY)) { - receiver.send(PROVIDER_OK, result); - } else { - receiver.send(PROVIDER_NOK, result); - } - } - } else if (action.equalsIgnoreCase(SRP_REGISTER)) { - Bundle session_id_bundle = tryToRegister(parameters); - if(session_id_bundle.getBoolean(RESULT_KEY)) { - receiver.send(SUCCESSFUL_SIGNUP, session_id_bundle); - } else { - receiver.send(FAILED_SIGNUP, session_id_bundle); - } - } else if (action.equalsIgnoreCase(SRP_AUTH)) { - Bundle session_id_bundle = tryToAuthenticate(parameters); - if(session_id_bundle.getBoolean(RESULT_KEY)) { - receiver.send(SUCCESSFUL_LOGIN, session_id_bundle); - } else { - receiver.send(FAILED_LOGIN, session_id_bundle); - } - } else if (action.equalsIgnoreCase(LOG_OUT)) { - if(logOut()) { - receiver.send(SUCCESSFUL_LOGOUT, Bundle.EMPTY); - } else { - receiver.send(LOGOUT_FAILED, Bundle.EMPTY); - } - } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { - if(updateVpnCertificate()) { - receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); - } else { - receiver.send(INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); - } - } else if(action.equalsIgnoreCase(DOWNLOAD_EIP_SERVICE)) { + if(action.equalsIgnoreCase(SET_UP_PROVIDER)) { + Bundle result = setUpProvider(parameters); + if(go_ahead) { + if(result.getBoolean(RESULT_KEY)) { + receiver.send(PROVIDER_OK, result); + } else { + receiver.send(PROVIDER_NOK, result); + } + } + } else if (action.equalsIgnoreCase(SIGN_UP)) { + Bundle result = tryToRegister(parameters); + if(result.getBoolean(RESULT_KEY)) { + receiver.send(SUCCESSFUL_SIGNUP, result); + } else { + receiver.send(FAILED_SIGNUP, result); + } + } else if (action.equalsIgnoreCase(LOG_IN)) { + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGING_IN); + Bundle result = tryToAuthenticate(parameters); + if(result.getBoolean(RESULT_KEY)) { + receiver.send(SUCCESSFUL_LOGIN, result); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGED_IN); + } else { + receiver.send(FAILED_LOGIN, result); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.NOT_LOGGED_IN); + } + } else if (action.equalsIgnoreCase(LOG_OUT)) { + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGING_OUT); + if(logOut()) { + receiver.send(SUCCESSFUL_LOGOUT, Bundle.EMPTY); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGED_OUT); + } else { + receiver.send(LOGOUT_FAILED, Bundle.EMPTY); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.DIDNT_LOG_OUT); + } + } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { + if(updateVpnCertificate()) { + receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); + } else { + receiver.send(INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); + } + } else if(action.equalsIgnoreCase(DOWNLOAD_EIP_SERVICE)) { Bundle result = getAndSetEipServiceJson(); if(result.getBoolean(RESULT_KEY)) { receiver.send(CORRECTLY_DOWNLOADED_EIP_SERVICE, result); @@ -176,13 +182,13 @@ public class ProviderAPI extends IntentService { receiver.send(INCORRECTLY_DOWNLOADED_EIP_SERVICE, result); } } - } + } private Bundle tryToRegister(Bundle task) { Bundle result = new Bundle(); int progress = 0; - String username = task.getString(SessionDialog.USERNAME); + String username = User.userName(); String password = task.getString(SessionDialog.PASSWORD); if(validUserLoginData(username, password)) { @@ -231,8 +237,8 @@ public class ProviderAPI extends IntentService { private Bundle tryToAuthenticate(Bundle task) { Bundle result = new Bundle(); int progress = 0; - - String username = task.getString(SessionDialog.USERNAME); + + String username = User.userName(); String password = task.getString(SessionDialog.PASSWORD); if(validUserLoginData(username, password)) { result = authenticate(username, password); @@ -675,7 +681,7 @@ public class ProviderAPI extends IntentService { String json_file_content = ""; URL provider_url = null; - int seconds_of_timeout = 1; + int seconds_of_timeout = 2; try { provider_url = new URL(string_url); URLConnection url_connection = provider_url.openConnection(); diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 04385ddd..face6ced 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -28,6 +28,7 @@ import android.widget.*; import org.jetbrains.annotations.NotNull; import org.json.*; import java.net.*; +import java.util.*; import butterknife.*; import de.blinkt.openvpn.activities.*; @@ -40,7 +41,7 @@ import se.leap.bitmaskclient.eip.*; * @author Sean Leonard <meanderingcode@aetherislands.net> * @author parmegv */ -public class Dashboard extends Activity implements SessionDialog.SessionDialogInterface, ProviderAPIResultReceiver.Receiver { +public class Dashboard extends Activity implements SessionDialog.SessionDialogInterface, ProviderAPIResultReceiver.Receiver, Observer { protected static final int CONFIGURE_LEAP = 0; protected static final int SWITCH_PROVIDER = 1; @@ -60,46 +61,65 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn @InjectView(R.id.providerName) TextView provider_name; + @InjectView(R.id.user_session_status) + TextView user_session_status_text_view; + @InjectView(R.id.user_session_status_progress) + ProgressBar user_session_status_progress_bar; EipFragment eip_fragment; private Provider provider; + private UserSessionStatus user_session_status; public ProviderAPIResultReceiver providerAPI_result_receiver; private boolean switching_provider; @Override protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - app = this; + super.onCreate(savedInstanceState); - PRNGFixes.apply(); + app = this; + user_session_status = UserSessionStatus.getInstance(); + user_session_status.addObserver(this); - preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); - handleVersion(); + PRNGFixes.apply(); - provider = getSavedProvider(savedInstanceState); + preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); + handleVersion(); + + restoreProvider(savedInstanceState); if (provider == null || provider.getName().isEmpty()) - startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); - else - buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); + startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); + else { + buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); + restoreSessionStatus(savedInstanceState); + } + } + + private void restoreProvider(Bundle savedInstanceState) { + if (savedInstanceState != null) { + if(savedInstanceState.containsKey(Provider.KEY)) + provider = savedInstanceState.getParcelable(Provider.KEY); + } + if(provider == null && preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false)) + provider = getSavedProviderFromSharedPreferences(); + } + + private void restoreSessionStatus(Bundle savedInstanceState) { + if (savedInstanceState != null) + if(savedInstanceState.containsKey(UserSessionStatus.TAG)) { + UserSessionStatus.SessionStatus status = (UserSessionStatus.SessionStatus) savedInstanceState.getSerializable(UserSessionStatus.TAG); + user_session_status.updateStatus(status); + } } @Override protected void onSaveInstanceState(@NotNull Bundle outState) { if(provider != null) outState.putParcelable(Provider.KEY, provider); - super.onSaveInstanceState(outState); - } - - private Provider getSavedProvider(Bundle savedInstanceState) { - Provider provider = null; - if(savedInstanceState != null) - provider = savedInstanceState.getParcelable(Provider.KEY); - else if(preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false)) - provider = getSavedProviderFromSharedPreferences(); + if(user_session_status_text_view != null && user_session_status_text_view.getVisibility() == TextView.VISIBLE) + outState.putSerializable(UserSessionStatus.TAG, user_session_status.sessionStatus()); - return provider; + super.onSaveInstanceState(outState); } private Provider getSavedProviderFromSharedPreferences() { @@ -107,9 +127,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn try { provider = new Provider(new URL(preferences.getString(Provider.MAIN_URL, ""))); provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (JSONException e) { + } catch (MalformedURLException | JSONException e) { e.printStackTrace(); } @@ -136,8 +154,8 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ - if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { - if ( resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) { + if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { + if ( resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) { provider = data.getParcelableExtra(Provider.KEY); providerToPreferences(provider); @@ -147,13 +165,13 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn sessionDialog(Bundle.EMPTY); } - } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { + } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { finish(); - } else - configErrorDialog(); - } else if(requestCode == EIP.DISCONNECT) { - EipStatus.getInstance().setConnectedOrDisconnected(); - } + } else + configErrorDialog(); + } else if(requestCode == EIP.DISCONNECT) { + EipStatus.getInstance().setConnectedOrDisconnected(); + } } @SuppressLint("CommitPrefEdits") @@ -164,7 +182,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } private void configErrorDialog() { - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getAppContext()); + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getContext()); alertBuilder.setTitle(getResources().getString(R.string.setup_error_title)); alertBuilder .setMessage(getResources().getString(R.string.setup_error_text)) @@ -172,7 +190,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn .setPositiveButton(getResources().getString(R.string.setup_error_configure_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - startActivityForResult(new Intent(getAppContext(),ConfigurationWizard.class),CONFIGURE_LEAP); + startActivityForResult(new Intent(getContext(),ConfigurationWizard.class),CONFIGURE_LEAP); } }) .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { @@ -190,55 +208,39 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn * service dependent UI elements to include. */ private void buildDashboard(boolean hide_and_turn_on_eip) { - setContentView(R.layout.dashboard); + setContentView(R.layout.dashboard); ButterKnife.inject(this); - provider_name.setText(provider.getDomain()); - if ( provider.hasEIP()){ + provider_name.setText(provider.getDomain()); + if ( provider.hasEIP()){ fragment_manager.removePreviousFragment(EipFragment.TAG); eip_fragment = new EipFragment(); - if (hide_and_turn_on_eip) { - preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); - Bundle arguments = new Bundle(); - arguments.putBoolean(EipFragment.START_ON_BOOT, true); + if (hide_and_turn_on_eip) { + preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); + Bundle arguments = new Bundle(); + arguments.putBoolean(EipFragment.START_ON_BOOT, true); if(eip_fragment != null) eip_fragment.setArguments(arguments); - } + } fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); - if (hide_and_turn_on_eip) { - onBackPressed(); - } - } + if (hide_and_turn_on_eip) { + onBackPressed(); + } + } + handleNewUserSessionStatus(user_session_status); } @Override public boolean onPrepareOptionsMenu(Menu menu) { - JSONObject provider_json; - try { - String provider_json_string = preferences.getString(Provider.KEY, ""); - if(!provider_json_string.isEmpty()) { - provider_json = new JSONObject(provider_json_string); - JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); - boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); - preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, allow_registered_eip).apply(); - - if(allow_registered_eip) { - if(LeapSRPSession.loggedIn()) { - menu.findItem(R.id.login_button).setVisible(false); - menu.findItem(R.id.logout_button).setVisible(true); - } else { - menu.findItem(R.id.login_button).setVisible(true); - menu.findItem(R.id.logout_button).setVisible(false); - } - menu.findItem(R.id.signup_button).setVisible(true); - } - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return true; + if(provider.allowsRegistration()) { + menu.findItem(R.id.signup_button).setVisible(true); + + boolean logged_in = User.loggedIn(); + menu.findItem(R.id.login_button).setVisible(!logged_in); + menu.findItem(R.id.logout_button).setVisible(logged_in); + } + return true; } @Override @@ -281,26 +283,74 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } public void showLog() { - Intent startLW = new Intent(getAppContext(), LogWindow.class); - //startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + Intent startLW = new Intent(getContext(), LogWindow.class); startActivity(startLW); } @Override public void signUp(String username, String password) { - Bundle parameters = bundleParameters(username, password); - providerApiCommand(parameters, R.string.signingup_message, ProviderAPI.SRP_REGISTER); + User.setUserName(username); + Bundle parameters = bundlePassword(password); + providerApiCommand(parameters, R.string.signingup_message, ProviderAPI.SIGN_UP); } @Override public void logIn(String username, String password) { - Bundle parameters = bundleParameters(username, password); - providerApiCommand(parameters, R.string.authenticating_message, ProviderAPI.SRP_AUTH); + User.setUserName(username); + Bundle parameters = bundlePassword(password); + providerApiCommand(parameters, R.string.authenticating_message, ProviderAPI.LOG_IN); } public void logOut() { providerApiCommand(Bundle.EMPTY, R.string.logout_message, ProviderAPI.LOG_OUT); } + + @Override + public void update (Observable observable, Object data) { + if(observable instanceof UserSessionStatus) { + UserSessionStatus status = (UserSessionStatus) observable; + handleNewUserSessionStatus(status); + } + } + + private void handleNewUserSessionStatus(UserSessionStatus status) { + user_session_status = status; + if(provider.allowsRegistration()) { + if(user_session_status.inProgress()) + showUserSessionProgressBar(); + else + hideUserSessionProgressBar(); + changeSessionStatusMessage(user_session_status.toString()); + invalidateOptionsMenu(); + } + } + + private void changeSessionStatusMessage(final String message) { + runOnUiThread(new Runnable() { + @Override + public void run() { + user_session_status_text_view.setText(message); + } + }); + } + + private void showUserSessionProgressBar() { + runOnUiThread(new Runnable() { + @Override + public void run() { + user_session_status_progress_bar.setVisibility(ProgressBar.VISIBLE); + } + }); + } + + private void hideUserSessionProgressBar() { + runOnUiThread(new Runnable() { + @Override + public void run() { + user_session_status_progress_bar.setVisibility(ProgressBar.GONE); + } + }); + } protected void downloadVpnCertificate() { boolean is_authenticated = LeapSRPSession.loggedIn(); @@ -312,10 +362,8 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } - private Bundle bundleParameters(String username, String password) { + private Bundle bundlePassword(String password) { Bundle parameters = new Bundle(); - if(!username.isEmpty()) - parameters.putString(SessionDialog.USERNAME, username); if(!password.isEmpty()) parameters.putString(SessionDialog.PASSWORD, password); return parameters; @@ -374,26 +422,20 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn String password = resultData.getString(SessionDialog.PASSWORD); logIn(username, password); } else if(resultCode == ProviderAPI.FAILED_SIGNUP) { - updateViewHidingProgressBar(resultCode); sessionDialog(resultData); } else if(resultCode == ProviderAPI.SUCCESSFUL_LOGIN) { - updateViewHidingProgressBar(resultCode); downloadVpnCertificate(); } else if(resultCode == ProviderAPI.FAILED_LOGIN) { - updateViewHidingProgressBar(resultCode); sessionDialog(resultData); } else if(resultCode == ProviderAPI.SUCCESSFUL_LOGOUT) { - updateViewHidingProgressBar(resultCode); if(switching_provider) switchProvider(); } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { - updateViewHidingProgressBar(resultCode); setResult(RESULT_CANCELED); } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { - updateViewHidingProgressBar(resultCode); eip_fragment.updateEipService(); + eip_fragment.handleNewVpnCertificate(); setResult(RESULT_OK); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { - updateViewHidingProgressBar(resultCode); setResult(RESULT_CANCELED); } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) { @@ -404,67 +446,12 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } } - private void updateViewHidingProgressBar(int resultCode) { - changeStatusMessage(resultCode); - hideProgressBar(); - invalidateOptionsMenu(); - } - - private void changeStatusMessage(final int previous_result_code) { - ResultReceiver status_receiver = new ResultReceiver(new Handler()){ - protected void onReceiveResult(int resultCode, Bundle resultData){ - super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(Constants.REQUEST_TAG); - if (request.equalsIgnoreCase(Constants.ACTION_IS_EIP_RUNNING)){ - if (resultCode == Activity.RESULT_OK){ - switch(previous_result_code){ - case ProviderAPI.SUCCESSFUL_LOGIN: setStatusMessage(R.string.succesful_authentication_message); break; - case ProviderAPI.FAILED_LOGIN: setStatusMessage(R.string.authentication_failed_message); break; - case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: setStatusMessage(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.SUCCESSFUL_LOGOUT: setStatusMessage(R.string.logged_out_message); break; - case ProviderAPI.LOGOUT_FAILED: setStatusMessage(R.string.log_out_failed_message); break; - - } - } - else if(resultCode == Activity.RESULT_CANCELED){ - switch(previous_result_code){ - case ProviderAPI.SUCCESSFUL_LOGIN: setStatusMessage(R.string.succesful_authentication_message); break; - case ProviderAPI.FAILED_LOGIN: setStatusMessage(R.string.authentication_failed_message); break; - case ProviderAPI.FAILED_SIGNUP: setStatusMessage(R.string.registration_failed_message); break; - case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break; - case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: setStatusMessage(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.SUCCESSFUL_LOGOUT: setStatusMessage(R.string.logged_out_message); break; - case ProviderAPI.LOGOUT_FAILED: setStatusMessage(R.string.log_out_failed_message); break; - } - } - } - - } - }; - eipIsRunning(status_receiver); - } - private void setStatusMessage(int string_resId) { if(eip_fragment != null && eip_fragment.status_message != null) eip_fragment.status_message.setText(string_resId); } - private void eipIsRunning(ResultReceiver eip_receiver){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent intent = new Intent(this, EIP.class); - intent.setAction(Constants.ACTION_IS_EIP_RUNNING); - intent.putExtra(Constants.RECEIVER_TAG, eip_receiver); - startService(intent); - } - - private void hideProgressBar() { - if(eip_fragment != null) { - eip_fragment.progress_bar.setProgress(0); - eip_fragment.progress_bar.setVisibility(ProgressBar.GONE); - } - } - - public static Context getAppContext() { + public static Context getContext() { return app; } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index 680f21e1..2057a80b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -23,6 +23,8 @@ import android.util.*; import android.view.*; import android.widget.*; +import org.jetbrains.annotations.NotNull; + import java.util.*; import butterknife.*; @@ -80,18 +82,20 @@ public class EipFragment extends Fragment implements Observer { Bundle arguments = getArguments(); if(arguments != null && arguments.containsKey(START_ON_BOOT) && arguments.getBoolean(START_ON_BOOT)) startEipFromScratch(); + if(savedInstanceState != null) restoreState(savedInstanceState); - if (savedInstanceState != null) { - status_message.setText(savedInstanceState.getString(STATUS_MESSAGE)); - if(savedInstanceState.getBoolean(IS_PENDING)) - eip_status.setConnecting(); - else if(savedInstanceState.getBoolean(IS_CONNECTED)) { - eip_status.setConnectedOrDisconnected(); - } - } return view; } + private void restoreState(@NotNull Bundle savedInstanceState) { + if(savedInstanceState.getBoolean(IS_PENDING)) + eip_status.setConnecting(); + else if(savedInstanceState.getBoolean(IS_CONNECTED)) + eip_status.setConnectedOrDisconnected(); + else + status_message.setText(savedInstanceState.getString(STATUS_MESSAGE)); + } + @Override public void onResume() { super.onResume(); @@ -103,17 +107,19 @@ public class EipFragment extends Fragment implements Observer { public void onSaveInstanceState(Bundle outState) { outState.putBoolean(IS_PENDING, eip_status.isConnecting()); outState.putBoolean(IS_CONNECTED, eip_status.isConnected()); - Log.d(TAG, "status message onSaveInstanceState = " + status_message.getText().toString()); outState.putString(STATUS_MESSAGE, status_message.getText().toString()); super.onSaveInstanceState(outState); } protected void saveStatus() { boolean is_on = eip_switch.isChecked(); - Log.d(TAG, "saveStatus: is_on = " + is_on); Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, is_on).commit(); } + void handleNewVpnCertificate() { + handleSwitch(!eip_switch.isEnabled()); + } + @OnCheckedChanged(R.id.eipSwitch) void handleSwitch(boolean isChecked) { if(isChecked) @@ -154,7 +160,8 @@ public class EipFragment extends Fragment implements Observer { askPendingStartCancellation(); } else if(eip_status.isConnected()) { askToStopEIP(); - } + } else + setDisconnectedUI(); } private void askPendingStartCancellation() { @@ -294,16 +301,22 @@ public class EipFragment extends Fragment implements Observer { String logmessage = eip_status.getLogMessage(); String prefix = dashboard.getString(localizedResId); + showProgressBar(); status_message.setText(prefix + " " + logmessage); is_starting_to_connect = false; adjustSwitch(); } private void updatingCertificateUI() { - progress_bar.setVisibility(View.VISIBLE); + showProgressBar(); status_message.setText(getString(R.string.updating_certificate_message)); } + private void showProgressBar() { + if(progress_bar != null) + progress_bar.setVisibility(View.VISIBLE); + } + private void hideProgressBar() { if(progress_bar != null) progress_bar.setVisibility(View.GONE); diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java index 09855baf..49c115ae 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java +++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java @@ -44,7 +44,8 @@ public class LeapSRPSession { final public static String TOKEN = "token"; final public static String AUTHORIZATION_HEADER= "Authorization"; final public static String TAG= "Leap SRP session class tag"; - + + private User user; private SRPParameters params; private String username; private String password; diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index d7ff6633..ef25c5d2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -172,6 +172,14 @@ public final class Provider implements Parcelable { return false; } + public boolean allowsRegistration() { + try { + return definition.getJSONObject(Provider.SERVICE).getBoolean(Provider.ALLOW_REGISTRATION); + } catch (JSONException e) { + return false; + } + } + @Override public int describeContents() { return 0; diff --git a/app/src/main/java/se/leap/bitmaskclient/User.java b/app/src/main/java/se/leap/bitmaskclient/User.java new file mode 100644 index 00000000..6e20c165 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/User.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package se.leap.bitmaskclient; + +public class User { + private static String user_name = "You"; + private static User user; + + public static User getInstance() { + if(user == null) { + user = new User(); + } + return user; + } + + public static void setUserName(String user_name) { + User.user_name = user_name; + } + + private User() { } + + public static String userName() { return user_name; } + + public static boolean loggedIn() { + return LeapSRPSession.loggedIn(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java b/app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java new file mode 100644 index 00000000..f533819b --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package se.leap.bitmaskclient; + +import android.os.*; + +import java.util.*; + +public class UserSessionStatus extends Observable { + public static String TAG = UserSessionStatus.class.getSimpleName(); + private static UserSessionStatus current_status; + + public enum SessionStatus { + LOGGED_IN, + LOGGED_OUT, + NOT_LOGGED_IN, + DIDNT_LOG_OUT, + LOGGING_IN, + LOGGING_OUT + } + + private static SessionStatus session_status = SessionStatus.NOT_LOGGED_IN; + + public static UserSessionStatus getInstance() { + if(current_status == null) { + current_status = new UserSessionStatus(); + } + return current_status; + } + + private UserSessionStatus() { } + + private void sessionStatus(SessionStatus session_status) { + this.session_status = session_status; + } + + public SessionStatus sessionStatus() { return session_status; } + + public boolean inProgress() { + return session_status == SessionStatus.LOGGING_IN + || session_status == SessionStatus.LOGGING_OUT; + } + + public static void updateStatus(SessionStatus session_status) { + current_status = getInstance(); + current_status.sessionStatus(session_status); + current_status.setChanged(); + current_status.notifyObservers(); + } + + @Override + public String toString() { + return User.userName() + " is " + + session_status.toString().toLowerCase().replaceAll("_", " "); + } +} 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 0c773208..0a707ab1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -42,7 +42,8 @@ public class VoidVpnService extends VpnService { public static boolean stop() { try { - fd.close(); + if(fd != null) + fd.close(); return true; } catch (IOException | NullPointerException e) { android.util.Log.d(TAG, "VoidVpnService didn't stop"); diff --git a/app/src/main/res/layout-xlarge/dashboard.xml b/app/src/main/res/layout-xlarge/dashboard.xml index bd644e1e..268bd3f9 100644 --- a/app/src/main/res/layout-xlarge/dashboard.xml +++ b/app/src/main/res/layout-xlarge/dashboard.xml @@ -52,6 +52,28 @@ </LinearLayout> </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingLeft="32dp"> + <ProgressBar + android:id="@+id/user_session_status_progress" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:indeterminate="true" + android:visibility="gone"/> + <TextView + android:id="@+id/user_session_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="10dp" + android:ellipsize="marquee" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" + /> + </LinearLayout> + <View android:layout_width="wrap_content" android:layout_height="1dp" diff --git a/app/src/main/res/layout/dashboard.xml b/app/src/main/res/layout/dashboard.xml index 67a1122f..f4269fe2 100644 --- a/app/src/main/res/layout/dashboard.xml +++ b/app/src/main/res/layout/dashboard.xml @@ -16,7 +16,6 @@ android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:ellipsize="marquee" - android:fadingEdge="horizontal" android:singleLine="true" android:text="@string/provider_label" android:textAppearance="?android:attr/textAppearanceMedium" /> @@ -28,19 +27,33 @@ android:textSize="28sp" android:layout_marginLeft="10dp" android:ellipsize="marquee" - android:fadingEdge="horizontal" android:singleLine="true" android:text="@string/provider_label_none" android:textAppearance="?android:attr/textAppearanceMedium" /> </LinearLayout> - <View - android:layout_width="wrap_content" - android:layout_height="2dp" - android:layout_marginBottom="15dp" - android:background="@android:drawable/divider_horizontal_bright" /> - + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <ProgressBar + android:id="@+id/user_session_status_progress" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:indeterminate="true" + android:visibility="gone"/> + <TextView + android:id="@+id/user_session_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="10dp" + android:ellipsize="marquee" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" + /> + </LinearLayout> + <LinearLayout android:id="@+id/servicesCollection" android:layout_width="match_parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 032602cb..897223ad 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -71,4 +71,6 @@ <string name="no">No</string> <string name="eip_state_not_connected">"Not running! Connection not secure!"</string> <string name="eip_state_connected">Connection Secure.</string> + <string name="provider_problem">It seems there is a problem with the provider.</string> + <string name="try_another_provider">Please try another provider, or contact yours.</string> </resources> diff --git a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java index abab106d..f5e78e65 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -96,7 +96,6 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download outState.putString(PROGRESSBAR_TEXT, progressbar_description.getText().toString()); if(selected_provider != null) outState.putParcelable(Provider.KEY, selected_provider); - outState.putParcelable(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); super.onSaveInstanceState(outState); } @@ -113,7 +112,6 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download if (savedInstanceState != null) restoreState(savedInstanceState); - else setUpProviderAPIResultReceiver(); } @@ -121,9 +119,13 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download progressbar_text = savedInstanceState.getString(PROGRESSBAR_TEXT, ""); provider_name = savedInstanceState.getString(Provider.NAME, ""); selected_provider = savedInstanceState.getParcelable(Provider.KEY); - progress = savedInstanceState.getInt(PROGRESSBAR_NUMBER, -1); - providerAPI_result_receiver = savedInstanceState.getParcelable(ProviderAPI.RECEIVER_KEY); - providerAPI_result_receiver.setReceiver(this); + + if(fragment_manager.findFragmentByTag(ProviderDetailFragment.TAG) == null && setting_up_provider) { + if (selected_provider != null) + onItemSelectedUi(selected_provider); + if (progress > 0) + mProgressBar.setProgress(progress); + } } @Override @@ -355,6 +357,7 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download DialogFragment newFragment = ProviderDetailFragment.newInstance(); newFragment.show(fragment_transaction, ProviderDetailFragment.TAG); + setting_up_provider = false; } } diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index c8efe0de..184173b2 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -31,8 +31,8 @@ import javax.net.ssl.*; import org.apache.http.client.ClientProtocolException; import org.json.*; +import se.leap.bitmaskclient.ProviderListContent.ProviderItem; import se.leap.bitmaskclient.eip.*; - /** * Implements HTTP api methods used to manage communications with the provider server. * @@ -48,8 +48,8 @@ public class ProviderAPI extends IntentService { TAG = ProviderAPI.class.getSimpleName(), SET_UP_PROVIDER = "setUpProvider", DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON", - SRP_REGISTER = "srpRegister", - SRP_AUTH = "srpAuth", + SIGN_UP = "srpRegister", + LOG_IN = "srpAuth", LOG_OUT = "logOut", DOWNLOAD_CERTIFICATE = "downloadUserAuthedCertificate", PARAMETERS = "parameters", @@ -137,25 +137,31 @@ public class ProviderAPI extends IntentService { receiver.send(PROVIDER_NOK, result); } } - } else if (action.equalsIgnoreCase(SRP_REGISTER)) { + } else if (action.equalsIgnoreCase(SIGN_UP)) { Bundle result = tryToRegister(parameters); if(result.getBoolean(RESULT_KEY)) { receiver.send(SUCCESSFUL_SIGNUP, result); } else { receiver.send(FAILED_SIGNUP, result); } - } else if (action.equalsIgnoreCase(SRP_AUTH)) { + } else if (action.equalsIgnoreCase(LOG_IN)) { + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGING_IN); Bundle result = tryToAuthenticate(parameters); if(result.getBoolean(RESULT_KEY)) { - receiver.send(SUCCESSFUL_LOGIN, result); + receiver.send(SUCCESSFUL_LOGIN, result); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGED_IN); } else { - receiver.send(FAILED_LOGIN, result); + receiver.send(FAILED_LOGIN, result); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.NOT_LOGGED_IN); } } else if (action.equalsIgnoreCase(LOG_OUT)) { + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGING_OUT); if(logOut()) { receiver.send(SUCCESSFUL_LOGOUT, Bundle.EMPTY); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.LOGGED_OUT); } else { receiver.send(LOGOUT_FAILED, Bundle.EMPTY); + UserSessionStatus.updateStatus(UserSessionStatus.SessionStatus.DIDNT_LOG_OUT); } } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { if(updateVpnCertificate()) { @@ -177,7 +183,7 @@ public class ProviderAPI extends IntentService { Bundle result = new Bundle(); int progress = 0; - String username = task.getString(SessionDialog.USERNAME); + String username = User.userName(); String password = task.getString(SessionDialog.PASSWORD); if(validUserLoginData(username, password)) { @@ -228,8 +234,8 @@ public class ProviderAPI extends IntentService { Bundle result = new Bundle(); int progress = 0; - String username = (String) task.get(SessionDialog.USERNAME); - String password = (String) task.get(SessionDialog.PASSWORD); + String username = User.userName(); + String password = task.getString(SessionDialog.PASSWORD); if(validUserLoginData(username, password)) { result = authenticate(username, password); broadcastProgress(progress++); |