Search in sources :

Example 1 with Transport

use of com.fsck.k9.mail.Transport in project k-9 by k9mail.

the class MessagingController method sendPendingMessagesSynchronous.

/**
     * Attempt to send any messages that are sitting in the Outbox.
     */
@VisibleForTesting
protected void sendPendingMessagesSynchronous(final Account account) {
    LocalFolder localFolder = null;
    Exception lastFailure = null;
    boolean wasPermanentFailure = false;
    try {
        LocalStore localStore = account.getLocalStore();
        localFolder = localStore.getFolder(account.getOutboxFolderName());
        if (!localFolder.exists()) {
            Timber.v("Outbox does not exist");
            return;
        }
        for (MessagingListener l : getListeners()) {
            l.sendPendingMessagesStarted(account);
        }
        localFolder.open(Folder.OPEN_MODE_RW);
        List<LocalMessage> localMessages = localFolder.getMessages(null);
        int progress = 0;
        int todo = localMessages.size();
        for (MessagingListener l : getListeners()) {
            l.synchronizeMailboxProgress(account, account.getSentFolderName(), progress, todo);
        }
        /*
             * The profile we will use to pull all of the content
             * for a given local message into memory for sending.
             */
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);
        fp.add(FetchProfile.Item.BODY);
        Timber.i("Scanning folder '%s' (%d) for messages to send", account.getOutboxFolderName(), localFolder.getId());
        Transport transport = transportProvider.getTransport(K9.app, account);
        for (LocalMessage message : localMessages) {
            if (message.isSet(Flag.DELETED)) {
                message.destroy();
                continue;
            }
            try {
                AtomicInteger count = new AtomicInteger(0);
                AtomicInteger oldCount = sendCount.putIfAbsent(message.getUid(), count);
                if (oldCount != null) {
                    count = oldCount;
                }
                Timber.i("Send count for message %s is %d", message.getUid(), count.get());
                if (count.incrementAndGet() > K9.MAX_SEND_ATTEMPTS) {
                    Timber.e("Send count for message %s can't be delivered after %d attempts. " + "Giving up until the user restarts the device", message.getUid(), MAX_SEND_ATTEMPTS);
                    notificationController.showSendFailedNotification(account, new MessagingException(message.getSubject()));
                    continue;
                }
                localFolder.fetch(Collections.singletonList(message), fp, null);
                try {
                    if (message.getHeader(K9.IDENTITY_HEADER).length > 0) {
                        Timber.v("The user has set the Outbox and Drafts folder to the same thing. " + "This message appears to be a draft, so K-9 will not send it");
                        continue;
                    }
                    message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
                    Timber.i("Sending message with UID %s", message.getUid());
                    transport.sendMessage(message);
                    message.setFlag(Flag.X_SEND_IN_PROGRESS, false);
                    message.setFlag(Flag.SEEN, true);
                    progress++;
                    for (MessagingListener l : getListeners()) {
                        l.synchronizeMailboxProgress(account, account.getSentFolderName(), progress, todo);
                    }
                    moveOrDeleteSentMessage(account, localStore, localFolder, message);
                } catch (AuthenticationFailedException e) {
                    lastFailure = e;
                    wasPermanentFailure = false;
                    handleAuthenticationFailure(account, false);
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                } catch (CertificateValidationException e) {
                    lastFailure = e;
                    wasPermanentFailure = false;
                    notifyUserIfCertificateProblem(account, e, false);
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                } catch (MessagingException e) {
                    lastFailure = e;
                    wasPermanentFailure = e.isPermanentFailure();
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                } catch (Exception e) {
                    lastFailure = e;
                    wasPermanentFailure = true;
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                }
            } catch (Exception e) {
                lastFailure = e;
                wasPermanentFailure = false;
                Timber.e(e, "Failed to fetch message for sending");
                addErrorMessage(account, "Failed to fetch message for sending", e);
                notifySynchronizeMailboxFailed(account, localFolder, e);
            }
        }
        for (MessagingListener l : getListeners()) {
            l.sendPendingMessagesCompleted(account);
        }
        if (lastFailure != null) {
            if (wasPermanentFailure) {
                notificationController.showSendFailedNotification(account, lastFailure);
            } else {
                notificationController.showSendFailedNotification(account, lastFailure);
            }
        }
    } catch (UnavailableStorageException e) {
        Timber.i("Failed to send pending messages because storage is not available - trying again later.");
        throw new UnavailableAccountException(e);
    } catch (Exception e) {
        Timber.v(e, "Failed to send pending messages");
        for (MessagingListener l : getListeners()) {
            l.sendPendingMessagesFailed(account);
        }
        addErrorMessage(account, null, e);
    } finally {
        if (lastFailure == null) {
            notificationController.clearSendFailedNotification(account);
        }
        closeFolder(localFolder);
    }
}
Also used : LocalMessage(com.fsck.k9.mailstore.LocalMessage) FetchProfile(com.fsck.k9.mail.FetchProfile) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) LocalStore(com.fsck.k9.mailstore.LocalStore) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) SuppressLint(android.annotation.SuppressLint) LocalFolder(com.fsck.k9.mailstore.LocalFolder) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) Transport(com.fsck.k9.mail.Transport) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 2 with Transport

use of com.fsck.k9.mail.Transport in project k-9 by k9mail.

the class SmtpTransportTest method sendMessage_with8BitEncoding.

