0
0
mirror of https://github.com/thunderbird/thunderbird-android.git synced 2024-09-20 04:02:14 +02:00

Remove knowledge of store URI from :mail:protocols:webdav module

This commit is contained in:
cketti 2018-07-17 21:12:06 +02:00
parent 9cb5c70e4b
commit 7ca3806c33
8 changed files with 82 additions and 96 deletions

View File

@ -7,8 +7,9 @@ import com.fsck.k9.backend.api.Backend
import com.fsck.k9.backend.webdav.WebDavBackend
import com.fsck.k9.mail.ServerSettings
import com.fsck.k9.mail.store.webdav.WebDavStore
import com.fsck.k9.mail.store.webdav.WebDavStoreUriCreator
import com.fsck.k9.mail.store.webdav.WebDavStoreUriDecoder
import com.fsck.k9.mail.store.webdav.WebDavStoreSettings
import com.fsck.k9.backend.webdav.WebDavStoreUriCreator
import com.fsck.k9.backend.webdav.WebDavStoreUriDecoder
import com.fsck.k9.mail.transport.WebDavTransport
import com.fsck.k9.mailstore.K9BackendStorage
@ -18,13 +19,14 @@ class WebDavBackendFactory(private val preferences: Preferences) : BackendFactor
override fun createBackend(account: Account): Backend {
val accountName = account.description
val backendStorage = K9BackendStorage(preferences, account, account.localStore)
val webDavStore = createWebDavStore(account)
val webDavTransport = WebDavTransport(account)
val serverSettings = WebDavStoreUriDecoder.decode(account.storeUri)
val webDavStore = createWebDavStore(serverSettings, account)
val webDavTransport = WebDavTransport(serverSettings, account)
return WebDavBackend(accountName, backendStorage, webDavStore, webDavTransport)
}
private fun createWebDavStore(account: Account): WebDavStore {
return WebDavStore(account)
private fun createWebDavStore(serverSettings: WebDavStoreSettings, account: Account): WebDavStore {
return WebDavStore(serverSettings, account)
}
override fun decodeStoreUri(storeUri: String): ServerSettings {

View File

@ -1,7 +1,8 @@
package com.fsck.k9.mail.store.webdav;
package com.fsck.k9.backend.webdav;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.webdav.WebDavStoreSettings;
import java.net.URI;
import java.net.URISyntaxException;

View File

@ -1,7 +1,8 @@
package com.fsck.k9.mail.store.webdav;
package com.fsck.k9.backend.webdav;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.store.webdav.WebDavStoreSettings;
import java.net.URI;
import java.net.URISyntaxException;

View File

@ -1,4 +1,4 @@
package com.fsck.k9.mail.store.webdav;
package com.fsck.k9.backend.webdav;
import com.fsck.k9.mail.AuthType;

View File

@ -25,6 +25,7 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.webdav.WebDavHttpClient.WebDavHttpClientFactory;
import javax.net.ssl.SSLException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
@ -81,34 +82,27 @@ public class WebDavStore extends RemoteStore {
private Folder sendFolder = null;
private Map<String, WebDavFolder> folderList = new HashMap<>();
public WebDavStore(StoreConfig storeConfig) throws MessagingException {
this(storeConfig, new WebDavHttpClient.WebDavHttpClientFactory());
public WebDavStore(WebDavStoreSettings serverSettings, StoreConfig storeConfig) {
this(serverSettings, storeConfig, new WebDavHttpClient.WebDavHttpClientFactory());
}
public WebDavStore(StoreConfig storeConfig, WebDavHttpClient.WebDavHttpClientFactory clientFactory)
throws MessagingException {
public WebDavStore(WebDavStoreSettings serverSettings, StoreConfig storeConfig,
WebDavHttpClientFactory clientFactory) {
super(storeConfig, null);
httpClientFactory = clientFactory;
WebDavStoreSettings settings;
try {
settings = WebDavStoreUriDecoder.decode(storeConfig.getStoreUri());
} catch (IllegalArgumentException e) {
throw new MessagingException("Error while decoding store URI", e);
}
hostname = serverSettings.host;
port = serverSettings.port;
hostname = settings.host;
port = settings.port;
mConnectionSecurity = serverSettings.connectionSecurity;
mConnectionSecurity = settings.connectionSecurity;
username = serverSettings.username;
password = serverSettings.password;
alias = serverSettings.alias;
username = settings.username;
password = settings.password;
alias = settings.alias;
path = settings.path;
formBasedAuthPath = settings.authPath;
mailboxPath = settings.mailboxPath;
path = serverSettings.path;
formBasedAuthPath = serverSettings.authPath;
mailboxPath = serverSettings.mailboxPath;
if (path == null || path.equals("")) {
@ -138,10 +132,10 @@ public class WebDavStore extends RemoteStore {
private String getRoot() {
String root;
if (mConnectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
root = "https";
} else {
if (mConnectionSecurity == ConnectionSecurity.NONE) {
root = "http";
} else {
root = "https";
}
root += "://" + hostname + ":" + port;
return root;

View File

@ -1,17 +1,16 @@
package com.fsck.k9.mail.store.webdav;
import java.util.HashMap;
import java.util.Map;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
import java.util.HashMap;
import java.util.Map;
/**
* This class is used to store the decoded contents of an WebDavStore URI.
*
* @see WebDavStore#decodeUri(String)
*/
public class WebDavStoreSettings extends ServerSettings {
public static final String ALIAS_KEY = "alias";
@ -24,10 +23,9 @@ public class WebDavStoreSettings extends ServerSettings {
public final String authPath;
public final String mailboxPath;
protected WebDavStoreSettings(String host, int port, ConnectionSecurity connectionSecurity,
AuthType authenticationType, String username, String password,
String clientCertificateAlias, String alias,
String path, String authPath, String mailboxPath) {
public WebDavStoreSettings(String host, int port, ConnectionSecurity connectionSecurity,
AuthType authenticationType, String username, String password, String clientCertificateAlias, String alias,
String path, String authPath, String mailboxPath) {
super(Type.WebDAV, host, port, connectionSecurity, authenticationType, username,
password, clientCertificateAlias);
this.alias = alias;

View File

@ -1,22 +1,22 @@
package com.fsck.k9.mail.transport;
import java.util.Collections;
import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.webdav.WebDavHttpClient;
import com.fsck.k9.mail.store.webdav.WebDavStore;
import com.fsck.k9.mail.store.webdav.WebDavStoreSettings;
import timber.log.Timber;
import java.util.Collections;
public class WebDavTransport extends Transport {
private WebDavStore store;
public WebDavTransport(StoreConfig storeConfig) throws MessagingException {
store = new WebDavStore(storeConfig, new WebDavHttpClient.WebDavHttpClientFactory());
public WebDavTransport(WebDavStoreSettings serverSettings, StoreConfig storeConfig) {
store = new WebDavStore(serverSettings, storeConfig);
if (K9MailLib.isDebug())
Timber.d(">>> New WebDavTransport creation complete");

View File

@ -6,7 +6,9 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.K9LibRobolectricTestRunner;
import com.fsck.k9.mail.MessagingException;
@ -66,9 +68,13 @@ public class WebDavStoreTest {
private ArgumentCaptor<HttpGeneric> requestCaptor;
private StoreConfig storeConfig;
private WebDavStoreSettings serverSettings;
private WebDavStore webDavStore;
@Before
public void setUp() throws Exception {
public void setUp() {
MockitoAnnotations.initMocks(this);
HttpParams httpParams = new BasicHttpParams();
@ -76,28 +82,15 @@ public class WebDavStoreTest {
when(mockHttpClient.getParams()).thenReturn(httpParams);
when(mockHttpClient.getConnectionManager()).thenReturn(mockClientConnectionManager);
when(mockClientConnectionManager.getSchemeRegistry()).thenReturn(mockSchemeRegistry);
}
@Test(expected = MessagingException.class)
public void constructor_withImapStoreUri_shouldThrow() throws Exception {
StoreConfig storeConfig = createStoreConfig("imap://user:password@imap.example.org");
new WebDavStore(storeConfig, mockHttpClientFactory);
}
@Test
public void checkSettings_withHttpPrefixedServerName_shouldUseInsecureConnection() throws Exception {
WebDavStore webDavStore = createWebDavStore("webdav://user:password@http://server:123456");
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE);
webDavStore.checkSettings();
assertHttpClientUsesHttps(false);
storeConfig = createStoreConfig();
serverSettings = createWebDavStoreSettings(ConnectionSecurity.SSL_TLS_REQUIRED);
webDavStore = createWebDavStore();
}
@Test
public void checkSettings_withWebDavUri_shouldUseInsecureConnection() throws Exception {
WebDavStore webDavStore = createWebDavStore("webdav://user:password@server:123456");
WebDavStore webDavStore = createWebDavStore(ConnectionSecurity.NONE);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE);
webDavStore.checkSettings();
@ -107,7 +100,7 @@ public class WebDavStoreTest {
@Test
public void checkSettings_withWebDavSslUri_shouldUseSecureConnection() throws Exception {
WebDavStore webDavStore = createWebDavStore("webdav+ssl://user:password@server:123456");
WebDavStore webDavStore = createWebDavStore(ConnectionSecurity.SSL_TLS_REQUIRED);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE);
webDavStore.checkSettings();
@ -117,7 +110,7 @@ public class WebDavStoreTest {
@Test
public void checkSettings_withWebDavTlsUri_shouldUseSecureConnection() throws Exception {
WebDavStore webDavStore = createWebDavStore("webdav+tls://user:password@server:123456");
WebDavStore webDavStore = createWebDavStore(ConnectionSecurity.STARTTLS_REQUIRED);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE);
webDavStore.checkSettings();
@ -127,7 +120,6 @@ public class WebDavStoreTest {
@Test
public void checkSettings_withOkResponse_shouldPerformFormBasedAuthentication() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
ArgumentCaptor<HttpGeneric> requestCaptor = ArgumentCaptor.forClass(HttpGeneric.class);
when(mockHttpClient.executeOverride(requestCaptor.capture(), any(HttpContext.class)))
.thenReturn(OK_200_RESPONSE)
@ -141,15 +133,14 @@ public class WebDavStoreTest {
assertEquals(4, requests.size());
assertEquals("GET", requests.get(0).getMethod()); // Checking auth type
assertEquals("POST", requests.get(1).getMethod()); // Posting form data
assertEquals("http://example.org:80/exchweb/bin/auth/owaauth.dll", requests.get(1).getURI().toString());
assertEquals("https://webdav.example.org:443/exchweb/bin/auth/owaauth.dll", requests.get(1).getURI().toString());
assertEquals("POST", requests.get(2).getMethod()); // Confirming login
assertEquals("http://example.org:80/exchweb/bin/auth/owaauth.dll", requests.get(2).getURI().toString());
assertEquals("https://webdav.example.org:443/exchweb/bin/auth/owaauth.dll", requests.get(2).getURI().toString());
assertEquals("GET", requests.get(3).getMethod()); // Getting response
}
@Test
public void checkSettings_withInitialUnauthorizedResponse_shouldPerformBasicAuthentication() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE);
webDavStore.checkSettings();
@ -164,7 +155,6 @@ public class WebDavStoreTest {
@Test(expected = MessagingException.class)
public void checkSettings_withUnauthorizedResponses_shouldThrow() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, UNAUTHORIZED_401_RESPONSE);
webDavStore.checkSettings();
@ -172,7 +162,6 @@ public class WebDavStoreTest {
@Test(expected = MessagingException.class)
public void checkSettings_withErrorResponse_shouldThrow() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, SERVER_ERROR_500_RESPONSE);
webDavStore.checkSettings();
@ -180,7 +169,6 @@ public class WebDavStoreTest {
@Test(expected = CertificateValidationException.class)
public void checkSettings_withSslException_shouldThrowCertificateValidationException() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
ArgumentCaptor<HttpGeneric> requestCaptor = ArgumentCaptor.forClass(HttpGeneric.class);
when(mockHttpClient.executeOverride(requestCaptor.capture(), any(HttpContext.class)))
.thenThrow(new SSLException("Test"));
@ -191,7 +179,6 @@ public class WebDavStoreTest {
//TODO: Is this really something we want to test?
@Test
public void checkSettings_shouldRegisterHttpsSchemeWithRegistry() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE);
webDavStore.checkSettings();
@ -203,17 +190,14 @@ public class WebDavStoreTest {
}
@Test
public void getFolder_shouldReturnWebDavFolderInstance() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
public void getFolder_shouldReturnWebDavFolderInstance() {
Folder result = webDavStore.getFolder("INBOX");
assertEquals(WebDavFolder.class, result.getClass());
}
@Test
public void getFolder_calledTwice_shouldReturnFirstInstance() throws Exception {
WebDavStore webDavStore = createDefaultWebDavStore();
public void getFolder_calledTwice_shouldReturnFirstInstance() {
String folderName = "Trash";
Folder webDavFolder = webDavStore.getFolder(folderName);
@ -224,8 +208,6 @@ public class WebDavStoreTest {
@Test
public void getPersonalNamespaces_shouldRequestSpecialFolders() throws Exception {
StoreConfig storeConfig = createStoreConfig("webdav://user:password@example.org:80");
WebDavStore webDavStore = new WebDavStore(storeConfig, mockHttpClientFactory);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE, createOkPropfindResponse(),
createOkSearchResponse());
@ -238,8 +220,6 @@ public class WebDavStoreTest {
@Test
public void getPersonalNamespaces_shouldSetSpecialFolderNames() throws Exception {
StoreConfig storeConfig = createStoreConfig("webdav://user:password@example.org:80");
WebDavStore webDavStore = new WebDavStore(storeConfig, mockHttpClientFactory);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE, createOkPropfindResponse(),
createOkSearchResponse());
@ -250,8 +230,6 @@ public class WebDavStoreTest {
@Test
public void getPersonalNamespaces_shouldRequestFolderList() throws Exception {
StoreConfig storeConfig = createStoreConfig("webdav://user:password@example.org:80");
WebDavStore webDavStore = new WebDavStore(storeConfig, mockHttpClientFactory);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE, createOkPropfindResponse(),
createOkSearchResponse());
@ -264,8 +242,6 @@ public class WebDavStoreTest {
@Test
public void getPersonalNamespaces_shouldProvideListOfAllFoldersSentFromResponses() throws Exception {
StoreConfig storeConfig = createStoreConfig("webdav://user:password@example.org:80");
WebDavStore webDavStore = new WebDavStore(storeConfig, mockHttpClientFactory);
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE, createOkPropfindResponse(),
createOkSearchResponse());
@ -337,7 +313,7 @@ public class WebDavStoreTest {
private Answer<HttpResponse> createOkResponseWithCookie() {
return new Answer<HttpResponse>() {
@Override
public HttpResponse answer(InvocationOnMock invocation) throws Throwable {
public HttpResponse answer(InvocationOnMock invocation) {
HttpContext context = (HttpContext) invocation.getArguments()[1];
if (context.getAttribute(ClientContext.COOKIE_STORE) != null) {
BasicCookieStore cookieStore =
@ -351,20 +327,34 @@ public class WebDavStoreTest {
};
}
private StoreConfig createStoreConfig(String storeUri) {
private StoreConfig createStoreConfig() {
StoreConfig storeConfig = mock(StoreConfig.class);
when(storeConfig.getInboxFolder()).thenReturn("INBOX");
when(storeConfig.getStoreUri()).thenReturn(storeUri);
return storeConfig;
}
private WebDavStore createWebDavStore(String storeUri) throws MessagingException {
StoreConfig storeConfig = createStoreConfig(storeUri);
return new WebDavStore(storeConfig, mockHttpClientFactory);
private WebDavStoreSettings createWebDavStoreSettings(ConnectionSecurity connectionSecurity) {
return new WebDavStoreSettings(
"webdav.example.org",
443,
connectionSecurity,
AuthType.PLAIN,
"user",
"password",
null,
null,
null,
null,
null);
}
private WebDavStore createDefaultWebDavStore() throws MessagingException {
return createWebDavStore("webdav://user:password@example.org:80");
private WebDavStore createWebDavStore() {
return new WebDavStore(serverSettings, storeConfig, mockHttpClientFactory);
}
private WebDavStore createWebDavStore(ConnectionSecurity connectionSecurity) {
WebDavStoreSettings serverSettings = createWebDavStoreSettings(connectionSecurity);
return new WebDavStore(serverSettings, storeConfig, mockHttpClientFactory);
}
private void configureHttpResponses(HttpResponse... responses) throws IOException {