Merge pull request #3965 from k9mail/cleanup_ProvidersXmlDiscovery
Clean up ProvidersXmlDiscovery
This commit is contained in:
commit
57062fd558
5 changed files with 168 additions and 147 deletions
|
@ -1,132 +0,0 @@
|
|||
package com.fsck.k9.autodiscovery.providersxml;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import android.content.res.XmlResourceParser;
|
||||
|
||||
import com.fsck.k9.autodiscovery.ConnectionSettings;
|
||||
import com.fsck.k9.autodiscovery.ConnectionSettingsDiscovery;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||
import com.fsck.k9.mail.ServerSettings;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
||||
public class ProvidersXmlDiscovery implements ConnectionSettingsDiscovery {
|
||||
private final BackendManager backendManager;
|
||||
private final ProvidersXmlProvider xmlProvider;
|
||||
|
||||
|
||||
public ProvidersXmlDiscovery(BackendManager backendManager, ProvidersXmlProvider xmlProvider) {
|
||||
this.backendManager = backendManager;
|
||||
this.xmlProvider = xmlProvider;
|
||||
}
|
||||
|
||||
private String[] splitEmail(String email) {
|
||||
String[] retParts = new String[2];
|
||||
String[] emailParts = email.split("@");
|
||||
retParts[0] = (emailParts.length > 0) ? emailParts[0] : "";
|
||||
retParts[1] = (emailParts.length > 1) ? emailParts[1] : "";
|
||||
return retParts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionSettings discover(String email) {
|
||||
String password = "";
|
||||
String[] emailParts = splitEmail(email);
|
||||
String user = emailParts[0];
|
||||
String domain = emailParts[1];
|
||||
Provider mProvider = findProviderForDomain(domain);
|
||||
if (mProvider == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
String userEnc = UrlEncodingHelper.encodeUtf8(user);
|
||||
String passwordEnc = UrlEncodingHelper.encodeUtf8(password);
|
||||
|
||||
String incomingUsername = mProvider.incomingUsernameTemplate;
|
||||
incomingUsername = incomingUsername.replaceAll("\\$email", email);
|
||||
incomingUsername = incomingUsername.replaceAll("\\$user", userEnc);
|
||||
incomingUsername = incomingUsername.replaceAll("\\$domain", domain);
|
||||
|
||||
URI incomingUriTemplate = mProvider.incomingUriTemplate;
|
||||
URI incomingUri = new URI(incomingUriTemplate.getScheme(), incomingUsername + ":" + passwordEnc,
|
||||
incomingUriTemplate.getHost(), incomingUriTemplate.getPort(), null, null, null);
|
||||
|
||||
String outgoingUsername = mProvider.outgoingUsernameTemplate;
|
||||
|
||||
URI outgoingUriTemplate = mProvider.outgoingUriTemplate;
|
||||
|
||||
|
||||
URI outgoingUri;
|
||||
if (outgoingUsername != null) {
|
||||
outgoingUsername = outgoingUsername.replaceAll("\\$email", email);
|
||||
outgoingUsername = outgoingUsername.replaceAll("\\$user", userEnc);
|
||||
outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain);
|
||||
outgoingUri = new URI(outgoingUriTemplate.getScheme(), outgoingUsername + ":"
|
||||
+ passwordEnc, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
|
||||
null, null);
|
||||
|
||||
} else {
|
||||
outgoingUri = new URI(outgoingUriTemplate.getScheme(),
|
||||
null, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
|
||||
null, null);
|
||||
}
|
||||
|
||||
ServerSettings incomingSettings = backendManager.decodeStoreUri(incomingUri.toString());
|
||||
ServerSettings outgoingSettings = backendManager.decodeTransportUri(outgoingUri.toString());
|
||||
return new ConnectionSettings(incomingSettings, outgoingSettings);
|
||||
} catch (URISyntaxException use) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Provider findProviderForDomain(String domain) {
|
||||
try {
|
||||
XmlResourceParser xml = xmlProvider.getXml();
|
||||
int xmlEventType;
|
||||
Provider provider = null;
|
||||
while ((xmlEventType = xml.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (xmlEventType == XmlPullParser.START_TAG &&
|
||||
"provider".equals(xml.getName()) &&
|
||||
domain.equalsIgnoreCase(xml.getAttributeValue(null, "domain"))) {
|
||||
provider = new Provider();
|
||||
provider.id = xml.getAttributeValue(null, "id");
|
||||
provider.label = xml.getAttributeValue(null, "label");
|
||||
provider.domain = xml.getAttributeValue(null, "domain");
|
||||
} else if (xmlEventType == XmlPullParser.START_TAG &&
|
||||
"incoming".equals(xml.getName()) &&
|
||||
provider != null) {
|
||||
provider.incomingUriTemplate = new URI(xml.getAttributeValue(null, "uri"));
|
||||
provider.incomingUsernameTemplate = xml.getAttributeValue(null, "username");
|
||||
} else if (xmlEventType == XmlPullParser.START_TAG &&
|
||||
"outgoing".equals(xml.getName()) &&
|
||||
provider != null) {
|
||||
provider.outgoingUriTemplate = new URI(xml.getAttributeValue(null, "uri"));
|
||||
provider.outgoingUsernameTemplate = xml.getAttributeValue(null, "username");
|
||||
} else if (xmlEventType == XmlPullParser.END_TAG &&
|
||||
"provider".equals(xml.getName()) &&
|
||||
provider != null) {
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Timber.e(e, "Error while trying to load provider settings.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static class Provider {
|
||||
String id;
|
||||
String label;
|
||||
String domain;
|
||||
URI incomingUriTemplate;
|
||||
String incomingUsernameTemplate;
|
||||
URI outgoingUriTemplate;
|
||||
String outgoingUsernameTemplate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package com.fsck.k9.autodiscovery.providersxml
|
||||
|
||||
import android.content.res.XmlResourceParser
|
||||
import com.fsck.k9.autodiscovery.ConnectionSettings
|
||||
import com.fsck.k9.autodiscovery.ConnectionSettingsDiscovery
|
||||
import com.fsck.k9.backend.BackendManager
|
||||
import com.fsck.k9.helper.EmailHelper
|
||||
import com.fsck.k9.helper.UrlEncodingHelper
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import timber.log.Timber
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
|
||||
class ProvidersXmlDiscovery(
|
||||
private val backendManager: BackendManager,
|
||||
private val xmlProvider: ProvidersXmlProvider
|
||||
) : ConnectionSettingsDiscovery {
|
||||
|
||||
override fun discover(email: String): ConnectionSettings? {
|
||||
val password = ""
|
||||
|
||||
val user = EmailHelper.getLocalPartFromEmailAddress(email) ?: return null
|
||||
val domain = EmailHelper.getDomainFromEmailAddress(email) ?: return null
|
||||
|
||||
val provider = findProviderForDomain(domain) ?: return null
|
||||
try {
|
||||
val userUrlEncoded = UrlEncodingHelper.encodeUtf8(user)
|
||||
val emailUrlEncoded = UrlEncodingHelper.encodeUtf8(email)
|
||||
|
||||
val incomingUserUrlEncoded = provider.incomingUsernameTemplate
|
||||
.replace("\$email", emailUrlEncoded)
|
||||
.replace("\$user", userUrlEncoded)
|
||||
.replace("\$domain", domain)
|
||||
val incomingUri = with(URI(provider.incomingUriTemplate)) {
|
||||
URI(scheme, "$incomingUserUrlEncoded:$password", host, port, null, null, null).toString()
|
||||
}
|
||||
val incomingSettings = backendManager.decodeStoreUri(incomingUri)
|
||||
|
||||
val outgoingUserUrlEncoded = provider.outgoingUsernameTemplate
|
||||
?.replace("\$email", emailUrlEncoded)
|
||||
?.replace("\$user", userUrlEncoded)
|
||||
?.replace("\$domain", domain)
|
||||
val outgoingUserInfo = if (outgoingUserUrlEncoded != null) "$outgoingUserUrlEncoded:$password" else null
|
||||
val outgoingUri = with(URI(provider.outgoingUriTemplate)) {
|
||||
URI(scheme, outgoingUserInfo, host, port, null, null, null).toString()
|
||||
}
|
||||
val outgoingSettings = backendManager.decodeTransportUri(outgoingUri)
|
||||
|
||||
return ConnectionSettings(incomingSettings, outgoingSettings)
|
||||
} catch (use: URISyntaxException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun findProviderForDomain(domain: String): Provider? {
|
||||
return try {
|
||||
xmlProvider.getXml().use { xml ->
|
||||
parseProviders(xml, domain)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while trying to load provider settings.")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseProviders(xml: XmlResourceParser, domain: String): Provider? {
|
||||
do {
|
||||
val xmlEventType = xml.next()
|
||||
if (xmlEventType == XmlPullParser.START_TAG && xml.name == "provider") {
|
||||
val providerDomain = xml.getAttributeValue(null, "domain")
|
||||
if (domain.equals(providerDomain, ignoreCase = true)) {
|
||||
val provider = parseProvider(xml)
|
||||
if (provider != null) return provider
|
||||
}
|
||||
}
|
||||
} while (xmlEventType != XmlPullParser.END_DOCUMENT)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun parseProvider(xml: XmlResourceParser): Provider? {
|
||||
var incomingUriTemplate: String? = null
|
||||
var incomingUsernameTemplate: String? = null
|
||||
var outgoingUriTemplate: String? = null
|
||||
var outgoingUsernameTemplate: String? = null
|
||||
|
||||
do {
|
||||
val xmlEventType = xml.next()
|
||||
if (xmlEventType == XmlPullParser.START_TAG) {
|
||||
when (xml.name) {
|
||||
"incoming" -> {
|
||||
incomingUriTemplate = xml.getAttributeValue(null, "uri")
|
||||
incomingUsernameTemplate = xml.getAttributeValue(null, "username")
|
||||
}
|
||||
"outgoing" -> {
|
||||
outgoingUriTemplate = xml.getAttributeValue(null, "uri")
|
||||
outgoingUsernameTemplate = xml.getAttributeValue(null, "username")
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!(xmlEventType == XmlPullParser.END_TAG && xml.name == "provider"))
|
||||
|
||||
return if (incomingUriTemplate != null && incomingUsernameTemplate != null &&
|
||||
outgoingUriTemplate != null) {
|
||||
Provider(incomingUriTemplate, incomingUsernameTemplate, outgoingUriTemplate, outgoingUsernameTemplate)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal data class Provider(
|
||||
val incomingUriTemplate: String,
|
||||
val incomingUsernameTemplate: String,
|
||||
val outgoingUriTemplate: String,
|
||||
val outgoingUsernameTemplate: String?
|
||||
)
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package com.fsck.k9.helper;
|
||||
|
||||
|
||||
public final class EmailHelper {
|
||||
private EmailHelper() {}
|
||||
|
||||
public static String getDomainFromEmailAddress(String email) {
|
||||
int separatorIndex = email.lastIndexOf('@');
|
||||
if (separatorIndex == -1 || separatorIndex + 1 == email.length()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return email.substring(separatorIndex + 1);
|
||||
}
|
||||
}
|
15
app/core/src/main/java/com/fsck/k9/helper/EmailHelper.kt
Normal file
15
app/core/src/main/java/com/fsck/k9/helper/EmailHelper.kt
Normal file
|
@ -0,0 +1,15 @@
|
|||
package com.fsck.k9.helper
|
||||
|
||||
object EmailHelper {
|
||||
@JvmStatic
|
||||
fun getLocalPartFromEmailAddress(email: String): String? {
|
||||
val index = email.lastIndexOf('@')
|
||||
return if (index == -1 || index == email.lastIndex) null else email.substring(0, index)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDomainFromEmailAddress(email: String): String? {
|
||||
val index = email.lastIndexOf('@')
|
||||
return if (index == -1 || index == email.lastIndex) null else email.substring(index + 1)
|
||||
}
|
||||
}
|
|
@ -28,4 +28,39 @@ public class EmailHelperTest {
|
|||
|
||||
assertEquals("domain", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDomainFromEmailAddress_withEmptyDomain_shouldReturnNull() {
|
||||
String result = EmailHelper.getDomainFromEmailAddress("user@");
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalPartFromEmailAddress_withRegularEmail_shouldReturnLocalPart() {
|
||||
String result = EmailHelper.getLocalPartFromEmailAddress("user@domain.com");
|
||||
|
||||
assertEquals("user", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalPartFromEmailAddress_withAtInLocalPart_shouldReturnLocalPart() {
|
||||
String result = EmailHelper.getLocalPartFromEmailAddress("\"user@work\"@domain");
|
||||
|
||||
assertEquals("\"user@work\"", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalPartFromEmailAddress_withInvalidEmail_shouldReturnNull() {
|
||||
String result = EmailHelper.getLocalPartFromEmailAddress("user");
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalPartFromEmailAddress_withEmptyDomain_shouldReturnNull() {
|
||||
String result = EmailHelper.getLocalPartFromEmailAddress("user@");
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue