From 99a4d94564635f0223d447bc9bcf081cadd8ff36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 2 Jul 2013 19:20:58 +0200 Subject: User messages are added to the new recovery dialog When login is not successful, a new recovery dialog is prompted with a message about the previous error. --- res/layout/log_in_dialog.xml | 7 +++ res/values/strings.xml | 8 ++- src/se/leap/leapclient/Dashboard.java | 13 +++-- src/se/leap/leapclient/LogInDialog.java | 26 +++------ src/se/leap/leapclient/NewProviderDialog.java | 2 +- src/se/leap/leapclient/ProviderAPI.java | 76 +++++++++++++++++---------- 6 files changed, 81 insertions(+), 51 deletions(-) diff --git a/res/layout/log_in_dialog.xml b/res/layout/log_in_dialog.xml index 6f28118d..4c9fdbad 100644 --- a/res/layout/log_in_dialog.xml +++ b/res/layout/log_in_dialog.xml @@ -6,6 +6,13 @@ android:orientation="vertical" tools:context=".LogInDialog" > + + Use anonymously Introduce your username Enter your password + User message + Not valid username and/or password. + Your password is not well-formed: it should have at least 8 characters. + Try again: Client HTTP error + Try again: I/O error + Try again: Bad response from the server + Update the app Log In Log Out Trust completely @@ -295,7 +302,6 @@ Server is down. It doesn\'t seem to be a LEAP provider. This is not a trusted LEAP provider. - Your password is not well-formed: it should have at least 8 characters. Authenticating Authenticating with entered login and password. Log out diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 59c0f182..a330f9e0 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -102,7 +102,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf buildDashboard(); if(data != null && data.hasExtra(ConfigHelper.LOG_IN)) { View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); - logInDialog(view); + logInDialog(view, ""); } } else if(resultCode == RESULT_CANCELED && data.hasExtra(ConfigHelper.QUIT)) { finish(); @@ -270,7 +270,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf return true; case R.id.login_button: View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); - logInDialog(view); + logInDialog(view, ""); return true; case R.id.logout_button: logOut(); @@ -340,7 +340,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * Shows the log in dialog. * @param view from which the dialog is created. */ - public void logInDialog(View view) { + public void logInDialog(View view, String user_message) { FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); Fragment previous_log_in_dialog = getFragmentManager().findFragmentByTag(ConfigHelper.LOG_IN_DIALOG); if (previous_log_in_dialog != null) { @@ -349,6 +349,11 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf fragment_transaction.addToBackStack(null); DialogFragment newFragment = LogInDialog.newInstance(); + if(user_message != null && !user_message.isEmpty()) { + Bundle user_message_bundle = new Bundle(); + user_message_bundle.putString(getResources().getString(R.string.user_message), user_message); + newFragment.setArguments(user_message_bundle); + } newFragment.show(fragment_transaction, ConfigHelper.LOG_IN_DIALOG); } @@ -384,7 +389,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string); downloadAuthedUserCertificate(session_id); } else if(resultCode == ConfigHelper.SRP_AUTHENTICATION_FAILED) { - logInDialog(getCurrentFocus()); + logInDialog(getCurrentFocus(), resultData.getString(getResources().getString(R.string.user_message))); mProgressDialog.dismiss(); } else if(resultCode == ConfigHelper.LOGOUT_SUCCESSFUL) { setResult(RESULT_OK); diff --git a/src/se/leap/leapclient/LogInDialog.java b/src/se/leap/leapclient/LogInDialog.java index 99b19628..0536c6df 100644 --- a/src/se/leap/leapclient/LogInDialog.java +++ b/src/se/leap/leapclient/LogInDialog.java @@ -9,7 +9,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; -import android.widget.Toast; +import android.widget.TextView; /** * Implements the log in dialog, currently without progress dialog. @@ -22,12 +22,16 @@ import android.widget.Toast; * */ public class LogInDialog extends DialogFragment { - + public AlertDialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null); - + + final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); + if(getArguments() != null && getArguments().containsKey(getResources().getString(R.string.user_message))) { + user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); + } else user_message.setVisibility(View.GONE); final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); @@ -36,12 +40,7 @@ public class LogInDialog extends DialogFragment { public void onClick(DialogInterface dialog, int id) { String username = username_field.getText().toString().trim(); String password = password_field.getText().toString().trim(); - if(wellFormedPassword(password)) { - interface_with_Dashboard.authenticate(username, password); - } else { - password_field.setText(""); - Toast.makeText(getActivity().getApplicationContext(), R.string.not_valid_password_message, Toast.LENGTH_LONG).show(); - } + interface_with_Dashboard.authenticate(username, password); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @@ -52,15 +51,6 @@ public class LogInDialog extends DialogFragment { return builder.create(); } - - /** - * Validates a password - * @param entered_password - * @return true if the entered password length is greater or equal to eight (8). - */ - private boolean wellFormedPassword(String entered_password) { - return entered_password.length() >= 8; - } /** * Interface used to communicate LogInDialog with Dashboard. diff --git a/src/se/leap/leapclient/NewProviderDialog.java b/src/se/leap/leapclient/NewProviderDialog.java index cf361719..3712e8f9 100644 --- a/src/se/leap/leapclient/NewProviderDialog.java +++ b/src/se/leap/leapclient/NewProviderDialog.java @@ -68,7 +68,7 @@ public class NewProviderDialog extends DialogFragment { Toast.makeText(getActivity().getApplicationContext(), R.string.valid_url_entered, Toast.LENGTH_LONG).show(); } else { url_input_field.setText(""); - Toast.makeText(getActivity().getApplicationContext(), R.string.not_valid_password_message, Toast.LENGTH_LONG).show(); + Toast.makeText(getActivity().getApplicationContext(), R.string.not_valid_url_entered, Toast.LENGTH_LONG).show(); } } }) diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 306ffa20..5238224e 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -62,7 +62,7 @@ import android.widget.Toast; /** * Implements HTTP api methods used to manage communications with the provider server. * - * It's an IntentService because it downloads data fromt he Internet, so it operates in the background. + * It's an IntentService because it downloads data from the Internet, so it operates in the background. * * @author parmegv * @author MeanderingCode @@ -126,7 +126,10 @@ public class ProviderAPI extends IntentService { if(session_id_bundle.getBoolean(ConfigHelper.RESULT_KEY)) { receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); } else { - receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); + Bundle user_message_bundle = new Bundle(); + String user_message_key = getResources().getString(R.string.user_message); + user_message_bundle.putString(user_message_key, session_id_bundle.getString(user_message_key)); + receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, user_message_bundle); } } else if ((task = task_for.getBundleExtra(ConfigHelper.LOG_OUT)) != null) { @@ -176,41 +179,60 @@ public class ProviderAPI extends IntentService { String username = (String) task.get(ConfigHelper.USERNAME_KEY); String password = (String) task.get(ConfigHelper.PASSWORD_KEY); - String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); + if(wellFormedPassword(password)) { + String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); - SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); - LeapSRPSession client = new LeapSRPSession(username, password, params); - byte[] A = client.exponential(); - try { - JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); - if(saltAndB.length() > 0) { - String salt = saltAndB.getString(ConfigHelper.SALT_KEY); - byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); - byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); - JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); - if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); + LeapSRPSession client = new LeapSRPSession(username, password, params); + byte[] A = client.exponential(); + try { + JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); + if(saltAndB.length() > 0) { + String salt = saltAndB.getString(ConfigHelper.SALT_KEY); + byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); + byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); + JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); + if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + } else { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); + session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); + session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); + } } else { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); - session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); - session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); } - } else { + } catch (ClientProtocolException e) { session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_client_http_user_message)); + } catch (IOException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_io_exception_user_message)); + } catch (JSONException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_json_exception_user_message)); + } catch (NoSuchAlgorithmException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_no_such_algorithm_exception_user_message)); } - } catch (ClientProtocolException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } catch (IOException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } catch (JSONException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } catch (NoSuchAlgorithmException e) { + } else { session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_not_valid_password_user_message)); } - + return session_id_bundle; } + /** + * Validates a password + * @param entered_password + * @return true if the entered password length is greater or equal to eight (8). + */ + private boolean wellFormedPassword(String entered_password) { + return entered_password.length() >= 8; + } + /** * Sends an HTTP POST request to the authentication server with the SRP Parameter A. * @param server_url -- cgit v1.2.3 From 84d3b5f6967c0bac2a740627386ff92b6e283b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 3 Jul 2013 18:02:36 +0200 Subject: ConfigurationWizard backstack and exit behavior. Feature #3023 first solution. I don't like to tell anything to the user when s/he wants to exit pressing the back button. I assume s/he is saying: "Wanna go out!!" I've implemented the behaviour written in UI Rev II. If a user selects a new provider when coming back from Switch Provider, the previous provider is forgotten and we assume s/he wants to change of provider but he is not sure to which. That means that previous provider configuration will be removed (that means there is no provider selected and Dashboard will not be launched before a new provider is selected). --- src/se/leap/leapclient/ConfigHelper.java | 3 ++- src/se/leap/leapclient/ConfigurationWizard.java | 14 +++++++++++++- src/se/leap/leapclient/ProviderDetailFragment.java | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index 10b3edf4..007db95c 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -178,7 +178,8 @@ public class ConfigHelper { public static JSONObject getJsonFromSharedPref(String shared_preferences_key) throws JSONException { JSONObject content = null; if ( checkSharedPrefs() ) { - content = new JSONObject( shared_preferences.getString(shared_preferences_key, "") ); + String json_string = shared_preferences.getString(shared_preferences_key, ""); + content = new JSONObject(json_string); } return content; diff --git a/src/se/leap/leapclient/ConfigurationWizard.java b/src/se/leap/leapclient/ConfigurationWizard.java index 23220e79..d12fdc77 100644 --- a/src/se/leap/leapclient/ConfigurationWizard.java +++ b/src/se/leap/leapclient/ConfigurationWizard.java @@ -154,10 +154,22 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn @Override public void onBackPressed() { + try { + if(ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY) == null || ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY).length() == 0) { + askDashboardToQuitApp(); + } else { + setResult(RESULT_OK); + } + } catch (JSONException e) { + askDashboardToQuitApp(); + } + super.onBackPressed(); + } + + private void askDashboardToQuitApp() { Intent ask_quit = new Intent(); ask_quit.putExtra(ConfigHelper.QUIT, ConfigHelper.QUIT); setResult(RESULT_CANCELED, ask_quit); - super.onBackPressed(); } private ProviderItem getProvider(String id) { diff --git a/src/se/leap/leapclient/ProviderDetailFragment.java b/src/se/leap/leapclient/ProviderDetailFragment.java index 0b707d3e..a788594f 100644 --- a/src/se/leap/leapclient/ProviderDetailFragment.java +++ b/src/se/leap/leapclient/ProviderDetailFragment.java @@ -79,6 +79,9 @@ public class ProviderDetailFragment extends DialogFragment { public void onCancel(DialogInterface dialog) { super.onCancel(dialog); ConfigHelper.removeFromSharedPref(ConfigHelper.PROVIDER_KEY); + ConfigHelper.removeFromSharedPref(ConfigHelper.DANGER_ON); + ConfigHelper.removeFromSharedPref(ConfigHelper.ALLOWED_ANON); + ConfigHelper.removeFromSharedPref(ConfigHelper.EIP_SERVICE_KEY); } public static DialogFragment newInstance() { -- cgit v1.2.3