Added support for optional Form Based Authentication login path and user mailbox path in account settings.

This commit is contained in:
Matthew Brace 2009-01-25 07:37:10 +00:00
parent 7d5d473563
commit de24b6a166
4 changed files with 133 additions and 34 deletions

View File

@ -112,6 +112,36 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="fill_parent" /> android:layout_width="fill_parent" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/webdav_path_debug_section"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:text="@string/account_setup_incoming_webdav_auth_path_label"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary" />
<EditText
android:id="@+id/webdav_auth_path"
android:hint="@string/account_setup_incoming_webdav_auth_path_hint"
android:singleLine="true"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<TextView
android:text="@string/account_setup_incoming_webdav_mailbox_path_label"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary" />
<EditText
android:id="@+id/webdav_mailbox_path"
android:hint="@string/account_setup_incoming_webdav_mailbox_path_hint"
android:singleLine="true"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</LinearLayout>
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="0px" android:layout_height="0px"

View File

@ -223,6 +223,11 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
<string name="account_setup_incoming_webdav_path_prefix_label">WebDav(Exchange) path</string> <string name="account_setup_incoming_webdav_path_prefix_label">WebDav(Exchange) path</string>
<string name="account_setup_incoming_webdav_path_prefix_hint">Optional</string> <string name="account_setup_incoming_webdav_path_prefix_hint">Optional</string>
<string name="account_setup_incoming_webdav_auth_path_label">Authentication path</string>
<string name="account_setup_incoming_webdav_auth_path_hint">Optional</string>
<string name="account_setup_incoming_webdav_mailbox_path_label">Mailbox path</string>
<string name="account_setup_incoming_webdav_mailbox_path_hint">Optional</string>
<string name="account_setup_outgoing_title">Outgoing server settings</string> <string name="account_setup_outgoing_title">Outgoing server settings</string>
<string name="account_setup_outgoing_smtp_server_label">SMTP server</string> <string name="account_setup_outgoing_smtp_server_label">SMTP server</string>
<string name="account_setup_outgoing_port_label">Port</string> <string name="account_setup_outgoing_port_label">Port</string>

View File

