diff --git a/proguard.flags b/proguard.flags index 260fa125c..230aeb1f6 100644 --- a/proguard.flags +++ b/proguard.flags @@ -103,6 +103,10 @@ *** setRecipient(com.android.emailcommon.mail.Message$RecipientType, com.android.emailcommon.mail.Address); } +-keepclasseswithmembers class com.android.emailcommon.internet.MimeHeader { + *** writeToString(); +} + -keepclasseswithmembers class com.android.emailcommon.internet.MimeMessage { (); (java.io.InputStream); diff --git a/src/com/android/email/LegacyConversions.java b/src/com/android/email/LegacyConversions.java index e9acd4c33..c937fbc38 100644 --- a/src/com/android/email/LegacyConversions.java +++ b/src/com/android/email/LegacyConversions.java @@ -32,8 +32,10 @@ import com.android.emailcommon.mail.Message.RecipientType; import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Attachment; import com.android.emailcommon.provider.EmailContent.AttachmentColumns; +import com.android.emailcommon.provider.EmailContent.HostAuth; import com.android.emailcommon.provider.EmailContent.Mailbox; import com.android.emailcommon.utility.AttachmentUtilities; +import com.android.emailcommon.utility.Utility; import org.apache.commons.io.IOUtils; @@ -48,6 +50,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -519,8 +522,20 @@ public class LegacyConversions { result.mSecuritySyncKey = null; result.mSignature = fromAccount.mSignature; - result.setStoreUri(context, fromAccount.getStoreUri()); - result.setSenderUri(context, fromAccount.getSenderUri()); + try { + HostAuth recvAuth = result.getOrCreateHostAuthRecv(context); + Utility.setHostAuthFromString(recvAuth, fromAccount.getStoreUri()); + } catch (URISyntaxException e) { + result.mHostAuthRecv = new HostAuth(); + Log.w(Logging.LOG_TAG, e); + } + try { + HostAuth sendAuth = result.getOrCreateHostAuthSend(context); + Utility.setHostAuthFromString(sendAuth, fromAccount.getSenderUri()); + } catch (URISyntaxException e) { + result.mHostAuthSend = new HostAuth(); + Log.w(Logging.LOG_TAG, e); + } return result; } diff --git a/src/com/android/email/VendorPolicyLoader.java b/src/com/android/email/VendorPolicyLoader.java index a608015d5..f4e3613c9 100644 --- a/src/com/android/email/VendorPolicyLoader.java +++ b/src/com/android/email/VendorPolicyLoader.java @@ -219,20 +219,16 @@ public class VendorPolicyLoader { params.putString(FIND_PROVIDER, domain); Bundle out = getPolicy(FIND_PROVIDER, params); if (out != null && !out.isEmpty()) { - try { - Provider p = new Provider(); - p.id = null; - p.label = null; - p.domain = domain; - p.incomingUriTemplate = new URI(out.getString(FIND_PROVIDER_IN_URI)); - p.incomingUsernameTemplate = out.getString(FIND_PROVIDER_IN_USER); - p.outgoingUriTemplate = new URI(out.getString(FIND_PROVIDER_OUT_URI)); - p.outgoingUsernameTemplate = out.getString(FIND_PROVIDER_OUT_USER); - p.note = out.getString(FIND_PROVIDER_NOTE); - return p; - } catch (URISyntaxException e) { - Log.d(Logging.LOG_TAG, "uri exception while vendor policy loads " + domain); - } + Provider p = new Provider(); + p.id = null; + p.label = null; + p.domain = domain; + p.incomingUriTemplate = out.getString(FIND_PROVIDER_IN_URI); + p.incomingUsernameTemplate = out.getString(FIND_PROVIDER_IN_USER); + p.outgoingUriTemplate = out.getString(FIND_PROVIDER_OUT_URI); + p.outgoingUsernameTemplate = out.getString(FIND_PROVIDER_OUT_USER); + p.note = out.getString(FIND_PROVIDER_NOTE); + return p; } return null; } diff --git a/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java b/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java index 1eb4c1fd2..44e6061df 100644 --- a/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java +++ b/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java @@ -501,9 +501,10 @@ public class AccountCheckSettingsFragment extends Fragment { return new MessagingException(MessagingException.AUTHENTICATION_FAILED); } // Return "real" AD results - HostAuth serverInfo = new HostAuth(); - serverInfo.setStoreUri("eas://user:password@testserver.com"); - return new AutoDiscoverResults(false, serverInfo); + HostAuth auth = new HostAuth(); + auth.setLogin("user", "password"); + auth.setConnection(Store.STORE_SCHEME_EAS, "testserver.com", 0); + return new AutoDiscoverResults(false, auth); } if (isCancelled()) return null; if ((mMode & SetupData.CHECK_INCOMING) != 0) { @@ -632,6 +633,7 @@ public class AccountCheckSettingsFragment extends Fragment { * recreated at any time without affecting the account checking progress. */ public static class CheckingDialog extends DialogFragment { + @SuppressWarnings("hiding") public final static String TAG = "CheckProgressDialog"; // Extras for saved instance state @@ -729,6 +731,7 @@ public class AccountCheckSettingsFragment extends Fragment { * The standard error dialog. Calls back to onErrorDialogButton(). */ public static class ErrorDialog extends DialogFragment { + @SuppressWarnings("hiding") public final static String TAG = "ErrorDialog"; // Bundle keys for arguments @@ -784,6 +787,7 @@ public class AccountCheckSettingsFragment extends Fragment { * same as any other failed check.) */ public static class SecurityRequiredDialog extends DialogFragment { + @SuppressWarnings("hiding") public final static String TAG = "SecurityRequiredDialog"; // Bundle keys for arguments diff --git a/src/com/android/email/activity/setup/AccountServerBaseFragment.java b/src/com/android/email/activity/setup/AccountServerBaseFragment.java index be658b6dd..0909457fd 100644 --- a/src/com/android/email/activity/setup/AccountServerBaseFragment.java +++ b/src/com/android/email/activity/setup/AccountServerBaseFragment.java @@ -53,6 +53,7 @@ public abstract class AccountServerBaseFragment extends Fragment protected Context mContext; protected Callback mCallback = EmptyCallback.INSTANCE; protected boolean mSettingsMode; + // TODO See how to get rid of this. Maybe define an "equals()" for HostAuth? // The URI that represents this account's currently saved settings protected URI mLoadedUri; @@ -60,6 +61,7 @@ public abstract class AccountServerBaseFragment extends Fragment public Button mProceedButton; // This is used to debounce multiple clicks on the proceed button (which does async work) public boolean mProceedButtonPressed; + /*package*/ String mBaseScheme = "protocol"; /** * Callback interface that owning activities must provide diff --git a/src/com/android/email/activity/setup/AccountSettingsUtils.java b/src/com/android/email/activity/setup/AccountSettingsUtils.java index 0b5ded2df..0634fd26c 100644 --- a/src/com/android/email/activity/setup/AccountSettingsUtils.java +++ b/src/com/android/email/activity/setup/AccountSettingsUtils.java @@ -119,13 +119,13 @@ public class AccountSettingsUtils { else if (xmlEventType == XmlResourceParser.START_TAG && "incoming".equals(xml.getName()) && provider != null) { - provider.incomingUriTemplate = new URI(getXmlAttribute(context, xml, "uri")); + provider.incomingUriTemplate = getXmlAttribute(context, xml, "uri"); provider.incomingUsernameTemplate = getXmlAttribute(context, xml, "username"); } else if (xmlEventType == XmlResourceParser.START_TAG && "outgoing".equals(xml.getName()) && provider != null) { - provider.outgoingUriTemplate = new URI(getXmlAttribute(context, xml, "uri")); + provider.outgoingUriTemplate = getXmlAttribute(context, xml, "uri"); provider.outgoingUsernameTemplate = getXmlAttribute(context, xml, "username"); } else if (xmlEventType == XmlResourceParser.END_TAG @@ -164,9 +164,9 @@ public class AccountSettingsUtils { public String id; public String label; public String domain; - public URI incomingUriTemplate; + public String incomingUriTemplate; public String incomingUsernameTemplate; - public URI outgoingUriTemplate; + public String outgoingUriTemplate; public String outgoingUsernameTemplate; public String note; } diff --git a/src/com/android/email/activity/setup/AccountSetupAccountType.java b/src/com/android/email/activity/setup/AccountSetupAccountType.java index fa270c134..288dcecfd 100644 --- a/src/com/android/email/activity/setup/AccountSetupAccountType.java +++ b/src/com/android/email/activity/setup/AccountSetupAccountType.java @@ -116,24 +116,17 @@ public class AccountSetupAccountType extends AccountSetupActivity implements OnC } /** - * The user has selected an exchange account type. Try to put together a URI using the entered - * email address. Also set the mail delete policy here, because there is no UI (for exchange), - * and switch the default sync interval to "push". + * The user has selected an exchange account type. Set the mail delete policy here, because + * there is no UI (for exchange), and switch the default sync interval to "push". */ private void onExchange() { Account account = SetupData.getAccount(); - try { - URI uri = new URI(account.getStoreUri(this)); - uri = new URI("eas+ssl+", uri.getUserInfo(), uri.getHost(), uri.getPort(), - null, null, null); - account.setStoreUri(this, uri.toString()); - account.setSenderUri(this, uri.toString()); - } catch (URISyntaxException use) { - /* - * This should not happen. - */ - throw new Error(use); - } + HostAuth recvAuth = account.getOrCreateHostAuthRecv(this); + recvAuth.setConnection( + "eas", recvAuth.mAddress, recvAuth.mPort, recvAuth.mFlags | HostAuth.FLAG_SSL); + HostAuth sendAuth = account.getOrCreateHostAuthSend(this); + sendAuth.setConnection( + "eas", sendAuth.mAddress, sendAuth.mPort, sendAuth.mFlags | HostAuth.FLAG_SSL); // TODO: Confirm correct delete policy for exchange account.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE); account.setSyncInterval(Account.CHECK_INTERVAL_PUSH); diff --git a/src/com/android/email/activity/setup/AccountSetupBasics.java b/src/com/android/email/activity/setup/AccountSetupBasics.java index c2441d345..be59ab14d 100644 --- a/src/com/android/email/activity/setup/AccountSetupBasics.java +++ b/src/com/android/email/activity/setup/AccountSetupBasics.java @@ -22,6 +22,7 @@ import com.android.email.VendorPolicyLoader; import com.android.email.activity.ActivityHelper; import com.android.email.activity.Welcome; import com.android.email.activity.setup.AccountSettingsUtils.Provider; +import com.android.email.mail.Store; import com.android.emailcommon.Logging; import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Account; @@ -53,7 +54,6 @@ import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; -import java.net.URI; import java.net.URISyntaxException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -421,47 +421,40 @@ public class AccountSetupBasics extends AccountSetupActivity String[] emailParts = email.split("@"); String user = emailParts[0]; String domain = emailParts[1]; - URI incomingUri = null; - URI outgoingUri = null; - String incomingUsername = mProvider.incomingUsernameTemplate; + try { + String incomingUsername = mProvider.incomingUsernameTemplate; incomingUsername = incomingUsername.replaceAll("\\$email", email); incomingUsername = incomingUsername.replaceAll("\\$user", user); incomingUsername = incomingUsername.replaceAll("\\$domain", domain); - URI incomingUriTemplate = mProvider.incomingUriTemplate; - incomingUri = new URI(incomingUriTemplate.getScheme(), incomingUsername + ":" - + password, incomingUriTemplate.getHost(), incomingUriTemplate.getPort(), - incomingUriTemplate.getPath(), null, null); + Account account = SetupData.getAccount(); + HostAuth recvAuth = account.getOrCreateHostAuthRecv(this); + Utility.setHostAuthFromString(recvAuth, mProvider.incomingUriTemplate); String outgoingUsername = mProvider.outgoingUsernameTemplate; outgoingUsername = outgoingUsername.replaceAll("\\$email", email); outgoingUsername = outgoingUsername.replaceAll("\\$user", user); outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain); - URI outgoingUriTemplate = mProvider.outgoingUriTemplate; - outgoingUri = new URI(outgoingUriTemplate.getScheme(), outgoingUsername + ":" - + password, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), - outgoingUriTemplate.getPath(), null, null); + HostAuth sendAuth = account.getOrCreateHostAuthSend(this); + Utility.setHostAuthFromString(sendAuth, mProvider.outgoingUriTemplate); - } catch (URISyntaxException use) { + // Populate the setup data, assuming that the duplicate account check will succeed + populateSetupData(getOwnerName(), email, mDefaultView.isChecked()); + + // Stop here if the login credentials duplicate an existing account + // Launch an Async task to do the work + new DuplicateCheckTask(this, recvAuth.mAddress, incomingUsername).execute(); + } catch (URISyntaxException e) { /* - * If there is some problem with the URI we give up and go on to - * manual setup. Technically speaking, AutoDiscover is OK here, since user clicked - * "Next" to get here. This would never happen in practice because we don't expect - * to find any EAS accounts in the providers list. + * If there is some problem with the URI we give up and go on to manual setup. + * Technically speaking, AutoDiscover is OK here, since the user clicked "Next" + * to get here. This will not happen in practice because we don't expect to + * find any EAS accounts in the providers list. */ onManualSetup(true); - return; } - - // Populate the setup data, assuming that the duplicate account check will succeed - populateSetupData(getOwnerName(), email, mDefaultView.isChecked(), - incomingUri.toString(), outgoingUri.toString()); - - // Stop here if the login credentials duplicate an existing account - // Launch an Async task to do the work - new DuplicateCheckTask(this, incomingUri.getHost(), incomingUsername).execute(); } /** @@ -561,18 +554,16 @@ public class AccountSetupBasics extends AccountSetupActivity return; } - String uriString = null; - try { - URI uri = new URI("placeholder", user + ":" + password, domain, -1, null, null, null); - uriString = uri.toString(); - } catch (URISyntaxException use) { - // If we can't set up the URL, don't continue - account setup pages will fail too - Toast.makeText(this, R.string.account_setup_username_password_toast, - Toast.LENGTH_LONG).show(); - return; - } + Account account = SetupData.getAccount(); + HostAuth recvAuth = account.getOrCreateHostAuthRecv(this); + recvAuth.setLogin(user, password); + recvAuth.setConnection("placeholder", domain, HostAuth.PORT_UNKNOWN, HostAuth.FLAG_NONE); - populateSetupData(getOwnerName(), email, mDefaultView.isChecked(), uriString, uriString); + HostAuth sendAuth = account.getOrCreateHostAuthSend(this); + sendAuth.setLogin(user, password); + sendAuth.setConnection("placeholder", domain, HostAuth.PORT_UNKNOWN, HostAuth.FLAG_NONE); + + populateSetupData(getOwnerName(), email, mDefaultView.isChecked()); SetupData.setAllowAutodiscover(allowAutoDiscover); AccountSetupAccountType.actionSelectAccountType(this); @@ -590,31 +581,42 @@ public class AccountSetupBasics extends AccountSetupActivity * @param outgoing The URI-style string defining the outgoing account */ private void forceCreateAccount(String email, String user, String incoming, String outgoing) { - populateSetupData(user, email, false, incoming, outgoing); + Account account = SetupData.getAccount(); + try { + HostAuth recvAuth = account.getOrCreateHostAuthRecv(this); + Utility.setHostAuthFromString(recvAuth, incoming); + + HostAuth sendAuth = account.getOrCreateHostAuthSend(this); + Utility.setHostAuthFromString(sendAuth, outgoing); + + populateSetupData(user, email, false); + } catch (URISyntaxException e) { + // If we can't set up the URL, don't continue - account setup pages will fail too + Toast.makeText( + this, R.string.account_setup_username_password_toast, Toast.LENGTH_LONG).show(); + } } /** * Populate SetupData's account with complete setup info. */ - private void populateSetupData(String senderName, String senderEmail, boolean isDefault, - String incoming, String outgoing) { + private void populateSetupData(String senderName, String senderEmail, boolean isDefault) { Account account = SetupData.getAccount(); account.setSenderName(senderName); account.setEmailAddress(senderEmail); account.setDisplayName(senderEmail); account.setDefaultAccount(isDefault); SetupData.setDefault(isDefault); // TODO - why duplicated, if already set in account - account.setStoreUri(this, incoming); - account.setSenderUri(this, outgoing); - // Set sync and delete policies for specific account types - if (incoming.startsWith("imap")) { + String protocol = account.mHostAuthRecv.mProtocol; + // Set sync and delete policies for specific inbound account types + if (Store.STORE_SCHEME_IMAP.equals(protocol)) { // Delete policy must be set explicitly, because IMAP does not provide a UI selection // for it. This logic needs to be followed in the auto setup flow as well. account.setDeletePolicy(EmailContent.Account.DELETE_POLICY_ON_DELETE); } - if (incoming.startsWith("eas")) { + if (Store.STORE_SCHEME_EAS.equals(protocol)) { account.setSyncInterval(Account.CHECK_INTERVAL_PUSH); } else { account.setSyncInterval(DEFAULT_ACCOUNT_CHECK_INTERVAL); diff --git a/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java b/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java index a119bd6f7..26795e5a4 100644 --- a/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java @@ -20,8 +20,10 @@ import com.android.email.AccountBackupRestore; import com.android.email.Email; import com.android.email.ExchangeUtils; import com.android.email.R; +import com.android.email.mail.Store; import com.android.emailcommon.Device; import com.android.emailcommon.Logging; +import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Account; import com.android.emailcommon.provider.EmailContent.HostAuth; import com.android.emailcommon.utility.Utility; @@ -85,6 +87,7 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment mCacheLoginCredential = savedInstanceState.getString(STATE_KEY_CREDENTIAL); mLoaded = savedInstanceState.getBoolean(STATE_KEY_LOADED, false); } + mBaseScheme = Store.STORE_SCHEME_EAS; } @Override @@ -255,11 +258,13 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment } boolean ssl = 0 != (hostAuth.mFlags & HostAuth.FLAG_SSL); - boolean trustCertificates = 0 != (hostAuth.mFlags & HostAuth.FLAG_TRUST_ALL_CERTIFICATES); + boolean trustCertificates = 0 != (hostAuth.mFlags & HostAuth.FLAG_TRUST_ALL); mSslSecurityView.setChecked(ssl); mTrustCertificatesView.setChecked(trustCertificates); showTrustCertificates(ssl); + // TODO See how to get rid of this. Maybe define an "equals()" for HostAuth? + // used to determine if these settings have changed try { mLoadedUri = getUri(); } catch (URISyntaxException ignore) { @@ -357,11 +362,9 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment */ @Override protected URI getUri() throws URISyntaxException { + Account account = SetupData.getAccount(); boolean sslRequired = mSslSecurityView.isChecked(); boolean trustCertificates = mTrustCertificatesView.isChecked(); - String scheme = (sslRequired) - ? (trustCertificates ? "eas+ssl+trustallcerts" : "eas+ssl+") - : "eas"; String userName = mUsernameView.getText().toString().trim(); // Remove a leading backslash, if there is one, since we now automatically put one at // the start of the username field @@ -372,16 +375,18 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment String userInfo = userName + ":" + mPasswordView.getText(); String host = mServerView.getText().toString().trim(); String path = null; + int port = mSslSecurityView.isChecked() ? 443 : 80; + // Ensure TLS is not set + int flags = account.getOrCreateHostAuthRecv(mContext).mFlags & ~HostAuth.FLAG_TLS; URI uri = new URI( - scheme, + HostAuth.getSchemeString(mBaseScheme, flags), userInfo, host, - 0, + port, path, null, null); - return uri; } @@ -399,21 +404,38 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment */ @Override public void onNext() { - try { - URI uri = getUri(); - Account setupAccount = SetupData.getAccount(); - setupAccount.setStoreUri(mContext, uri.toString()); - setupAccount.setSenderUri(mContext, uri.toString()); + EmailContent.Account account = SetupData.getAccount(); - // Check for a duplicate account (requires async DB work) and if OK, proceed with check - startDuplicateTaskCheck(setupAccount.mId, uri.getHost(), mCacheLoginCredential, - SetupData.CHECK_INCOMING); - } catch (URISyntaxException use) { - /* - * It's unrecoverable if we cannot create a URI from components that - * we validated to be safe. - */ - throw new Error(use); + String userName = mUsernameView.getText().toString().trim(); + if (userName.startsWith("\\")) { + userName = userName.substring(1); } + mCacheLoginCredential = userName; + String userPassword = mPasswordView.getText().toString(); + + int flags = 0; + if (mSslSecurityView.isChecked()) { + flags |= HostAuth.FLAG_SSL; + } + if (mTrustCertificatesView.isChecked()) { + flags |= HostAuth.FLAG_TRUST_ALL; + } + String serverAddress = mServerView.getText().toString().trim(); + + int port = mSslSecurityView.isChecked() ? 443 : 80; + HostAuth sendAuth = account.getOrCreateHostAuthSend(mContext); + sendAuth.setLogin(userName, userPassword); + sendAuth.setConnection(mBaseScheme, serverAddress, port, flags); + sendAuth.mDomain = null; + + HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext); + recvAuth.setLogin(userName, userPassword); + recvAuth.setConnection(mBaseScheme, serverAddress, port, flags); + recvAuth.mDomain = null; + + // Check for a duplicate account (requires async DB work) and if OK, proceed with check + startDuplicateTaskCheck(account.mId, serverAddress, mCacheLoginCredential, + SetupData.CHECK_INCOMING); } + } diff --git a/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java b/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java index 9ba275076..ff5eaf223 100644 --- a/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupIncomingFragment.java @@ -19,9 +19,10 @@ package com.android.email.activity.setup; import com.android.email.AccountBackupRestore; import com.android.email.Email; import com.android.email.R; +import com.android.email.mail.Store; import com.android.emailcommon.Logging; -import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Account; +import com.android.emailcommon.provider.EmailContent.HostAuth; import com.android.emailcommon.utility.Utility; import android.app.Activity; @@ -54,21 +55,12 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { private final static String STATE_KEY_CREDENTIAL = "AccountSetupIncomingFragment.credential"; private final static String STATE_KEY_LOADED = "AccountSetupIncomingFragment.loaded"; - private static final int POP_PORTS[] = { - 110, 995, 995, 110, 110 - }; - private static final String POP_SCHEMES[] = { - "pop3", "pop3+ssl+", "pop3+ssl+trustallcerts", "pop3+tls+", "pop3+tls+trustallcerts" - }; - private static final int IMAP_PORTS[] = { - 143, 993, 993, 143, 143 - }; - private static final String IMAP_SCHEMES[] = { - "imap", "imap+ssl+", "imap+ssl+trustallcerts", "imap+tls+", "imap+tls+trustallcerts" - }; + private static final int POP3_PORT_NORMAL = 110; + private static final int POP3_PORT_SSL = 995; + + private static final int IMAP_PORT_NORMAL = 143; + private static final int IMAP_PORT_SSL = 993; - private int mAccountPorts[]; - private String mAccountSchemes[]; private EditText mUsernameView; private EditText mPasswordView; private TextView mServerLabelView; @@ -131,18 +123,16 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { // Set up spinners SpinnerOption securityTypes[] = { - new SpinnerOption(0, - context.getString(R.string.account_setup_incoming_security_none_label)), - new SpinnerOption(1, - context.getString(R.string.account_setup_incoming_security_ssl_label)), - new SpinnerOption(2, - context.getString( - R.string.account_setup_incoming_security_ssl_trust_certificates_label)), - new SpinnerOption(3, - context.getString(R.string.account_setup_incoming_security_tls_label)), - new SpinnerOption(4, - context.getString( - R.string.account_setup_incoming_security_tls_trust_certificates_label)), + new SpinnerOption(HostAuth.FLAG_NONE, context.getString( + R.string.account_setup_incoming_security_none_label)), + new SpinnerOption(HostAuth.FLAG_SSL, context.getString( + R.string.account_setup_incoming_security_ssl_label)), + new SpinnerOption(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, context.getString( + R.string.account_setup_incoming_security_ssl_trust_certificates_label)), + new SpinnerOption(HostAuth.FLAG_TLS, context.getString( + R.string.account_setup_incoming_security_tls_label)), + new SpinnerOption(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL, context.getString( + R.string.account_setup_incoming_security_tls_trust_certificates_label)), }; SpinnerOption deletePolicies[] = { @@ -290,16 +280,12 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { private void configureEditor() { if (mConfigured) return; Account account = SetupData.getAccount(); - String protocol = account.mHostAuthRecv.mProtocol; - if (protocol.startsWith("pop3")) { + mBaseScheme = account.mHostAuthRecv.mProtocol; + if (Store.STORE_SCHEME_POP3.equals(mBaseScheme)) { mServerLabelView.setText(R.string.account_setup_incoming_pop_server_label); - mAccountPorts = POP_PORTS; - mAccountSchemes = POP_SCHEMES; mImapPathPrefixSectionView.setVisibility(View.GONE); - } else if (protocol.startsWith("imap")) { + } else if (Store.STORE_SCHEME_IMAP.equals(mBaseScheme)) { mServerLabelView.setText(R.string.account_setup_incoming_imap_server_label); - mAccountPorts = IMAP_PORTS; - mAccountSchemes = IMAP_SCHEMES; mDeletePolicyLabelView.setVisibility(View.GONE); mDeletePolicyView.setVisibility(View.GONE); } else { @@ -313,61 +299,49 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { */ private void loadSettings() { if (mLoaded) return; - try { - // TODO this should be accessed directly via the HostAuth structure - EmailContent.Account account = SetupData.getAccount(); - URI uri = new URI(account.getStoreUri(mContext)); - String username = null; - String password = null; - if (uri.getUserInfo() != null) { - String[] userInfoParts = uri.getUserInfo().split(":", 2); - username = userInfoParts[0]; - if (userInfoParts.length > 1) { - password = userInfoParts[1]; - } - } - if (username != null) { - mUsernameView.setText(username); - } + Account account = SetupData.getAccount(); + HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext); - if (password != null) { - mPasswordView.setText(password); - } - - if (uri.getScheme().startsWith("pop3")) { - mLoadedDeletePolicy = account.getDeletePolicy(); - SpinnerOption.setSpinnerOptionValue(mDeletePolicyView, mLoadedDeletePolicy); - } else if (uri.getScheme().startsWith("imap")) { - if (uri.getPath() != null && uri.getPath().length() > 0) { - mImapPathPrefixView.setText(uri.getPath().substring(1)); - } - } else { - throw new Error("Unknown account type: " + account.getStoreUri(mContext)); - } - - for (int i = 0; i < mAccountSchemes.length; i++) { - if (mAccountSchemes[i].equals(uri.getScheme())) { - SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, i); - } - } - - if (uri.getHost() != null) { - mServerView.setText(uri.getHost()); - } - - if (uri.getPort() != -1) { - mPortView.setText(Integer.toString(uri.getPort())); - } else { - updatePortFromSecurityType(); - } - } catch (URISyntaxException use) { - /* - * We should always be able to parse our own settings. - */ - throw new Error(use); + String username = recvAuth.mLogin; + if (username != null) { + mUsernameView.setText(username); + } + String password = recvAuth.mPassword; + if (password != null) { + mPasswordView.setText(password); } + if (Store.STORE_SCHEME_POP3.equals(recvAuth.mProtocol)) { + mLoadedDeletePolicy = account.getDeletePolicy(); + SpinnerOption.setSpinnerOptionValue(mDeletePolicyView, mLoadedDeletePolicy); + } else if (Store.STORE_SCHEME_IMAP.equals(recvAuth.mProtocol)) { + String prefix = recvAuth.mDomain; + if (prefix != null && prefix.length() > 0) { + mImapPathPrefixView.setText(prefix.substring(1)); + } + } else { + throw new Error("Unknown account type: " + account.getStoreUri(mContext)); + } + + int flags = recvAuth.mFlags; + flags &= ~HostAuth.FLAG_AUTHENTICATE; + SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, flags); + + String hostname = recvAuth.mAddress; + if (hostname != null) { + mServerView.setText(hostname); + } + + int port = recvAuth.mPort; + if (port != HostAuth.PORT_UNKNOWN) { + mPortView.setText(Integer.toString(port)); + } else { + updatePortFromSecurityType(); + } + + // TODO See how to get rid of this. Maybe define an "equals()" for HostAuth? + // used to determine if these settings have changed try { mLoadedUri = getUri(); } catch (URISyntaxException ignore) { @@ -400,9 +374,19 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { AccountSettingsUtils.checkPasswordSpaces(mContext, mPasswordView); } - private void updatePortFromSecurityType() { + private int getPortFromSecurityType() { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; - mPortView.setText(Integer.toString(mAccountPorts[securityType])); + boolean useSsl = ((securityType & HostAuth.FLAG_SSL) != 0); + int port = useSsl ? IMAP_PORT_SSL : IMAP_PORT_NORMAL; // default to IMAP + if (Store.STORE_SCHEME_POP3.equals(mBaseScheme)) { + port = useSsl ? POP3_PORT_SSL : POP3_PORT_NORMAL; + } + return port; + } + + private void updatePortFromSecurityType() { + int port = getPortFromSecurityType(); + mPortView.setText(Integer.toString(port)); } /** @@ -425,28 +409,16 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { */ @Override public void saveSettingsAfterSetup() { - EmailContent.Account account = SetupData.getAccount(); + Account account = SetupData.getAccount(); + HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext); + HostAuth sendAuth = account.getOrCreateHostAuthSend(mContext); // Set the username and password for the outgoing settings to the username and // password the user just set for incoming. Use the verified host address to try and // pick a smarter outgoing address. - try { - String hostName = - AccountSettingsUtils.inferServerName(account.mHostAuthRecv.mAddress, null, "smtp"); - URI oldUri = new URI(account.getSenderUri(mContext)); - URI uri = new URI( - oldUri.getScheme(), - mUsernameView.getText().toString().trim() + ":" - + mPasswordView.getText().toString(), - hostName, - oldUri.getPort(), - null, - null, - null); - account.setSenderUri(mContext, uri.toString()); - } catch (URISyntaxException use) { - // If we can't set up the URL we just continue. It's only for convenience. - } + String hostName = AccountSettingsUtils.inferServerName(recvAuth.mAddress, null, "smtp"); + sendAuth.setLogin(recvAuth.mLogin, recvAuth.mPassword); + sendAuth.setConnection(sendAuth.mProtocol, hostName, sendAuth.mPort, sendAuth.mFlags); } /** @@ -458,20 +430,23 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { protected URI getUri() throws URISyntaxException { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; String path = null; - if (mAccountSchemes[securityType].startsWith("imap")) { + if (Store.STORE_SCHEME_IMAP.equals(mBaseScheme)) { path = "/" + mImapPathPrefixView.getText().toString().trim(); } String userName = mUsernameView.getText().toString().trim(); mCacheLoginCredential = userName; + String userInfo = userName + ":" + mPasswordView.getText(); + String host = mServerView.getText().toString().trim(); + int port = Integer.parseInt(mPortView.getText().toString().trim()); + URI uri = new URI( - mAccountSchemes[securityType], - userName + ":" + mPasswordView.getText(), - mServerView.getText().toString().trim(), - Integer.parseInt(mPortView.getText().toString().trim()), + HostAuth.getSchemeString(mBaseScheme, securityType), + userInfo, + host, + port, path, // path null, // query null); - return uri; } @@ -480,25 +455,32 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment { */ @Override public void onNext() { - EmailContent.Account setupAccount = SetupData.getAccount(); + Account account = SetupData.getAccount(); - setupAccount.setDeletePolicy( - (Integer)((SpinnerOption)mDeletePolicyView.getSelectedItem()).value); + account.setDeletePolicy( + (Integer) ((SpinnerOption) mDeletePolicyView.getSelectedItem()).value); + HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext); + String userName = mUsernameView.getText().toString().trim(); + String userPassword = mPasswordView.getText().toString(); + recvAuth.setLogin(userName, userPassword); + + String serverAddress = mServerView.getText().toString().trim(); + int serverPort; try { - URI uri = getUri(); - setupAccount.setStoreUri(mContext, uri.toString()); - - // Check for a duplicate account (requires async DB work) and if OK, proceed with check - startDuplicateTaskCheck(setupAccount.mId, uri.getHost(), mCacheLoginCredential, - SetupData.CHECK_INCOMING); - } catch (URISyntaxException use) { - /* - * It's unrecoverable if we cannot create a URI from components that - * we validated to be safe. - */ - throw new Error(use); + serverPort = Integer.parseInt(mPortView.getText().toString().trim()); + } catch (NumberFormatException e) { + serverPort = getPortFromSecurityType(); + Log.d(Logging.LOG_TAG, "Non-integer server port; using '" + serverPort + "'"); } + int securityType = (Integer) ((SpinnerOption) mSecurityTypeView.getSelectedItem()).value; + recvAuth.setConnection(mBaseScheme, serverAddress, serverPort, securityType); + recvAuth.mDomain = null; + + // Check for a duplicate account (requires async DB work) and if OK, + // proceed with check + startDuplicateTaskCheck( + account.mId, serverAddress, mCacheLoginCredential, SetupData.CHECK_INCOMING); } @Override diff --git a/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java b/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java index 824bb4f65..e19593d6b 100644 --- a/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupOutgoingFragment.java @@ -22,6 +22,7 @@ import com.android.email.R; import com.android.emailcommon.Logging; import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Account; +import com.android.emailcommon.provider.EmailContent.HostAuth; import com.android.emailcommon.utility.Utility; import android.app.Activity; @@ -56,13 +57,8 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment private final static String STATE_KEY_LOADED = "AccountSetupOutgoingFragment.loaded"; - private static final int SMTP_PORTS[] = { - 587, 465, 465, 587, 587 - }; - - private static final String SMTP_SCHEMES[] = { - "smtp", "smtp+ssl+", "smtp+ssl+trustallcerts", "smtp+tls+", "smtp+tls+trustallcerts" - }; + private static final int SMTP_PORT_NORMAL = 587; + private static final int SMTP_PORT_SSL = 465; private EditText mUsernameView; private EditText mPasswordView; @@ -91,6 +87,7 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment if (savedInstanceState != null) { mLoaded = savedInstanceState.getBoolean(STATE_KEY_LOADED, false); } + mBaseScheme = "smtp"; } @Override @@ -118,15 +115,15 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment // Note: Strings are shared with AccountSetupIncomingFragment SpinnerOption securityTypes[] = { - new SpinnerOption(0, context.getString( + new SpinnerOption(HostAuth.FLAG_NONE, context.getString( R.string.account_setup_incoming_security_none_label)), - new SpinnerOption(1, context.getString( + new SpinnerOption(HostAuth.FLAG_SSL, context.getString( R.string.account_setup_incoming_security_ssl_label)), - new SpinnerOption(2, context.getString( + new SpinnerOption(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, context.getString( R.string.account_setup_incoming_security_ssl_trust_certificates_label)), - new SpinnerOption(3, context.getString( + new SpinnerOption(HostAuth.FLAG_TLS, context.getString( R.string.account_setup_incoming_security_tls_label)), - new SpinnerOption(4, context.getString( + new SpinnerOption(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, context.getString( R.string.account_setup_incoming_security_tls_trust_certificates_label)), }; @@ -258,50 +255,38 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment */ private void loadSettings() { if (mLoaded) return; - try { - // TODO this should be accessed directly via the HostAuth structure - URI uri = new URI(SetupData.getAccount().getSenderUri(mContext)); - String username = null; - String password = null; - if (uri.getUserInfo() != null) { - String[] userInfoParts = uri.getUserInfo().split(":", 2); - username = userInfoParts[0]; - if (userInfoParts.length > 1) { - password = userInfoParts[1]; - } - } + HostAuth senderAuth = SetupData.getAccount().getOrCreateHostAuthSend(mContext); + if ((senderAuth.mFlags & HostAuth.FLAG_AUTHENTICATE) != 0) { + String username = senderAuth.mLogin; if (username != null) { mUsernameView.setText(username); mRequireLoginView.setChecked(true); } + String password = senderAuth.mPassword; if (password != null) { mPasswordView.setText(password); } - - for (int i = 0; i < SMTP_SCHEMES.length; i++) { - if (SMTP_SCHEMES[i].equals(uri.getScheme())) { - SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, i); - } - } - - if (uri.getHost() != null) { - mServerView.setText(uri.getHost()); - } - - if (uri.getPort() != -1) { - mPortView.setText(Integer.toString(uri.getPort())); - } else { - updatePortFromSecurityType(); - } - } catch (URISyntaxException use) { - /* - * We should always be able to parse our own settings. - */ - throw new Error(use); } + int flags = senderAuth.mFlags & ~HostAuth.FLAG_AUTHENTICATE; + SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, flags); + + String hostname = senderAuth.mAddress; + if (hostname != null) { + mServerView.setText(hostname); + } + + int port = senderAuth.mPort; + if (port != -1) { + mPortView.setText(Integer.toString(port)); + } else { + updatePortFromSecurityType(); + } + + // TODO See how to get rid of this. Maybe define an "equals()" for HostAuth? + // used to determine if these settings have changed try { mLoadedUri = getUri(); } catch (URISyntaxException ignore) { @@ -350,9 +335,15 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment validateFields(); } - private void updatePortFromSecurityType() { + private int getPortFromSecurityType() { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; - mPortView.setText(Integer.toString(SMTP_PORTS[securityType])); + int port = (securityType & HostAuth.FLAG_SSL) != 0 ? SMTP_PORT_SSL : SMTP_PORT_NORMAL; + return port; + } + + private void updatePortFromSecurityType() { + int port = getPortFromSecurityType(); + mPortView.setText(Integer.toString(port)); } /** @@ -386,12 +377,18 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment if (mRequireLoginView.isChecked()) { userInfo = mUsernameView.getText().toString().trim() + ":" + mPasswordView.getText(); } + String host = mServerView.getText().toString().trim(); + String path = null; + int port = Integer.parseInt(mPortView.getText().toString().trim()); + URI uri = new URI( - SMTP_SCHEMES[securityType], + HostAuth.getSchemeString(mBaseScheme, securityType), userInfo, - mServerView.getText().toString().trim(), - Integer.parseInt(mPortView.getText().toString().trim()), - null, null, null); + host, + port, + path, + null, + null); return uri; } @@ -401,17 +398,23 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment @Override public void onNext() { EmailContent.Account account = SetupData.getAccount(); + HostAuth sendAuth = account.getOrCreateHostAuthSend(mContext); + + String userName = mUsernameView.getText().toString().trim(); + String userPassword = mPasswordView.getText().toString(); + sendAuth.setLogin(userName, userPassword); + + String serverAddress = mServerView.getText().toString().trim(); + int serverPort; try { - // TODO this should be accessed directly via the HostAuth structure - URI uri = getUri(); - account.setSenderUri(mContext, uri.toString()); - } catch (URISyntaxException use) { - /* - * It's unrecoverable if we cannot create a URI from components that - * we validated to be safe. - */ - throw new Error(use); + serverPort = Integer.parseInt(mPortView.getText().toString().trim()); + } catch (NumberFormatException e) { + serverPort = getPortFromSecurityType(); + Log.d(Logging.LOG_TAG, "Non-integer server port; using '" + serverPort + "'"); } + int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; + sendAuth.setConnection(mBaseScheme, serverAddress, serverPort, securityType); + sendAuth.mDomain = null; mCallback.onProceedNext(SetupData.CHECK_OUTGOING, this); } diff --git a/src/com/android/emailcommon/provider/EmailContent.java b/src/com/android/emailcommon/provider/EmailContent.java index 3ea955c9a..91dfd653f 100644 --- a/src/com/android/emailcommon/provider/EmailContent.java +++ b/src/com/android/emailcommon/provider/EmailContent.java @@ -32,6 +32,7 @@ import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; +import android.text.TextUtils; import java.io.File; import java.net.URI; @@ -454,6 +455,7 @@ public abstract class EmailContent { public static final String DELETED_TABLE_NAME = "Message_Deletes"; // To refer to a specific message, use ContentUris.withAppendedId(CONTENT_URI, id) + @SuppressWarnings("hiding") public static final Uri CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/message"); public static final Uri CONTENT_URI_LIMIT_1 = uriWithLimit(CONTENT_URI, 1); public static final Uri SYNCED_CONTENT_URI = @@ -965,6 +967,7 @@ public abstract class EmailContent { public static final class Account extends EmailContent implements AccountColumns, Parcelable { public static final String TABLE_NAME = "Account"; + @SuppressWarnings("hiding") public static final Uri CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/account"); public static final Uri ADD_TO_FIELD_URI = Uri.parse(EmailContent.CONTENT_URI + "/accountIdAddToField"); @@ -1353,37 +1356,7 @@ public abstract class EmailContent { return ""; } - /** - * For compatibility while converting to provider model, set the store URI - * - * @param context - * @param storeUri the new value - */ - @Deprecated - public void setStoreUri(Context context, String storeUri) { - // reconstitute or create if necessary - if (mHostAuthRecv == null) { - if (mHostAuthKeyRecv != 0) { - mHostAuthRecv = HostAuth.restoreHostAuthWithId(context, mHostAuthKeyRecv); - } else { - mHostAuthRecv = new EmailContent.HostAuth(); - } - } - - if (mHostAuthRecv != null) { - mHostAuthRecv.setStoreUri(storeUri); - } - } - - /** - * For compatibility while converting to provider model, set the sender URI - * - * @param context - * @param senderUri the new value - */ - @Deprecated - public void setSenderUri(Context context, String senderUri) { - // reconstitute or create if necessary + public HostAuth getOrCreateHostAuthSend(Context context) { if (mHostAuthSend == null) { if (mHostAuthKeySend != 0) { mHostAuthSend = HostAuth.restoreHostAuthWithId(context, mHostAuthKeySend); @@ -1391,10 +1364,18 @@ public abstract class EmailContent { mHostAuthSend = new EmailContent.HostAuth(); } } + return mHostAuthSend; + } - if (mHostAuthSend != null) { - mHostAuthSend.setStoreUri(senderUri); + public HostAuth getOrCreateHostAuthRecv(Context context) { + if (mHostAuthRecv == null) { + if (mHostAuthKeyRecv != 0) { + mHostAuthRecv = HostAuth.restoreHostAuthWithId(context, mHostAuthKeyRecv); + } else { + mHostAuthRecv = new EmailContent.HostAuth(); + } } + return mHostAuthRecv; } /** @@ -2569,10 +2550,15 @@ public abstract class EmailContent { @SuppressWarnings("hiding") public static final Uri CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/hostauth"); - public static final int FLAG_SSL = 1; - public static final int FLAG_TLS = 2; - public static final int FLAG_AUTHENTICATE = 4; - public static final int FLAG_TRUST_ALL_CERTIFICATES = 8; + public static final int PORT_UNKNOWN = -1; + + public static final int FLAG_NONE = 0x00; // No flags + public static final int FLAG_SSL = 0x01; // Use SSL + public static final int FLAG_TLS = 0x02; // Use TLS + public static final int FLAG_AUTHENTICATE = 0x04; // Use name/password for authentication + public static final int FLAG_TRUST_ALL = 0x08; // Trust all certificates + // Mask of settings directly configurable by the user + public static final int USER_CONFIG_MASK = 0x0b; public String mProtocol; public String mAddress; @@ -2581,6 +2567,7 @@ public abstract class EmailContent { public String mLogin; public String mPassword; public String mDomain; + // TODO Remove all vestiges of this public long mAccountKey; // DEPRECATED - Will not be set or stored public static final int CONTENT_ID_COLUMN = 0; @@ -2607,7 +2594,7 @@ public abstract class EmailContent { mBaseUri = CONTENT_URI; // other defaults policy) - mPort = -1; + mPort = PORT_UNKNOWN; } /** @@ -2632,6 +2619,52 @@ public abstract class EmailContent { } } + + /** + * Returns the scheme for the specified flags. + */ + public static String getSchemeString(String protocol, int flags) { + String security = ""; + switch (flags & USER_CONFIG_MASK) { + case FLAG_SSL: + security = "+ssl+"; + break; + case FLAG_SSL | FLAG_TRUST_ALL: + security = "+ssl+trustallcerts"; + break; + case FLAG_TLS: + security = "+tls+"; + break; + case FLAG_TLS | FLAG_TRUST_ALL: + security = "+tls+trustallcerts"; + break; + } + return protocol + security; + } + + /** + * Returns the flags for the specified scheme. + */ + public static int getSchemeFlags(String scheme) { + String[] schemeParts = scheme.split("\\+"); + int flags = HostAuth.FLAG_NONE; + if (schemeParts.length >= 2) { + String part1 = schemeParts[1]; + if ("ssl".equals(part1)) { + flags |= HostAuth.FLAG_SSL; + } else if ("tls".equals(part1)) { + flags |= HostAuth.FLAG_TLS; + } + if (schemeParts.length >= 3) { + String part2 = schemeParts[2]; + if ("trustallcerts".equals(part2)) { + flags |= HostAuth.FLAG_TRUST_ALL; + } + } + } + return flags; + } + @Override public void restore(Cursor cursor) { mBaseUri = CONTENT_URI; @@ -2667,37 +2700,20 @@ public abstract class EmailContent { * @return a string in the form of a Uri, as used by the other parts of the email app */ public String getStoreUri() { - String security; - switch (mFlags & (FLAG_SSL | FLAG_TLS | FLAG_TRUST_ALL_CERTIFICATES)) { - case FLAG_SSL: - security = "+ssl+"; - break; - case FLAG_SSL | FLAG_TRUST_ALL_CERTIFICATES: - security = "+ssl+trustallcerts"; - break; - case FLAG_TLS: - security = "+tls+"; - break; - case FLAG_TLS | FLAG_TRUST_ALL_CERTIFICATES: - security = "+tls+trustallcerts"; - break; - default: - security = ""; - break; - } String userInfo = null; if ((mFlags & FLAG_AUTHENTICATE) != 0) { String trimUser = (mLogin != null) ? mLogin.trim() : ""; String password = (mPassword != null) ? mPassword : ""; userInfo = trimUser + ":" + password; } + String scheme = getSchemeString(mProtocol, mFlags); String address = (mAddress != null) ? mAddress.trim() : null; String path = (mDomain != null) ? "/" + mDomain : null; URI uri; try { uri = new URI( - mProtocol + security, + scheme, userInfo, address, mPort, @@ -2711,77 +2727,73 @@ public abstract class EmailContent { } /** - * For compatibility while converting to provider model, set fields from a "store URI" - * - * @param uriString a String containing a Uri + * Sets the user name and password from URI user info string */ - @Deprecated - public void setStoreUri(String uriString) { - try { - URI uri = new URI(uriString); - mLogin = null; - mPassword = null; - mFlags &= ~FLAG_AUTHENTICATE; - if (uri.getUserInfo() != null) { - String[] userInfoParts = uri.getUserInfo().split(":", 2); - mLogin = userInfoParts[0]; - mFlags |= FLAG_AUTHENTICATE; - if (userInfoParts.length > 1) { - mPassword = userInfoParts[1]; - } + public void setLogin(String userInfo) { + String userName = null; + String userPassword = null; + if (!TextUtils.isEmpty(userInfo)) { + String[] userInfoParts = userInfo.split(":", 2); + userName = userInfoParts[0]; + if (userInfoParts.length > 1) { + userPassword = userInfoParts[1]; } - - // Set protocol, security, and additional flags based on uri scheme - String[] schemeParts = uri.getScheme().split("\\+"); - mProtocol = (schemeParts.length >= 1) ? schemeParts[0] : null; - mFlags &= ~(FLAG_SSL | FLAG_TLS | FLAG_TRUST_ALL_CERTIFICATES); - boolean ssl = false; - if (schemeParts.length >= 2) { - String part1 = schemeParts[1]; - if ("ssl".equals(part1)) { - ssl = true; - mFlags |= FLAG_SSL; - } else if ("tls".equals(part1)) { - mFlags |= FLAG_TLS; - } - if (schemeParts.length >= 3) { - String part2 = schemeParts[2]; - if ("trustallcerts".equals(part2)) { - mFlags |= FLAG_TRUST_ALL_CERTIFICATES; - } - } - } - - mAddress = uri.getHost(); - mPort = uri.getPort(); - if (mPort == -1) { - // infer port# from protocol + security - // SSL implies a different port - TLS runs in the "regular" port - // TODO: This really shouldn't be here - it should have been set up - // in the account setup screens. - if ("pop3".equals(mProtocol)) { - mPort = ssl ? 995 : 110; - } else if ("imap".equals(mProtocol)) { - mPort = ssl ? 993 : 143; - } else if ("eas".equals(mProtocol)) { - mPort = ssl ? 443 : 80; - } else if ("smtp".equals(mProtocol)) { - mPort = ssl ? 465 : 587; - } - } - - if (uri.getPath() != null && uri.getPath().length() > 0) { - mDomain = uri.getPath().substring(1); - } - - - } catch (URISyntaxException use) { - /* - * We should always be able to parse our own settings. - */ - throw new Error(use); } + setLogin(userName, userPassword); + } + /** + * Sets the user name and password + */ + public void setLogin(String userName, String userPassword) { + mLogin = userName; + mPassword = userPassword; + + if (mLogin == null) { + mFlags &= ~FLAG_AUTHENTICATE; + } else { + mFlags |= FLAG_AUTHENTICATE; + } + } + + /** + * Sets the connection values of the auth structure per the given scheme, host and port. + */ + public void setConnection(String scheme, String host, int port) { + String[] schemeParts = scheme.split("\\+"); + String protocol = schemeParts[0]; + int flags = getSchemeFlags(scheme); + + setConnection(protocol, host, port, flags); + } + + public void setConnection(String protocol, String address, int port, int flags) { + // Set protocol, security, and additional flags based on uri scheme + mProtocol = protocol; + + mFlags &= ~(FLAG_SSL | FLAG_TLS | FLAG_TRUST_ALL); + mFlags |= (flags & USER_CONFIG_MASK); + + mAddress = address; + mPort = port; + if (mPort == PORT_UNKNOWN) { + boolean useSSL = ((mFlags & FLAG_SSL) != 0); + // infer port# from protocol + security + // SSL implies a different port - TLS runs in the "regular" port + // NOTE: Although the port should be setup in the various setup screens, this + // block cannot easily be moved because we get process URIs from other sources + // (e.g. for tests, provider templates and account restore) that may or may not + // have a port specified. + if ("pop3".equals(mProtocol)) { + mPort = useSSL ? 995 : 110; + } else if ("imap".equals(mProtocol)) { + mPort = useSSL ? 993 : 143; + } else if ("eas".equals(mProtocol)) { + mPort = useSSL ? 443 : 80; + } else if ("smtp".equals(mProtocol)) { + mPort = useSSL ? 465 : 587; + } + } } /** diff --git a/src/com/android/emailcommon/utility/Utility.java b/src/com/android/emailcommon/utility/Utility.java index 4d055cf32..d2bf1a5aa 100644 --- a/src/com/android/emailcommon/utility/Utility.java +++ b/src/com/android/emailcommon/utility/Utility.java @@ -64,6 +64,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; @@ -1107,4 +1109,21 @@ public class Utility { i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); return i; } + + /** + * Legacy URI parser. Used in one of three different scenarios: + * 1. Backup / Restore of account + * 2. Parsing template from provider.xml + * 3. Forcefully creating URI for test + */ + public static void setHostAuthFromString(HostAuth auth, String uriString) + throws URISyntaxException { + URI uri = new URI(uriString); + String path = uri.getPath(); + if (path != null && path.length() > 0) { + auth.mDomain = path.substring(1); + } + auth.setLogin(uri.getUserInfo()); + auth.setConnection(uri.getScheme(), uri.getHost(), uri.getPort()); + } } diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java index 67f9123cf..9cfe4f268 100644 --- a/src/com/android/exchange/EasSyncService.java +++ b/src/com/android/exchange/EasSyncService.java @@ -242,7 +242,7 @@ public class EasSyncService extends AbstractSyncService { return; } mSsl = (ha.mFlags & HostAuth.FLAG_SSL) != 0; - mTrustSsl = (ha.mFlags & HostAuth.FLAG_TRUST_ALL_CERTIFICATES) != 0; + mTrustSsl = (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0; } private EasSyncService(String prefix) { @@ -853,7 +853,7 @@ public class EasSyncService extends AbstractSyncService { svc.mUserName = ha.mLogin; svc.mPassword = ha.mPassword; svc.mSsl = (ha.mFlags & HostAuth.FLAG_SSL) != 0; - svc.mTrustSsl = (ha.mFlags & HostAuth.FLAG_TRUST_ALL_CERTIFICATES) != 0; + svc.mTrustSsl = (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0; svc.mDeviceId = Device.getDeviceId(context); svc.mAccount = acct; Serializer s = new Serializer(); diff --git a/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java b/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java index 78f92bfb5..e75a1ece9 100644 --- a/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java @@ -18,6 +18,7 @@ package com.android.email.activity.setup; import com.android.email.mail.Store; import com.android.emailcommon.provider.EmailContent.Account; +import com.android.emailcommon.utility.Utility; import android.content.ContentUris; import android.content.Context; @@ -28,6 +29,8 @@ import android.preference.PreferenceFragment; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.MediumTest; +import java.net.URISyntaxException; + /** * Tests of basic UI logic in the Account Settings fragment. * @@ -129,7 +132,7 @@ public class AccountSettingsXLTests extends ActivityInstrumentationTestCase2 good fields */ - public void testGoodUri() { + public void testGoodUri() + throws URISyntaxException { Intent i = getTestIntent("eas://user:password@server.com"); setActivityIntent(i); getActivityAndFields(); @@ -86,7 +89,8 @@ public class AccountSetupExchangeTests extends /** * No user is not OK - not enabled */ - public void testBadUriNoUser() { + public void testBadUriNoUser() + throws URISyntaxException { Intent i = getTestIntent("eas://:password@server.com"); setActivityIntent(i); getActivityAndFields(); @@ -96,7 +100,8 @@ public class AccountSetupExchangeTests extends /** * No password is not OK - not enabled */ - public void testBadUriNoPassword() { + public void testBadUriNoPassword() + throws URISyntaxException { Intent i = getTestIntent("eas://user@server.com"); setActivityIntent(i); getActivityAndFields(); @@ -187,7 +192,7 @@ public class AccountSetupExchangeTests extends account.mHostAuthRecv = ProviderTestUtils.setupHostAuth( "eas", "hostauth", 1, false, mActivity.getBaseContext()); account.mHostAuthRecv.mFlags |= HostAuth.FLAG_SSL; - account.mHostAuthRecv.mFlags &= ~HostAuth.FLAG_TRUST_ALL_CERTIFICATES; + account.mHostAuthRecv.mFlags &= ~HostAuth.FLAG_TRUST_ALL; mActivity.mFragment.mLoaded = false; boolean loadResult = mActivity.mFragment.loadSettings(account); assertTrue(loadResult); @@ -197,7 +202,7 @@ public class AccountSetupExchangeTests extends // Setup host auth with variants of SSL enabled and check. This also enables the // "trust certificates" checkbox (not checked, but visible now). - account.mHostAuthRecv.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; + account.mHostAuthRecv.mFlags |= HostAuth.FLAG_TRUST_ALL; mActivity.mFragment.mLoaded = false; loadResult = mActivity.mFragment.loadSettings(account); assertTrue(loadResult); @@ -232,9 +237,12 @@ public class AccountSetupExchangeTests extends /** * Create an intent with the Account in it */ - private Intent getTestIntent(String storeUriString) { + private Intent getTestIntent(String storeUriString) + throws URISyntaxException { EmailContent.Account account = new EmailContent.Account(); - account.setStoreUri(getInstrumentation().getTargetContext(), storeUriString); + Context context = getInstrumentation().getTargetContext(); + HostAuth auth = account.getOrCreateHostAuthRecv(context); + Utility.setHostAuthFromString(auth, storeUriString); Intent i = new Intent(Intent.ACTION_MAIN); SetupData.init(SetupData.FLOW_MODE_NORMAL, account); SetupData.setAllowAutodiscover(false); diff --git a/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java b/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java index 7e211bca0..570813488 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupIncomingTests.java @@ -18,7 +18,10 @@ package com.android.email.activity.setup; import com.android.email.R; import com.android.emailcommon.provider.EmailContent; +import com.android.emailcommon.provider.EmailContent.HostAuth; +import com.android.emailcommon.utility.Utility; +import android.content.Context; import android.content.Intent; import android.test.ActivityInstrumentationTestCase2; import android.test.UiThreadTest; @@ -34,14 +37,14 @@ import java.net.URISyntaxException; * runtest -c com.android.email.activity.setup.AccountSetupIncomingTests email */ @MediumTest -public class AccountSetupIncomingTests extends +public class AccountSetupIncomingTests extends ActivityInstrumentationTestCase2 { - + private AccountSetupIncoming mActivity; private AccountSetupIncomingFragment mFragment; private EditText mServerView; private EditText mPasswordView; - + public AccountSetupIncomingTests() { super(AccountSetupIncoming.class); } @@ -60,47 +63,51 @@ public class AccountSetupIncomingTests extends Intent i = getTestIntent("imap://user:password@server.com:999"); setActivityIntent(i); } - + /** * Test processing with a complete, good URI -> good fields */ - public void testGoodUri() { + public void testGoodUri() + throws URISyntaxException { Intent i = getTestIntent("imap://user:password@server.com:999"); setActivityIntent(i); getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); } - + /** * No user is not OK - not enabled */ - public void testBadUriNoUser() { + public void testBadUriNoUser() + throws URISyntaxException { Intent i = getTestIntent("imap://:password@server.com:999"); setActivityIntent(i); getActivityAndFields(); assertFalse(mActivity.mNextButtonEnabled); } - + /** * No password is not OK - not enabled */ - public void testBadUriNoPassword() { + public void testBadUriNoPassword() + throws URISyntaxException { Intent i = getTestIntent("imap://user@server.com:999"); setActivityIntent(i); getActivityAndFields(); assertFalse(mActivity.mNextButtonEnabled); } - + /** * No port is OK - still enabled */ - public void testGoodUriNoPort() { + public void testGoodUriNoPort() + throws URISyntaxException { Intent i = getTestIntent("imap://user:password@server.com"); setActivityIntent(i); getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); } - + /** * Test for non-standard but OK server names */ @@ -108,11 +115,11 @@ public class AccountSetupIncomingTests extends public void testGoodServerVariants() { getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); - + mServerView.setText(" server.com "); assertTrue(mActivity.mNextButtonEnabled); } - + /** * Test for non-empty but non-OK server names */ @@ -120,10 +127,10 @@ public class AccountSetupIncomingTests extends public void testBadServerVariants() { getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); - + mServerView.setText(" "); assertFalse(mActivity.mNextButtonEnabled); - + mServerView.setText("serv$er.com"); assertFalse(mActivity.mNextButtonEnabled); } @@ -169,7 +176,7 @@ public class AccountSetupIncomingTests extends * TODO: A series of tests to explore the logic around security models & ports * TODO: A series of tests exploring differences between IMAP and POP3 */ - + /** * Get the activity (which causes it to be started, using our intent) and get the UI fields */ @@ -179,13 +186,16 @@ public class AccountSetupIncomingTests extends mServerView = (EditText) mActivity.findViewById(R.id.account_server); mPasswordView = (EditText) mActivity.findViewById(R.id.account_password); } - + /** * Create an intent with the Account in it */ - private Intent getTestIntent(String storeUriString) { + private Intent getTestIntent(String storeUriString) + throws URISyntaxException { EmailContent.Account account = new EmailContent.Account(); - account.setStoreUri(getInstrumentation().getTargetContext(), storeUriString); + Context context = getInstrumentation().getTargetContext(); + HostAuth auth = account.getOrCreateHostAuthRecv(context); + Utility.setHostAuthFromString(auth, storeUriString); SetupData.init(SetupData.FLOW_MODE_NORMAL, account); return new Intent(Intent.ACTION_MAIN); } diff --git a/tests/src/com/android/email/activity/setup/AccountSetupOptionsTests.java b/tests/src/com/android/email/activity/setup/AccountSetupOptionsTests.java index c30b4e0fd..20ed005be 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupOptionsTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupOptionsTests.java @@ -19,7 +19,10 @@ package com.android.email.activity.setup; import com.android.email.R; import com.android.email.mail.Store; import com.android.emailcommon.provider.EmailContent; +import com.android.emailcommon.provider.EmailContent.HostAuth; +import com.android.emailcommon.utility.Utility; +import android.content.Context; import android.content.Intent; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.MediumTest; @@ -28,19 +31,21 @@ import android.widget.CheckBox; import android.widget.Spinner; import android.widget.SpinnerAdapter; +import java.net.URISyntaxException; + /** * Tests of basic UI logic in the AccountSetupOptions screen. * You can run this entire test case with: * runtest -c com.android.email.activity.setup.AccountSetupOptionsTests email */ @MediumTest -public class AccountSetupOptionsTests +public class AccountSetupOptionsTests extends ActivityInstrumentationTestCase2 { private AccountSetupOptions mActivity; private Spinner mCheckFrequencyView; private CheckBox mBackgroundAttachmentsView; - + public AccountSetupOptionsTests() { super(AccountSetupOptions.class); } @@ -48,44 +53,47 @@ public class AccountSetupOptionsTests /** * Test that POP accounts aren't displayed with a push option */ - public void testPushOptionPOP() { + public void testPushOptionPOP() + throws URISyntaxException { Intent i = getTestIntent("Name", "pop3://user:password@server.com"); this.setActivityIntent(i); - + getActivityAndFields(); - + boolean hasPush = frequencySpinnerHasValue(EmailContent.Account.CHECK_INTERVAL_PUSH); assertFalse(hasPush); } - + /** * Test that IMAP accounts aren't displayed with a push option */ - public void testPushOptionIMAP() { + public void testPushOptionIMAP() + throws URISyntaxException { Intent i = getTestIntent("Name", "imap://user:password@server.com"); this.setActivityIntent(i); - + getActivityAndFields(); - + boolean hasPush = frequencySpinnerHasValue(EmailContent.Account.CHECK_INTERVAL_PUSH); assertFalse(hasPush); } - + /** * Test that EAS accounts are displayed with a push option */ - public void testPushOptionEAS() { + public void testPushOptionEAS() + throws URISyntaxException { // This test should only be run if EAS is supported - if (Store.StoreInfo.getStoreInfo("eas", this.getInstrumentation().getTargetContext()) + if (Store.StoreInfo.getStoreInfo("eas", this.getInstrumentation().getTargetContext()) == null) { return; } - + Intent i = getTestIntent("Name", "eas://user:password@server.com"); this.setActivityIntent(i); - + getActivityAndFields(); - + boolean hasPush = frequencySpinnerHasValue(EmailContent.Account.CHECK_INTERVAL_PUSH); assertTrue(hasPush); } @@ -93,23 +101,26 @@ public class AccountSetupOptionsTests /** * Test that POP3 accounts don't have a "background attachments" checkbox */ - public void testBackgroundAttachmentsPop() { + public void testBackgroundAttachmentsPop() + throws URISyntaxException { checkBackgroundAttachments("pop3://user:password@server.com", false); } /** * Test that IMAP accounts have a "background attachments" checkbox */ - public void testBackgroundAttachmentsImap() { + public void testBackgroundAttachmentsImap() + throws URISyntaxException { checkBackgroundAttachments("imap://user:password@server.com", true); } /** * Test that EAS accounts have a "background attachments" checkbox */ - public void testBackgroundAttachmentsEas() { + public void testBackgroundAttachmentsEas() + throws URISyntaxException { // This test should only be run if EAS is supported - if (Store.StoreInfo.getStoreInfo("eas", this.getInstrumentation().getTargetContext()) + if (Store.StoreInfo.getStoreInfo("eas", this.getInstrumentation().getTargetContext()) == null) { return; } @@ -117,9 +128,10 @@ public class AccountSetupOptionsTests } /** - * Common code to check that the "background attachments" checkbox is shown/hidden properly + * Common code to check that the "background attachments" checkbox is shown/hidden properly */ - private void checkBackgroundAttachments(String storeUri, boolean expectVisible) { + private void checkBackgroundAttachments(String storeUri, boolean expectVisible) + throws URISyntaxException { Intent i = getTestIntent("Name", storeUri); this.setActivityIntent(i); getActivityAndFields(); @@ -144,7 +156,7 @@ public class AccountSetupOptionsTests mBackgroundAttachmentsView = (CheckBox) mActivity.findViewById( R.id.account_background_attachments); } - + /** * Test the frequency values list for a particular value */ @@ -159,16 +171,19 @@ public class AccountSetupOptionsTests } return false; } - + /** * Create an intent with the Account in it */ - private Intent getTestIntent(String name, String storeUri) { + private Intent getTestIntent(String name, String storeUri) + throws URISyntaxException { EmailContent.Account account = new EmailContent.Account(); account.setSenderName(name); - account.setStoreUri(getInstrumentation().getTargetContext(), storeUri); + Context context = getInstrumentation().getTargetContext(); + HostAuth auth = account.getOrCreateHostAuthRecv(context); + Utility.setHostAuthFromString(auth, storeUri); SetupData.init(SetupData.FLOW_MODE_NORMAL, account); return new Intent(Intent.ACTION_MAIN); } - + } diff --git a/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java b/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java index 4d66f97bc..169eb75aa 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupOutgoingTests.java @@ -18,7 +18,10 @@ package com.android.email.activity.setup; import com.android.email.R; import com.android.emailcommon.provider.EmailContent; +import com.android.emailcommon.provider.EmailContent.HostAuth; +import com.android.emailcommon.utility.Utility; +import android.content.Context; import android.content.Intent; import android.test.ActivityInstrumentationTestCase2; import android.test.UiThreadTest; @@ -34,14 +37,14 @@ import java.net.URISyntaxException; * runtest -c com.android.email.activity.setup.AccountSetupOutgoingTests email */ @MediumTest -public class AccountSetupOutgoingTests extends +public class AccountSetupOutgoingTests extends ActivityInstrumentationTestCase2 { private AccountSetupOutgoing mActivity; private AccountSetupOutgoingFragment mFragment; private EditText mServerView; private EditText mPasswordView; - + public AccountSetupOutgoingTests() { super(AccountSetupOutgoing.class); } @@ -60,7 +63,7 @@ public class AccountSetupOutgoingTests extends Intent i = getTestIntent("smtp://user:password@server.com:999"); setActivityIntent(i); } - + /** * Test processing with a complete, good URI -> good fields */ @@ -68,37 +71,40 @@ public class AccountSetupOutgoingTests extends getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); } - + /** * No user is not OK - not enabled */ - public void testBadUriNoUser() { + public void testBadUriNoUser() + throws URISyntaxException { Intent i = getTestIntent("smtp://:password@server.com:999"); setActivityIntent(i); getActivityAndFields(); assertFalse(mActivity.mNextButtonEnabled); } - + /** * No password is not OK - not enabled */ - public void testBadUriNoPassword() { + public void testBadUriNoPassword() + throws URISyntaxException { Intent i = getTestIntent("smtp://user@server.com:999"); setActivityIntent(i); getActivityAndFields(); assertFalse(mActivity.mNextButtonEnabled); } - + /** * No port is OK - still enabled */ - public void testGoodUriNoPort() { + public void testGoodUriNoPort() + throws URISyntaxException { Intent i = getTestIntent("smtp://user:password@server.com"); setActivityIntent(i); getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); } - + /** * Test for non-standard but OK server names */ @@ -106,11 +112,11 @@ public class AccountSetupOutgoingTests extends public void testGoodServerVariants() { getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); - + mServerView.setText(" server.com "); assertTrue(mActivity.mNextButtonEnabled); } - + /** * Test for non-empty but non-OK server names */ @@ -118,10 +124,10 @@ public class AccountSetupOutgoingTests extends public void testBadServerVariants() { getActivityAndFields(); assertTrue(mActivity.mNextButtonEnabled); - + mServerView.setText(" "); assertFalse(mActivity.mNextButtonEnabled); - + mServerView.setText("serv$er.com"); assertFalse(mActivity.mNextButtonEnabled); } @@ -166,7 +172,7 @@ public class AccountSetupOutgoingTests extends /** * TODO: A series of tests to explore the logic around security models & ports */ - + /** * Get the activity (which causes it to be started, using our intent) and get the UI fields */ @@ -176,13 +182,16 @@ public class AccountSetupOutgoingTests extends mServerView = (EditText) mActivity.findViewById(R.id.account_server); mPasswordView = (EditText) mActivity.findViewById(R.id.account_password); } - + /** * Create an intent with the Account in it */ - private Intent getTestIntent(String senderUriString) { + private Intent getTestIntent(String senderUriString) + throws URISyntaxException { EmailContent.Account account = new EmailContent.Account(); - account.setSenderUri(this.getInstrumentation().getTargetContext(), senderUriString); + Context context = getInstrumentation().getTargetContext(); + HostAuth auth = account.getOrCreateHostAuthSend(context); + Utility.setHostAuthFromString(auth, senderUriString); SetupData.init(SetupData.FLOW_MODE_NORMAL, account); return new Intent(Intent.ACTION_MAIN); } diff --git a/tests/src/com/android/email/provider/ProviderTests.java b/tests/src/com/android/email/provider/ProviderTests.java index ba3bcfad5..571134b4b 100644 --- a/tests/src/com/android/email/provider/ProviderTests.java +++ b/tests/src/com/android/email/provider/ProviderTests.java @@ -46,6 +46,7 @@ import android.test.ProviderTestCase2; import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.util.ArrayList; /** @@ -128,8 +129,78 @@ public class ProviderTests extends ProviderTestCase2 { account1.mHostAuthSend, hostAuth2get); } + public void testAccountGetHostAuthSend() { + Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext); + account.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false, + mMockContext); + account.save(mMockContext); + HostAuth authGet; + HostAuth authTest; + + authTest = account.mHostAuthSend; + assertNotNull(authTest); + assertTrue(account.mHostAuthKeySend != 0); + + // HostAuth is not changed + authGet = account.getOrCreateHostAuthSend(mMockContext); + assertTrue(authGet == authTest); // return the same object + + // New HostAuth; based upon mHostAuthKeyRecv + authTest = EmailContent.HostAuth.restoreHostAuthWithId(mMockContext, + account.mHostAuthKeySend); + account.mHostAuthSend = null; + authGet = account.getOrCreateHostAuthSend(mMockContext); + assertNotNull(authGet); + assertNotNull(account.mHostAuthSend); + ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthSend-1", authTest, authGet); + + // New HostAuth; completely empty + authTest = new EmailContent.HostAuth(); + account.mHostAuthSend = null; + account.mHostAuthKeySend = 0; + authGet = account.getOrCreateHostAuthSend(mMockContext); + assertNotNull(authGet); + assertNotNull(account.mHostAuthSend); + ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthSendv-2", authTest, authGet); + } + + public void testAccountGetHostAuthRecv() { + Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext); + account.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false, + mMockContext); + account.save(mMockContext); + HostAuth authGet; + HostAuth authTest; + + authTest = account.mHostAuthRecv; + assertNotNull(authTest); + assertTrue(account.mHostAuthKeyRecv != 0); + + // HostAuth is not changed + authGet = account.getOrCreateHostAuthRecv(mMockContext); + assertTrue(authGet == authTest); // return the same object + + // New HostAuth; based upon mHostAuthKeyRecv + authTest = EmailContent.HostAuth.restoreHostAuthWithId(mMockContext, + account.mHostAuthKeyRecv); + account.mHostAuthRecv = null; + authGet = account.getOrCreateHostAuthRecv(mMockContext); + assertNotNull(authGet); + assertNotNull(account.mHostAuthRecv); + ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthRecv-1", authTest, authGet); + + // New HostAuth; completely empty + authTest = new EmailContent.HostAuth(); + account.mHostAuthRecv = null; + account.mHostAuthKeyRecv = 0; + authGet = account.getOrCreateHostAuthRecv(mMockContext); + assertNotNull(authGet); + assertNotNull(account.mHostAuthRecv); + ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthRecv-2", authTest, authGet); + } + /** - * Simple test of account parceling. The rather tortuous path is to ensure that the + * Simple test of account parceling. The rather torturous path is to ensure that the * account is really flattened all the way down to a parcel and back. */ public void testAccountParcel() { @@ -149,7 +220,7 @@ public class ProviderTests extends ProviderTestCase2 { /** * Test for {@link Account#getShortcutSafeUri()} and - * {@link Account#getAccountIdForShortcutSafeUri}. + * {@link Account#getAccountIdFromShortcutSafeUri}. */ public void testAccountShortcutSafeUri() { final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext); @@ -223,9 +294,6 @@ public class ProviderTests extends ProviderTestCase2 { /** * Get the value of the unread count in the mailbox of the account. * This can be different from the actual number of unread messages in that mailbox. - * @param accountId - * @param mailboxId - * @return */ private int getUnreadCount(long mailboxId) { String text = null; @@ -252,24 +320,24 @@ public class ProviderTests extends ProviderTestCase2 { /** * Test the various combinations of SSL, TLS, and trust-certificates encoded as Uris */ - @SuppressWarnings("deprecation") - public void testHostAuthSecurityUri() { + public void testHostAuthSecurityUri() + throws URISyntaxException { HostAuth ha = ProviderTestUtils.setupHostAuth("uri-security", 1, false, mMockContext); final int MASK = - HostAuth.FLAG_SSL | HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL_CERTIFICATES; + HostAuth.FLAG_SSL | HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL; // Set various URIs and check the resulting flags - ha.setStoreUri("protocol://user:password@server:123"); + Utility.setHostAuthFromString(ha, "protocol://user:password@server:123"); assertEquals(0, ha.mFlags & MASK); - ha.setStoreUri("protocol+ssl+://user:password@server:123"); + Utility.setHostAuthFromString(ha, "protocol+ssl+://user:password@server:123"); assertEquals(HostAuth.FLAG_SSL, ha.mFlags & MASK); - ha.setStoreUri("protocol+ssl+trustallcerts://user:password@server:123"); - assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL_CERTIFICATES, ha.mFlags & MASK); - ha.setStoreUri("protocol+tls+://user:password@server:123"); + Utility.setHostAuthFromString(ha, "protocol+ssl+trustallcerts://user:password@server:123"); + assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, ha.mFlags & MASK); + Utility.setHostAuthFromString(ha, "protocol+tls+://user:password@server:123"); assertEquals(HostAuth.FLAG_TLS, ha.mFlags & MASK); - ha.setStoreUri("protocol+tls+trustallcerts://user:password@server:123"); - assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL_CERTIFICATES, ha.mFlags & MASK); + Utility.setHostAuthFromString(ha, "protocol+tls+trustallcerts://user:password@server:123"); + assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL, ha.mFlags & MASK); // Now check the retrival method (building URI from flags) ha.mFlags &= ~MASK; @@ -278,14 +346,14 @@ public class ProviderTests extends ProviderTestCase2 { ha.mFlags |= HostAuth.FLAG_SSL; uriString = ha.getStoreUri(); assertTrue(uriString.startsWith("protocol+ssl+://")); - ha.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; + ha.mFlags |= HostAuth.FLAG_TRUST_ALL; uriString = ha.getStoreUri(); assertTrue(uriString.startsWith("protocol+ssl+trustallcerts://")); ha.mFlags &= ~MASK; ha.mFlags |= HostAuth.FLAG_TLS; uriString = ha.getStoreUri(); assertTrue(uriString.startsWith("protocol+tls+://")); - ha.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; + ha.mFlags |= HostAuth.FLAG_TRUST_ALL; uriString = ha.getStoreUri(); assertTrue(uriString.startsWith("protocol+tls+trustallcerts://")); } @@ -293,89 +361,375 @@ public class ProviderTests extends ProviderTestCase2 { /** * Test port assignments made from Uris */ - @SuppressWarnings("deprecation") - public void testHostAuthPortAssignments() { + public void testHostAuthPortAssignments() + throws URISyntaxException { HostAuth ha = ProviderTestUtils.setupHostAuth("uri-port", 1, false, mMockContext); // Set various URIs and check the resulting flags // Hardwired port - ha.setStoreUri("imap://user:password@server:123"); + Utility.setHostAuthFromString(ha, "imap://user:password@server:123"); assertEquals(123, ha.mPort); // Auto-assigned ports - ha.setStoreUri("imap://user:password@server"); + Utility.setHostAuthFromString(ha, "imap://user:password@server"); assertEquals(143, ha.mPort); - ha.setStoreUri("imap+ssl://user:password@server"); + Utility.setHostAuthFromString(ha, "imap+ssl://user:password@server"); assertEquals(993, ha.mPort); - ha.setStoreUri("imap+ssl+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "imap+ssl+trustallcerts://user:password@server"); assertEquals(993, ha.mPort); - ha.setStoreUri("imap+tls://user:password@server"); + Utility.setHostAuthFromString(ha, "imap+tls://user:password@server"); assertEquals(143, ha.mPort); - ha.setStoreUri("imap+tls+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "imap+tls+trustallcerts://user:password@server"); assertEquals(143, ha.mPort); // Hardwired port - ha.setStoreUri("pop3://user:password@server:123"); + Utility.setHostAuthFromString(ha, "pop3://user:password@server:123"); assertEquals(123, ha.mPort); // Auto-assigned ports - ha.setStoreUri("pop3://user:password@server"); + Utility.setHostAuthFromString(ha, "pop3://user:password@server"); assertEquals(110, ha.mPort); - ha.setStoreUri("pop3+ssl://user:password@server"); + Utility.setHostAuthFromString(ha, "pop3+ssl://user:password@server"); assertEquals(995, ha.mPort); - ha.setStoreUri("pop3+ssl+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "pop3+ssl+trustallcerts://user:password@server"); assertEquals(995, ha.mPort); - ha.setStoreUri("pop3+tls://user:password@server"); + Utility.setHostAuthFromString(ha, "pop3+tls://user:password@server"); assertEquals(110, ha.mPort); - ha.setStoreUri("pop3+tls+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "pop3+tls+trustallcerts://user:password@server"); assertEquals(110, ha.mPort); // Hardwired port - ha.setStoreUri("eas://user:password@server:123"); + Utility.setHostAuthFromString(ha, "eas://user:password@server:123"); assertEquals(123, ha.mPort); // Auto-assigned ports - ha.setStoreUri("eas://user:password@server"); + Utility.setHostAuthFromString(ha, "eas://user:password@server"); assertEquals(80, ha.mPort); - ha.setStoreUri("eas+ssl://user:password@server"); + Utility.setHostAuthFromString(ha, "eas+ssl://user:password@server"); assertEquals(443, ha.mPort); - ha.setStoreUri("eas+ssl+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "eas+ssl+trustallcerts://user:password@server"); assertEquals(443, ha.mPort); // Hardwired port - ha.setStoreUri("smtp://user:password@server:123"); + Utility.setHostAuthFromString(ha, "smtp://user:password@server:123"); assertEquals(123, ha.mPort); // Auto-assigned ports - ha.setStoreUri("smtp://user:password@server"); + Utility.setHostAuthFromString(ha, "smtp://user:password@server"); assertEquals(587, ha.mPort); - ha.setStoreUri("smtp+ssl://user:password@server"); + Utility.setHostAuthFromString(ha, "smtp+ssl://user:password@server"); assertEquals(465, ha.mPort); - ha.setStoreUri("smtp+ssl+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "smtp+ssl+trustallcerts://user:password@server"); assertEquals(465, ha.mPort); - ha.setStoreUri("smtp+tls://user:password@server"); + Utility.setHostAuthFromString(ha, "smtp+tls://user:password@server"); assertEquals(587, ha.mPort); - ha.setStoreUri("smtp+tls+trustallcerts://user:password@server"); + Utility.setHostAuthFromString(ha, "smtp+tls+trustallcerts://user:password@server"); assertEquals(587, ha.mPort); } /** * Test preservation of username & password in URI */ - @SuppressWarnings("deprecation") - public void testHostAuthUri() { + public void testHostAuthUri() + throws URISyntaxException { HostAuth ha = new HostAuth(); - ha.setStoreUri("protocol://user:password@server:123"); + Utility.setHostAuthFromString(ha, "protocol://user:password@server:123"); String getUri = ha.getStoreUri(); assertEquals("protocol://user:password@server:123", getUri); // Now put spaces in/around username (they are trimmed) - ha.setStoreUri("protocol://%20us%20er%20:password@server:123"); + Utility.setHostAuthFromString(ha, "protocol://%20us%20er%20:password@server:123"); getUri = ha.getStoreUri(); assertEquals("protocol://us%20er:password@server:123", getUri); // Now put spaces around password (should not be trimmed) - ha.setStoreUri("protocol://user:%20pass%20word%20@server:123"); + Utility.setHostAuthFromString(ha, "protocol://user:%20pass%20word%20@server:123"); getUri = ha.getStoreUri(); assertEquals("protocol://user:%20pass%20word%20@server:123", getUri); } + /** + * Test user name and password are set correctly + */ + public void testHostAuthSetLogin() { + HostAuth ha = new HostAuth(); + ha.setLogin("user:password"); + assertEquals("user", ha.mLogin); + assertEquals("password", ha.mPassword); + + // special characters are not removed during insertion + ha.setLogin("%20us%20er%20:password"); + assertEquals("%20us%20er%20", ha.mLogin); + assertEquals("password", ha.mPassword); + + // special characters are not removed during insertion + ha.setLogin("user:%20pass%20word%20"); + assertEquals("user", ha.mLogin); + assertEquals("%20pass%20word%20", ha.mPassword); + + ha.setLogin("user:"); + assertEquals("user", ha.mLogin); + assertEquals("", ha.mPassword); + + ha.setLogin(":password"); + assertEquals("", ha.mLogin); + assertEquals("password", ha.mPassword); + + ha.setLogin(""); + assertNull(ha.mLogin); + assertNull(ha.mPassword); + + ha.setLogin(null); + assertNull(ha.mLogin); + assertNull(ha.mPassword); + + ha.setLogin("userpassword"); + assertEquals("userpassword", ha.mLogin); + assertNull(ha.mPassword); + } + + /** + * Test the authentication flag is set correctly when setting user name and password + */ + public void testHostAuthSetLoginAuthenticate() { + HostAuth ha = new HostAuth(); + + ha.mFlags = 0x00000000; + ha.setLogin("user", "password"); + assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); + + ha.mFlags = 0x00000000; + ha.setLogin("user", ""); + assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); + + ha.mFlags = 0x00000000; + ha.setLogin("", "password"); + assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); + + ha.mFlags = 0x00000000; + ha.setLogin("user", null); + assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); + + ha.mFlags = 0xffffffff; + ha.setLogin(null, "password"); + assertEquals(~HostAuth.FLAG_AUTHENTICATE, ha.mFlags); + + ha.mFlags = 0xffffffff; + ha.setLogin(null, null); + assertEquals(~HostAuth.FLAG_AUTHENTICATE, ha.mFlags); + } + + /** + * Test setting the connection using a URI scheme + */ + public void testHostAuthSetConnectionScheme() { + HostAuth ha = new HostAuth(); + + // Set URIs for IMAP + // Hardwired port + ha.setConnection("imap", "server", 123); + assertEquals(0, ha.mFlags); + assertEquals(123, ha.mPort); + + // Auto-assigned ports + ha.setConnection("imap", "server", -1); + assertEquals(0, ha.mFlags); + assertEquals(143, ha.mPort); + + ha.setConnection("imap+ssl", "server", -1); + assertEquals(HostAuth.FLAG_SSL, ha.mFlags); + assertEquals(993, ha.mPort); + + ha.setConnection("imap+ssl+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_SSL|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(993, ha.mPort); + + ha.setConnection("imap+tls", "server", -1); + assertEquals(HostAuth.FLAG_TLS, ha.mFlags); + assertEquals(143, ha.mPort); + + ha.setConnection("imap+tls+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_TLS|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(143, ha.mPort); + + // Set URIs for POP3 + // Hardwired port + ha.setConnection("pop3", "server", 123); + assertEquals(0, ha.mFlags); + assertEquals(123, ha.mPort); + + // Auto-assigned ports + ha.setConnection("pop3", "server", -1); + assertEquals(0, ha.mFlags); + assertEquals(110, ha.mPort); + + ha.setConnection("pop3+ssl", "server", -1); + assertEquals(HostAuth.FLAG_SSL, ha.mFlags); + assertEquals(995, ha.mPort); + + ha.setConnection("pop3+ssl+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_SSL|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(995, ha.mPort); + + ha.setConnection("pop3+tls", "server", -1); + assertEquals(HostAuth.FLAG_TLS, ha.mFlags); + assertEquals(110, ha.mPort); + + ha.setConnection("pop3+tls+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_TLS|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(110, ha.mPort); + + // Set URIs for Exchange + // Hardwired port + ha.setConnection("eas", "server", 123); + assertEquals(0, ha.mFlags); + assertEquals(123, ha.mPort); + + // Auto-assigned ports + ha.setConnection("eas", "server", -1); + assertEquals(0, ha.mFlags); + assertEquals(80, ha.mPort); + + ha.setConnection("eas+ssl", "server", -1); + assertEquals(HostAuth.FLAG_SSL, ha.mFlags); + assertEquals(443, ha.mPort); + + ha.setConnection("eas+ssl+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_SSL|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(443, ha.mPort); + + // Set URIs for SMTP + // Hardwired port + ha.setConnection("smtp", "server", 123); + assertEquals(0, ha.mFlags); + assertEquals(123, ha.mPort); + + // Auto-assigned ports + ha.setConnection("smtp", "server", -1); + assertEquals(0, ha.mFlags); + assertEquals(587, ha.mPort); + + ha.setConnection("smtp+ssl", "server", -1); + assertEquals(HostAuth.FLAG_SSL, ha.mFlags); + assertEquals(465, ha.mPort); + + ha.setConnection("smtp+ssl+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_SSL|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(465, ha.mPort); + + ha.setConnection("smtp+tls", "server", -1); + assertEquals(HostAuth.FLAG_TLS, ha.mFlags); + assertEquals(587, ha.mPort); + + ha.setConnection("smtp+tls+trustallcerts", "server", -1); + assertEquals(HostAuth.FLAG_TLS|HostAuth.FLAG_TRUST_ALL, ha.mFlags); + assertEquals(587, ha.mPort); + } + + /** + * Test setting the connection using a protocol and flags + */ + public void testHostAuthSetConnectionFlags() { + HostAuth ha = new HostAuth(); + + // Different port types don't affect flags + ha.setConnection("imap", "server", 123, 0); + assertEquals(0, ha.mFlags); + ha.setConnection("imap", "server", -1, 0); + assertEquals(0, ha.mFlags); + + // Different protocol types don't affect flags + ha.setConnection("pop3", "server", 123, 0); + assertEquals(0, ha.mFlags); + ha.setConnection("pop3", "server", -1, 0); + assertEquals(0, ha.mFlags); + ha.setConnection("eas", "server", 123, 0); + assertEquals(0, ha.mFlags); + ha.setConnection("eas", "server", -1, 0); + assertEquals(0, ha.mFlags); + ha.setConnection("smtp", "server", 123, 0); + assertEquals(0, ha.mFlags); + ha.setConnection("smtp", "server", -1, 0); + assertEquals(0, ha.mFlags); + + // Sets SSL flag + ha.setConnection("imap", "server", -1, HostAuth.FLAG_SSL); + assertEquals(HostAuth.FLAG_SSL, ha.mFlags); + + // Sets SSL+Trusted flags + ha.setConnection("imap", "server", -1, HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL); + assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, ha.mFlags); + + // Sets TLS flag + ha.setConnection("imap", "server", -1, HostAuth.FLAG_TLS); + assertEquals(HostAuth.FLAG_TLS, ha.mFlags); + + // Sets TLS+Trusted flags + ha.setConnection("imap", "server", -1, HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL); + assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL, ha.mFlags); + + // Test other defined flags; should not affect mFlags + ha.setConnection("imap", "server", -1, HostAuth.FLAG_AUTHENTICATE); + assertEquals(0, ha.mFlags); + + // Test every other bit; should not affect mFlags + ha.setConnection("imap", "server", -1, 0xfffffff4); + assertEquals(0, ha.mFlags); + } + + public void testHostAuthGetSchemeString() { + String scheme; + + scheme = HostAuth.getSchemeString("foo", 0); + assertEquals("foo", scheme); + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_SSL); + assertEquals("foo+ssl+", scheme); + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL); + assertEquals("foo+ssl+trustallcerts", scheme); + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_TLS); + assertEquals("foo+tls+", scheme); + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL); + assertEquals("foo+tls+trustallcerts", scheme); + // error cases; no security string appended to protocol + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_TRUST_ALL); + assertEquals("foo", scheme); + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_SSL | HostAuth.FLAG_TLS); + assertEquals("foo", scheme); + scheme = HostAuth.getSchemeString("foo", HostAuth.FLAG_SSL | HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL); + assertEquals("foo", scheme); + scheme = HostAuth.getSchemeString("foo", 0xfffffff4); + assertEquals("foo", scheme); + } + + public void testHostAuthGetSchemeFlags() { + int flags; + + flags = HostAuth.getSchemeFlags(""); + assertEquals(0, flags); + flags = HostAuth.getSchemeFlags("+"); + assertEquals(0, flags); + flags = HostAuth.getSchemeFlags("foo+"); + assertEquals(0, flags); + flags = HostAuth.getSchemeFlags("foo+ssl"); + assertEquals(HostAuth.FLAG_SSL, flags); + flags = HostAuth.getSchemeFlags("foo+ssl+"); + assertEquals(HostAuth.FLAG_SSL, flags); + flags = HostAuth.getSchemeFlags("foo+ssl+trustallcerts"); + assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, flags); + flags = HostAuth.getSchemeFlags("foo+tls+"); + assertEquals(HostAuth.FLAG_TLS, flags); + flags = HostAuth.getSchemeFlags("foo+tls+trustallcerts"); + assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL, flags); + flags = HostAuth.getSchemeFlags("foo+bogus"); + assertEquals(0, flags); + flags = HostAuth.getSchemeFlags("foo+bogus+trustallcerts"); + assertEquals(HostAuth.FLAG_TRUST_ALL, flags); + flags = HostAuth.getSchemeFlags("foo+ssl+bogus"); + assertEquals(HostAuth.FLAG_SSL, flags); + flags = HostAuth.getSchemeFlags("foo+ssl+trustallcerts+bogus"); + assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, flags); + flags = HostAuth.getSchemeFlags("foo+bogus+bogus"); + assertEquals(0, flags); + flags = HostAuth.getSchemeFlags("foo+bogus+bogus+bogus"); + assertEquals(0, flags); + } + /** * Test simple mailbox save/retrieve */