From fb4333b3a5051b08d3a255000bb1b8331e2a1d43 Mon Sep 17 00:00:00 2001 From: Andrew Stadler Date: Fri, 24 Sep 2010 16:36:36 -0700 Subject: [PATCH] Allow spaces in passwords * Separate/identical fixes for incoming, outgoing, exchange * Unit tests * Some protocols will fail anyway (e.g. POP3) TODO: Some sort of warning (master only - won't backport that) Bug: 2981433 Change-Id: I82984e5912fc7fcb88e747815d0fe33cb36605e7 --- .../setup/AccountSetupExchangeFragment.java | 4 +- .../activity/setup/AccountSetupIncoming.java | 2 +- .../setup/AccountSetupIncomingFragment.java | 4 +- .../activity/setup/AccountSetupOutgoing.java | 2 +- .../setup/AccountSetupOutgoingFragment.java | 5 +- .../setup/AccountSetupExchangeTests.java | 44 ++++++++++++++++++ .../setup/AccountSetupIncomingTests.java | 46 ++++++++++++++++++- .../setup/AccountSetupOutgoingTests.java | 46 ++++++++++++++++++- 8 files changed, 142 insertions(+), 11 deletions(-) diff --git a/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java b/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java index d5dd10ff0..b9aa4091c 100644 --- a/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java @@ -336,7 +336,7 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment * a problem with the user input. * @return a URI built from the account setup fields */ - private URI getUri() throws URISyntaxException { + /* package */ URI getUri() throws URISyntaxException { boolean sslRequired = mSslSecurityView.isChecked(); boolean trustCertificates = mTrustCertificatesView.isChecked(); String scheme = (sslRequired) @@ -349,7 +349,7 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment userName = userName.substring(1); } mCacheLoginCredential = userName; - String userInfo = userName + ":" + mPasswordView.getText().toString().trim(); + String userInfo = userName + ":" + mPasswordView.getText(); String host = mServerView.getText().toString().trim(); String path = null; diff --git a/src/com/android/email/activity/setup/AccountSetupIncoming.java b/src/com/android/email/activity/setup/AccountSetupIncoming.java index 0801a9790..977304ae1 100644 --- a/src/com/android/email/activity/setup/AccountSetupIncoming.java +++ b/src/com/android/email/activity/setup/AccountSetupIncoming.java @@ -33,7 +33,7 @@ import android.os.Bundle; public class AccountSetupIncoming extends AccountSetupActivity implements AccountSetupIncomingFragment.Callback { - private AccountSetupIncomingFragment mFragment; + /* package */ AccountSetupIncomingFragment mFragment; /* package */ boolean mNextButtonEnabled; public static void actionIncomingSettings(Activity fromActivity, int mode, Account account) { diff --git a/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java b/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java index bc1030b88..3e39baf77 100644 --- a/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java @@ -414,7 +414,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { * a problem with the user input. * @return a URI built from the account setup fields */ - private URI getUri() throws URISyntaxException { + /* package */ URI getUri() throws URISyntaxException { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; String path = null; if (mAccountSchemes[securityType].startsWith("imap")) { @@ -424,7 +424,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { mCacheLoginCredential = userName; URI uri = new URI( mAccountSchemes[securityType], - userName + ":" + mPasswordView.getText().toString().trim(), + userName + ":" + mPasswordView.getText(), mServerView.getText().toString().trim(), Integer.parseInt(mPortView.getText().toString().trim()), path, // path diff --git a/src/com/android/email/activity/setup/AccountSetupOutgoing.java b/src/com/android/email/activity/setup/AccountSetupOutgoing.java index 828dc6874..869978ed6 100644 --- a/src/com/android/email/activity/setup/AccountSetupOutgoing.java +++ b/src/com/android/email/activity/setup/AccountSetupOutgoing.java @@ -33,7 +33,7 @@ import android.os.Bundle; public class AccountSetupOutgoing extends Activity implements AccountSetupOutgoingFragment.Callback { - private AccountSetupOutgoingFragment mFragment; + /* package */ AccountSetupOutgoingFragment mFragment; /* package */ boolean mNextButtonEnabled; public static void actionOutgoingSettings(Activity fromActivity, int mode, Account account) { diff --git a/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java b/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java index 90b46d053..603ec4712 100644 --- a/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java @@ -353,12 +353,11 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment * a problem with the user input. * @return a URI built from the account setup fields */ - private URI getUri() throws URISyntaxException { + /* package */ URI getUri() throws URISyntaxException { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; String userInfo = null; if (mRequireLoginView.isChecked()) { - userInfo = mUsernameView.getText().toString().trim() + ":" - + mPasswordView.getText().toString().trim(); + userInfo = mUsernameView.getText().toString().trim() + ":" + mPasswordView.getText(); } URI uri = new URI( SMTP_SCHEMES[securityType], diff --git a/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java b/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java index e800af505..5518ea4ad 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java @@ -30,6 +30,9 @@ import android.view.View; import android.widget.CheckBox; import android.widget.EditText; +import java.net.URI; +import java.net.URISyntaxException; + /** * Tests of the basic UI logic in the Account Setup Incoming (IMAP / POP3) screen. * You can run this entire test case with: @@ -40,7 +43,9 @@ public class AccountSetupExchangeTests extends ActivityInstrumentationTestCase2 { //EXCHANGE-REMOVE-SECTION-START private AccountSetupExchange mActivity; + private AccountSetupExchangeFragment mFragment; private EditText mServerView; + private EditText mPasswordView; private CheckBox mSslRequiredCheckbox; private CheckBox mTrustAllCertificatesCheckbox; //EXCHANGE-REMOVE-SECTION-END @@ -125,6 +130,43 @@ public class AccountSetupExchangeTests extends assertFalse(mActivity.mNextButtonEnabled); } + /** + * Test to confirm that passwords with leading or trailing spaces are accepted verbatim. + */ + @UiThreadTest + public void testPasswordNoTrim() throws URISyntaxException { + getActivityAndFields(); + + // Clear the password - should disable + checkPassword(null, false); + + // Various combinations of spaces should be OK + checkPassword(" leading", true); + checkPassword("trailing ", true); + checkPassword("em bedded", true); + checkPassword(" ", true); + } + + /** + * Check password field for a given password. Should be called in UI thread. Confirms that + * the password has not been trimmed. + * + * @param password the password to test with + * @param expectNext true if expected that this password will enable the "next" button + */ + private void checkPassword(String password, boolean expectNext) throws URISyntaxException { + mPasswordView.setText(password); + if (expectNext) { + assertTrue(mActivity.mNextButtonEnabled); + URI uri = mFragment.getUri(); + String actualUserInfo = uri.getUserInfo(); + String actualPassword = actualUserInfo.split(":", 2)[1]; + assertEquals(password, actualPassword); + } else { + assertFalse(mActivity.mNextButtonEnabled); + } + } + /** * Test aspects of loadSettings() * @@ -176,7 +218,9 @@ public class AccountSetupExchangeTests extends */ private void getActivityAndFields() { mActivity = getActivity(); + mFragment = mActivity.mFragment; mServerView = (EditText) mActivity.findViewById(R.id.account_server); + mPasswordView = (EditText) mActivity.findViewById(R.id.account_password); mSslRequiredCheckbox = (CheckBox) mActivity.findViewById(R.id.account_ssl); mTrustAllCertificatesCheckbox = (CheckBox) mActivity.findViewById(R.id.account_trust_certificates); diff --git a/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java b/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java index a496c3a97..4737be549 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java @@ -25,6 +25,9 @@ import android.test.UiThreadTest; import android.test.suitebuilder.annotation.MediumTest; import android.widget.EditText; +import java.net.URI; +import java.net.URISyntaxException; + /** * Tests of the basic UI logic in the Account Setup Incoming (IMAP / POP3) screen. * You can run this entire test case with: @@ -35,7 +38,9 @@ public class AccountSetupIncomingTests extends ActivityInstrumentationTestCase2 { private AccountSetupIncoming mActivity; + private AccountSetupIncomingFragment mFragment; private EditText mServerView; + private EditText mPasswordView; public AccountSetupIncomingTests() { super(AccountSetupIncoming.class); @@ -122,7 +127,44 @@ public class AccountSetupIncomingTests extends mServerView.setText("serv$er.com"); assertFalse(mActivity.mNextButtonEnabled); } - + + /** + * Test to confirm that passwords with leading or trailing spaces are accepted verbatim. + */ + @UiThreadTest + public void testPasswordNoTrim() throws URISyntaxException { + getActivityAndFields(); + + // Clear the password - should disable + checkPassword(null, false); + + // Various combinations of spaces should be OK + checkPassword(" leading", true); + checkPassword("trailing ", true); + checkPassword("em bedded", true); + checkPassword(" ", true); + } + + /** + * Check password field for a given password. Should be called in UI thread. Confirms that + * the password has not been trimmed. + * + * @param password the password to test with + * @param expectNext true if expected that this password will enable the "next" button + */ + private void checkPassword(String password, boolean expectNext) throws URISyntaxException { + mPasswordView.setText(password); + if (expectNext) { + assertTrue(mActivity.mNextButtonEnabled); + URI uri = mFragment.getUri(); + String actualUserInfo = uri.getUserInfo(); + String actualPassword = actualUserInfo.split(":", 2)[1]; + assertEquals(password, actualPassword); + } else { + assertFalse(mActivity.mNextButtonEnabled); + } + } + /** * TODO: A series of tests to explore the logic around security models & ports * TODO: A series of tests exploring differences between IMAP and POP3 @@ -133,7 +175,9 @@ public class AccountSetupIncomingTests extends */ private void getActivityAndFields() { mActivity = getActivity(); + mFragment = mActivity.mFragment; mServerView = (EditText) mActivity.findViewById(R.id.account_server); + mPasswordView = (EditText) mActivity.findViewById(R.id.account_password); } /** diff --git a/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java b/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java index 742c5d184..53984be6f 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java @@ -25,6 +25,9 @@ import android.test.UiThreadTest; import android.test.suitebuilder.annotation.MediumTest; import android.widget.EditText; +import java.net.URI; +import java.net.URISyntaxException; + /** * Tests of the basic UI logic in the Account Setup Outgoing (SMTP) screen. * You can run this entire test case with: @@ -35,7 +38,9 @@ public class AccountSetupOutgoingTests extends ActivityInstrumentationTestCase2 { private AccountSetupOutgoing mActivity; + private AccountSetupOutgoingFragment mFragment; private EditText mServerView; + private EditText mPasswordView; public AccountSetupOutgoingTests() { super(AccountSetupOutgoing.class); @@ -120,7 +125,44 @@ public class AccountSetupOutgoingTests extends mServerView.setText("serv$er.com"); assertFalse(mActivity.mNextButtonEnabled); } - + + /** + * Test to confirm that passwords with leading or trailing spaces are accepted verbatim. + */ + @UiThreadTest + public void testPasswordNoTrim() throws URISyntaxException { + getActivityAndFields(); + + // Clear the password - should disable + checkPassword(null, false); + + // Various combinations of spaces should be OK + checkPassword(" leading", true); + checkPassword("trailing ", true); + checkPassword("em bedded", true); + checkPassword(" ", true); + } + + /** + * Check password field for a given password. Should be called in UI thread. Confirms that + * the password has not been trimmed. + * + * @param password the password to test with + * @param expectNext true if expected that this password will enable the "next" button + */ + private void checkPassword(String password, boolean expectNext) throws URISyntaxException { + mPasswordView.setText(password); + if (expectNext) { + assertTrue(mActivity.mNextButtonEnabled); + URI uri = mFragment.getUri(); + String actualUserInfo = uri.getUserInfo(); + String actualPassword = actualUserInfo.split(":", 2)[1]; + assertEquals(password, actualPassword); + } else { + assertFalse(mActivity.mNextButtonEnabled); + } + } + /** * TODO: A series of tests to explore the logic around security models & ports */ @@ -130,7 +172,9 @@ public class AccountSetupOutgoingTests extends */ private void getActivityAndFields() { mActivity = getActivity(); + mFragment = mActivity.mFragment; mServerView = (EditText) mActivity.findViewById(R.id.account_server); + mPasswordView = (EditText) mActivity.findViewById(R.id.account_password); } /**