@ -61,6 +61,8 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
private Spinner mDeletePolicyView; private Spinner mDeletePolicyView;
private EditText mImapPathPrefixView; private EditText mImapPathPrefixView;
private EditText mWebdavPathPrefixView; private EditText mWebdavPathPrefixView;
private EditText mWebdavAuthPathView;
private EditText mWebdavMailboxPathView;
private Button mNextButton; private Button mNextButton;
private Account mAccount; private Account mAccount;
private boolean mMakeDefault; private boolean mMakeDefault;
@ -93,6 +95,8 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
mDeletePolicyView = (Spinner)findViewById(R.id.account_delete_policy); mDeletePolicyView = (Spinner)findViewById(R.id.account_delete_policy);
mImapPathPrefixView = (EditText)findViewById(R.id.imap_path_prefix); mImapPathPrefixView = (EditText)findViewById(R.id.imap_path_prefix);
mWebdavPathPrefixView = (EditText)findViewById(R.id.webdav_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 = (Button)findViewById(R.id.next);
mNextButton.setOnClickListener(this); 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.imap_path_prefix_section).setVisibility(View.GONE);
findViewById(R.id.webdav_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")) { } else if (uri.getScheme().startsWith("imap")) {
serverLabelView.setText(R.string.account_setup_incoming_imap_server_label); serverLabelView.setText(R.string.account_setup_incoming_imap_server_label);
mAccountPorts = imapPorts; mAccountPorts = imapPorts;
@ -215,6 +220,7 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
mImapPathPrefixView.setText(uri.getPath().substring(1)); mImapPathPrefixView.setText(uri.getPath().substring(1));
} }
findViewById(R.id.webdav_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("webdav")) { } else if (uri.getScheme().startsWith("webdav")) {
serverLabelView.setText(R.string.account_setup_incoming_webdav_server_label); serverLabelView.setText(R.string.account_setup_incoming_webdav_server_label);
mAccountPorts = webdavPorts; mAccountPorts = webdavPorts;
@ -223,7 +229,23 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
/** Hide the unnecessary fields */ /** Hide the unnecessary fields */
findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE); findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE);
if (uri.getPath() != null && uri.getPath().length() > 0) { 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 { } else {
throw new Error("Unknown account type: " + mAccount.getStoreUri()); throw new Error("Unknown account type: " + mAccount.getStoreUri());
@ -313,31 +335,33 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
} }
private void onNext() { private void onNext() {
int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value;
try { try {
String path = null; String path = null;
if (mAccountSchemes[securityType].startsWith("imap")) { if (mAccountSchemes[securityType].startsWith("imap")) {
path = "/" + mImapPathPrefixView.getText(); path = "/" + mImapPathPrefixView.getText();
} else if (mAccountSchemes[securityType].startsWith("webdav")) { } else if (mAccountSchemes[securityType].startsWith("webdav")) {
path = "/" + mWebdavPathPrefixView.getText(); path = "/" + mWebdavPathPrefixView.getText();
} path = path + "|" + mWebdavAuthPathView.getText();
path = path + "|" + mWebdavMailboxPathView.getText();
URI uri = new URI( }
mAccountSchemes[securityType],
mUsernameView.getText() + ":" + mPasswordView.getText(), URI uri = new URI(
mServerView.getText().toString(), mAccountSchemes[securityType],
Integer.parseInt(mPortView.getText().toString()), mUsernameView.getText() + ":" + mPasswordView.getText(),
path, // path mServerView.getText().toString(),
null, // query Integer.parseInt(mPortView.getText().toString()),
null); path, // path
mAccount.setStoreUri(uri.toString()); null, // query
} catch (URISyntaxException use) { null);
/* mAccount.setStoreUri(uri.toString());
* It's unrecoverable if we cannot create a URI from components that } catch (URISyntaxException use) {
* we validated to be safe. /*
*/ * It's unrecoverable if we cannot create a URI from components that
throw new Error(use); * we validated to be safe.
} */
throw new Error(use);
}
int deleteSpinnerVal = (Integer)((SpinnerOption)mDeletePolicyView.getSelectedItem()).value; int deleteSpinnerVal = (Integer)((SpinnerOption)mDeletePolicyView.getSelectedItem()).value;

View File

@ -85,6 +85,8 @@ public class WebDavStore extends Store {
private String mUrl; /* Stores the base URL for the server */ private String mUrl; /* Stores the base URL for the server */
private String mHost; /* Stores the host name for the server */ private String mHost; /* Stores the host name for the server */
private String mPath; /* Stores the path 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 URI mUri; /* Stores the Uniform Resource Indicator with all connection info */
private CookieStore mAuthCookies; /* Stores cookies from authentication */ private CookieStore mAuthCookies; /* Stores cookies from authentication */
@ -134,9 +136,28 @@ public class WebDavStore extends Store {
} }
} }
mPath = mUri.getPath(); String[] pathParts = mUri.getPath().split("\\|");
if (mPath == null) {
mPath = ""; 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 || if (mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED ||
@ -442,12 +463,20 @@ public class WebDavStore extends Store {
*/ */
public CookieStore doAuthentication(String username, String password, public CookieStore doAuthentication(String username, String password,
String url) throws IOException, MessagingException { String url) throws IOException, MessagingException {
String authPath = "/exchweb/bin/auth/owaauth.dll"; String authPath;
CookieStore cookies = null; CookieStore cookies = null;
String[] urlParts = url.split("/"); String[] urlParts = url.split("/");
String finalUrl = ""; String finalUrl = "";
String loginUrl = new String(); 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++) { for (int i = 0; i <= 2; i++) {
if (i != 0) { if (i != 0) {
finalUrl = finalUrl + "/" + urlParts[i]; 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 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. * This basically scrapes the OWA login page for the form submission URL.
* UGLY! * 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); HttpGet httpget = new HttpGet(finalUrl);
HttpResponse response = httpclient.execute(httpget); HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
@ -509,7 +541,12 @@ public class WebDavStore extends Store {
ArrayList<BasicNameValuePair> pairs = new ArrayList(); ArrayList<BasicNameValuePair> pairs = new ArrayList();
pairs.add(new BasicNameValuePair("username", username)); pairs.add(new BasicNameValuePair("username", username));
pairs.add(new BasicNameValuePair("password", password)); 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("flags", "0"));
pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On")); pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On"));
pairs.add(new BasicNameValuePair("forcedownlevel", "0")); 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 + "/"; this.mUrl = finalUrl + "/Exchange/" + this.alias + "/";
} else { } else {
this.mUrl = tempUrl; this.mUrl = tempUrl;
} }
} catch (UnsupportedEncodingException uee) { } 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) { } catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e); throw new CertificateValidationException(e.getMessage(), e);