From de24b6a1663c100bbb60a6325e6fcfb2879833a8 Mon Sep 17 00:00:00 2001 From: Matthew Brace Date: Sun, 25 Jan 2009 07:37:10 +0000 Subject: [PATCH] Added support for optional Form Based Authentication login path and user mailbox path in account settings. --- res/layout/account_setup_incoming.xml | 30 ++++++++ res/values/strings.xml | 5 ++ .../activity/setup/AccountSetupIncoming.java | 76 ++++++++++++------- .../android/email/mail/store/WebDavStore.java | 56 ++++++++++++-- 4 files changed, 133 insertions(+), 34 deletions(-) diff --git a/res/layout/account_setup_incoming.xml b/res/layout/account_setup_incoming.xml index 9f60731ed..8a790d7e3 100644 --- a/res/layout/account_setup_incoming.xml +++ b/res/layout/account_setup_incoming.xml @@ -112,6 +112,36 @@ android:layout_height="wrap_content" android:layout_width="fill_parent" /> + + + + + + WebDav(Exchange) path Optional + Authentication path + Optional + Mailbox path + Optional + Outgoing server settings SMTP server Port diff --git a/src/com/android/email/activity/setup/AccountSetupIncoming.java b/src/com/android/email/activity/setup/AccountSetupIncoming.java index 86878989d..de7b3f165 100644 --- a/src/com/android/email/activity/setup/AccountSetupIncoming.java +++ b/src/com/android/email/activity/setup/AccountSetupIncoming.java @@ -61,6 +61,8 @@ public class AccountSetupIncoming extends Activity implements OnClickListener { private Spinner mDeletePolicyView; private EditText mImapPathPrefixView; private EditText mWebdavPathPrefixView; + private EditText mWebdavAuthPathView; + private EditText mWebdavMailboxPathView; private Button mNextButton; private Account mAccount; private boolean mMakeDefault; @@ -93,6 +95,8 @@ public class AccountSetupIncoming extends Activity implements OnClickListener { mDeletePolicyView = (Spinner)findViewById(R.id.account_delete_policy); mImapPathPrefixView = (EditText)findViewById(R.id.imap_path_prefix); mWebdavPathPrefixView = (EditText)findViewById(R.id.webdav_path_prefix); + mWebdavAuthPathView = (EditText)findViewById(R.id.webdav_auth_path); + mWebdavMailboxPathView = (EditText)findViewById(R.id.webdav_mailbox_path); mNextButton = (Button)findViewById(R.id.next); mNextButton.setOnClickListener(this); @@ -206,6 +210,7 @@ public class AccountSetupIncoming extends Activity implements OnClickListener { findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE); findViewById(R.id.webdav_path_prefix_section).setVisibility(View.GONE); + findViewById(R.id.webdav_path_debug_section).setVisibility(View.GONE); } else if (uri.getScheme().startsWith("imap")) { serverLabelView.setText(R.string.account_setup_incoming_imap_server_label); mAccountPorts = imapPorts; @@ -215,6 +220,7 @@ public class AccountSetupIncoming extends Activity implements OnClickListener { mImapPathPrefixView.setText(uri.getPath().substring(1)); } findViewById(R.id.webdav_path_prefix_section).setVisibility(View.GONE); + findViewById(R.id.webdav_path_debug_section).setVisibility(View.GONE); } else if (uri.getScheme().startsWith("webdav")) { serverLabelView.setText(R.string.account_setup_incoming_webdav_server_label); mAccountPorts = webdavPorts; @@ -223,7 +229,23 @@ public class AccountSetupIncoming extends Activity implements OnClickListener { /** Hide the unnecessary fields */ findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE); if (uri.getPath() != null && uri.getPath().length() > 0) { - mWebdavPathPrefixView.setText(uri.getPath().substring(1)); + String[] pathParts = uri.getPath().split("\\|"); + + for (int i = 0, count = pathParts.length; i < count; i++) { + if (i == 0) { + if (pathParts[0] != null) { + mWebdavPathPrefixView.setText(pathParts[0].substring(1)); + } + } else if (i == 1) { + if (pathParts[1] != null) { + mWebdavAuthPathView.setText(pathParts[1]); + } + } else if (i == 2) { + if (pathParts[2] != null ) { + mWebdavMailboxPathView.setText(pathParts[2]); + } + } + } } } else { throw new Error("Unknown account type: " + mAccount.getStoreUri()); @@ -313,31 +335,33 @@ public class AccountSetupIncoming extends Activity implements OnClickListener { } private void onNext() { - int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; - try { - String path = null; - if (mAccountSchemes[securityType].startsWith("imap")) { - path = "/" + mImapPathPrefixView.getText(); - } else if (mAccountSchemes[securityType].startsWith("webdav")) { - path = "/" + mWebdavPathPrefixView.getText(); - } - - URI uri = new URI( - mAccountSchemes[securityType], - mUsernameView.getText() + ":" + mPasswordView.getText(), - mServerView.getText().toString(), - Integer.parseInt(mPortView.getText().toString()), - path, // path - null, // query - null); - mAccount.setStoreUri(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); - } + int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; + try { + String path = null; + if (mAccountSchemes[securityType].startsWith("imap")) { + path = "/" + mImapPathPrefixView.getText(); + } else if (mAccountSchemes[securityType].startsWith("webdav")) { + path = "/" + mWebdavPathPrefixView.getText(); + path = path + "|" + mWebdavAuthPathView.getText(); + path = path + "|" + mWebdavMailboxPathView.getText(); + } + + URI uri = new URI( + mAccountSchemes[securityType], + mUsernameView.getText() + ":" + mPasswordView.getText(), + mServerView.getText().toString(), + Integer.parseInt(mPortView.getText().toString()), + path, // path + null, // query + null); + mAccount.setStoreUri(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); + } int deleteSpinnerVal = (Integer)((SpinnerOption)mDeletePolicyView.getSelectedItem()).value; diff --git a/src/com/android/email/mail/store/WebDavStore.java b/src/com/android/email/mail/store/WebDavStore.java index a6301e3a7..aa0abeac1 100644 --- a/src/com/android/email/mail/store/WebDavStore.java +++ b/src/com/android/email/mail/store/WebDavStore.java @@ -85,6 +85,8 @@ public class WebDavStore extends Store { private String mUrl; /* Stores the base URL for the server */ private String mHost; /* Stores the host name for the server */ private String mPath; /* Stores the path for the server */ + private String mAuthPath; /* Stores the path off of the server to post data to for form based authentication */ + private String mMailboxPath; /* Stores the user specified path to the mailbox */ private URI mUri; /* Stores the Uniform Resource Indicator with all connection info */ private CookieStore mAuthCookies; /* Stores cookies from authentication */ @@ -134,9 +136,28 @@ public class WebDavStore extends Store { } } - mPath = mUri.getPath(); - if (mPath == null) { - mPath = ""; + String[] pathParts = mUri.getPath().split("\\|"); + + for (int i = 0, count = pathParts.length; i < count; i++) { + if (i == 0) { + if (pathParts[0] != null) { + if (!pathParts[0].substring(1).equals("")) { + mPath = pathParts[0].substring(1); + } else { + mPath = ""; + } + } else { + mPath = ""; + } + } else if (i == 1) { + if (pathParts[1] != null) { + mAuthPath = "/" + pathParts[1]; + } + } else if (i == 2) { + if (pathParts[2] != null) { + mMailboxPath = "/" + pathParts[2]; + } + } } if (mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED || @@ -442,12 +463,20 @@ public class WebDavStore extends Store { */ public CookieStore doAuthentication(String username, String password, String url) throws IOException, MessagingException { - String authPath = "/exchweb/bin/auth/owaauth.dll"; + String authPath; CookieStore cookies = null; String[] urlParts = url.split("/"); String finalUrl = ""; String loginUrl = new String(); + if (this.mAuthPath != null && + !this.mAuthPath.equals("") && + !this.mAuthPath.equals("/")) { + authPath = this.mAuthPath; + } else { + authPath = "/exchweb/bin/auth/owaauth.dll"; + } + for (int i = 0; i <= 2; i++) { if (i != 0) { finalUrl = finalUrl + "/" + urlParts[i]; @@ -471,8 +500,11 @@ public class WebDavStore extends Store { * This is in a separate block because I really don't like how it's done. * This basically scrapes the OWA login page for the form submission URL. * UGLY! + * Added an if-check to see if there's a user supplied authentication path for FBA */ - { + if (this.mAuthPath == null || + this.mAuthPath.equals("") || + this.mAuthPath.equals("/")) { HttpGet httpget = new HttpGet(finalUrl); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); @@ -509,7 +541,12 @@ public class WebDavStore extends Store { ArrayList pairs = new ArrayList(); pairs.add(new BasicNameValuePair("username", username)); pairs.add(new BasicNameValuePair("password", password)); - pairs.add(new BasicNameValuePair("destination", url)); + if (this.mMailboxPath != null && + !this.mMailboxPath.equals("")) { + pairs.add(new BasicNameValuePair("destination", finalUrl + this.mMailboxPath)); + } else { + pairs.add(new BasicNameValuePair("destination", url)); + } pairs.add(new BasicNameValuePair("flags", "0")); pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On")); pairs.add(new BasicNameValuePair("forcedownlevel", "0")); @@ -554,14 +591,17 @@ public class WebDavStore extends Store { } } - if (tempUrl.equals("")) { + if (this.mMailboxPath != null && + !this.mMailboxPath.equals("")) { + this.mUrl = finalUrl + "/" + this.mMailboxPath + "/"; + } else if (tempUrl.equals("")) { this.mUrl = finalUrl + "/Exchange/" + this.alias + "/"; } else { this.mUrl = tempUrl; } } catch (UnsupportedEncodingException uee) { - Log.e(Email.LOG_TAG, "Error encoding POST data for authencation: " + uee + "\nTrace: " + processException(uee)); + Log.e(Email.LOG_TAG, "Error encoding POST data for authentication: " + uee + "\nTrace: " + processException(uee)); } } catch (SSLException e) { throw new CertificateValidationException(e.getMessage(), e);