@Test
public void sendMessage_with8BitEncoding() throws Exception {
    Message message = getDefaultMessage();
    MockSmtpServer server = createServerAndSetupForPlainAuthentication("8BITMIME");
    server.expect("MAIL FROM:<user@localhost> BODY=8BITMIME");
    server.output("250 OK");
    server.expect("RCPT TO:<user2@localhost>");
    server.output("250 OK");
    server.expect("DATA");
    server.output("354 End data with <CR><LF>.<CR><LF>");
    server.expect("[message data]");
    server.expect(".");
    server.output("250 OK: queued as 12345");
    server.expect("QUIT");
    server.output("221 BYE");
    server.closeConnection();
    SmtpTransport transport = startServerAndCreateSmtpTransport(server);
    transport.sendMessage(message);
    server.verifyConnectionClosed();
    server.verifyInteractionCompleted();
}
Also used : MimeMessage(com.fsck.k9.mail.internet.MimeMessage) Message(com.fsck.k9.mail.Message) MockSmtpServer(com.fsck.k9.mail.transport.mockServer.MockSmtpServer) XOAuth2ChallengeParserTest(com.fsck.k9.mail.XOAuth2ChallengeParserTest) Test(org.junit.Test)

Example 3 with Transport

use of com.fsck.k9.mail.Transport in project k-9 by k9mail.

the class SmtpTransportTest method open_withXoauth2Extension.

@Test
public void open_withXoauth2Extension() throws Exception {
    MockSmtpServer server = new MockSmtpServer();
    server.output("220 localhost Simple Mail Transfer Service Ready");
    server.expect("EHLO localhost");
    server.output("250-localhost Hello client.localhost");
    server.output("250 AUTH XOAUTH2");
    server.expect("AUTH XOAUTH2 dXNlcj11c2VyAWF1dGg9QmVhcmVyIG9sZFRva2VuAQE=");
    server.output("235 2.7.0 Authentication successful");
    SmtpTransport transport = startServerAndCreateSmtpTransport(server, AuthType.XOAUTH2, ConnectionSecurity.NONE);
    transport.open();
    server.verifyConnectionStillOpen();
    server.verifyInteractionCompleted();
}
Also used : MockSmtpServer(com.fsck.k9.mail.transport.mockServer.MockSmtpServer) XOAuth2ChallengeParserTest(com.fsck.k9.mail.XOAuth2ChallengeParserTest) Test(org.junit.Test)

Example 4 with Transport

use of com.fsck.k9.mail.Transport in project k-9 by k9mail.

the class SmtpTransportTest method open_withXoauth2Extension_shouldThrowOnFailure_fetchingToken.

@Test
public void open_withXoauth2Extension_shouldThrowOnFailure_fetchingToken() throws Exception {
    MockSmtpServer server = new MockSmtpServer();
    server.output("220 localhost Simple Mail Transfer Service Ready");
    server.expect("EHLO localhost");
    server.output("250-localhost Hello client.localhost");
    server.output("250 AUTH XOAUTH2");
    server.expect("QUIT");
    server.output("221 BYE");
    when(oAuth2TokenProvider.getToken(anyString(), anyInt())).thenThrow(new AuthenticationFailedException("Failed to fetch token"));
    SmtpTransport transport = startServerAndCreateSmtpTransport(server, AuthType.XOAUTH2, ConnectionSecurity.NONE);
    try {
        transport.open();
        fail("Exception expected");
    } catch (AuthenticationFailedException e) {
        assertEquals("Failed to fetch token", e.getMessage());
    }
    server.verifyConnectionClosed();
    server.verifyInteractionCompleted();
}
Also used : AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) MockSmtpServer(com.fsck.k9.mail.transport.mockServer.MockSmtpServer) XOAuth2ChallengeParserTest(com.fsck.k9.mail.XOAuth2ChallengeParserTest) Test(org.junit.Test)

Example 5 with Transport

use of com.fsck.k9.mail.Transport in project k-9 by k9mail.

the class SmtpTransportTest method open_withoutCramMd5AuthExtension_shouldThrow.

@Test
public void open_withoutCramMd5AuthExtension_shouldThrow() throws Exception {
    MockSmtpServer server = new MockSmtpServer();
    server.output("220 localhost Simple Mail Transfer Service Ready");
    server.expect("EHLO localhost");
    server.output("250-localhost Hello client.localhost");
    server.output("250 AUTH PLAIN LOGIN");
    server.expect("QUIT");
    server.output("221 BYE");
    SmtpTransport transport = startServerAndCreateSmtpTransport(server, AuthType.CRAM_MD5, ConnectionSecurity.NONE);
    try {
        transport.open();
        fail("Exception expected");
    } catch (MessagingException e) {
        assertEquals("Authentication method CRAM-MD5 is unavailable.", e.getMessage());
    }
    server.verifyConnectionClosed();
    server.verifyInteractionCompleted();
}
Also used : MessagingException(com.fsck.k9.mail.MessagingException) MockSmtpServer(com.fsck.k9.mail.transport.mockServer.MockSmtpServer) XOAuth2ChallengeParserTest(com.fsck.k9.mail.XOAuth2ChallengeParserTest) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)29 XOAuth2ChallengeParserTest (com.fsck.k9.mail.XOAuth2ChallengeParserTest)27 MockSmtpServer (com.fsck.k9.mail.transport.mockServer.MockSmtpServer)27 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)6 MessagingException (com.fsck.k9.mail.MessagingException)6 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)6 Message (com.fsck.k9.mail.Message)5 InOrder (org.mockito.InOrder)5 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)3 SuppressLint (android.annotation.SuppressLint)1 VisibleForTesting (android.support.annotation.VisibleForTesting)1 FetchProfile (com.fsck.k9.mail.FetchProfile)1 Transport (com.fsck.k9.mail.Transport)1 LocalFolder (com.fsck.k9.mailstore.LocalFolder)1 LocalMessage (com.fsck.k9.mailstore.LocalMessage)1 LocalStore (com.fsck.k9.mailstore.LocalStore)1 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)1 IOException (java.io.IOException)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1