Search in sources :

Example 11 with MimeMultipart

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

the class MessageBuilder method buildBody.

private void buildBody(MimeMessage message) throws MessagingException {
    // Build the body.
    // TODO FIXME - body can be either an HTML or Text part, depending on whether we're in
    // HTML mode or not.  Should probably fix this so we don't mix up html and text parts.
    TextBody body = buildText(isDraft);
    // text/plain part when messageFormat == MessageFormat.HTML
    TextBody bodyPlain = null;
    final boolean hasAttachments = !attachments.isEmpty();
    if (messageFormat == SimpleMessageFormat.HTML) {
        // HTML message (with alternative text part)
        // This is the compiled MIME part for an HTML message.
        MimeMultipart composedMimeMessage = createMimeMultipart();
        composedMimeMessage.setSubType("alternative");
        // Let the receiver select either the text or the HTML part.
        bodyPlain = buildText(isDraft, SimpleMessageFormat.TEXT);
        composedMimeMessage.addBodyPart(new MimeBodyPart(bodyPlain, "text/plain"));
        composedMimeMessage.addBodyPart(new MimeBodyPart(body, "text/html"));
        if (hasAttachments) {
            // If we're HTML and have attachments, we have a MimeMultipart container to hold the
            // whole message (mp here), of which one part is a MimeMultipart container
            // (composedMimeMessage) with the user's composed messages, and subsequent parts for
            // the attachments.
            MimeMultipart mp = createMimeMultipart();
            mp.addBodyPart(new MimeBodyPart(composedMimeMessage));
            addAttachmentsToMessage(mp);
            MimeMessageHelper.setBody(message, mp);
        } else {
            // If no attachments, our multipart/alternative part is the only one we need.
            MimeMessageHelper.setBody(message, composedMimeMessage);
        }
    } else if (messageFormat == SimpleMessageFormat.TEXT) {
        // Text-only message.
        if (hasAttachments) {
            MimeMultipart mp = createMimeMultipart();
            mp.addBodyPart(new MimeBodyPart(body, "text/plain"));
            addAttachmentsToMessage(mp);
            MimeMessageHelper.setBody(message, mp);
        } else {
            // No attachments to include, just stick the text body in the message and call it good.
            MimeMessageHelper.setBody(message, body);
        }
    }
    // If this is a draft, add metadata for thawing.
    if (isDraft) {
        // Add the identity to the message.
        message.addHeader(K9.IDENTITY_HEADER, buildIdentityHeader(body, bodyPlain));
    }
}
Also used : TextBody(com.fsck.k9.mail.internet.TextBody) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart)

Example 12 with MimeMultipart

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

the class PgpMessageBuilderTest method buildSign__withDetachedSignatureInResult__shouldSucceed.

@Test
public void buildSign__withDetachedSignatureInResult__shouldSucceed() throws MessagingException {
    cryptoStatusBuilder.setCryptoMode(CryptoMode.SIGN_ONLY);
    pgpMessageBuilder.setCryptoStatus(cryptoStatusBuilder.build());
    ArgumentCaptor<Intent> capturedApiIntent = ArgumentCaptor.forClass(Intent.class);
    Intent returnIntent = new Intent();
    returnIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
    returnIntent.putExtra(OpenPgpApi.RESULT_DETACHED_SIGNATURE, new byte[] { 1, 2, 3 });
    when(openPgpApi.executeApi(capturedApiIntent.capture(), any(OpenPgpDataSource.class), any(OutputStream.class))).thenReturn(returnIntent);
    Callback mockCallback = mock(Callback.class);
    pgpMessageBuilder.buildAsync(mockCallback);
    Intent expectedIntent = new Intent(OpenPgpApi.ACTION_DETACHED_SIGN);
    expectedIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, TEST_SIGN_KEY_ID);
    expectedIntent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
    assertIntentEqualsActionAndExtras(expectedIntent, capturedApiIntent.getValue());
    ArgumentCaptor<MimeMessage> captor = ArgumentCaptor.forClass(MimeMessage.class);
    verify(mockCallback).onMessageBuildSuccess(captor.capture(), eq(false));
    verifyNoMoreInteractions(mockCallback);
    MimeMessage message = captor.getValue();
    Assert.assertEquals("message must be multipart/signed", "multipart/signed", message.getMimeType());
    MimeMultipart multipart = (MimeMultipart) message.getBody();
    Assert.assertEquals("multipart/signed must consist of two parts", 2, multipart.getCount());
    BodyPart contentBodyPart = multipart.getBodyPart(0);
    Assert.assertEquals("first part must have content type text/plain", "text/plain", MimeUtility.getHeaderParameter(contentBodyPart.getContentType(), null));
    Assert.assertTrue("signed message body must be TextBody", contentBodyPart.getBody() instanceof TextBody);
    Assert.assertEquals(MimeUtil.ENC_QUOTED_PRINTABLE, ((TextBody) contentBodyPart.getBody()).getEncoding());
    assertContentOfBodyPartEquals("content must match the message text", contentBodyPart, TEST_MESSAGE_TEXT);
    BodyPart signatureBodyPart = multipart.getBodyPart(1);
    String contentType = signatureBodyPart.getContentType();
    Assert.assertEquals("second part must be pgp signature", "application/pgp-signature", MimeUtility.getHeaderParameter(contentType, null));
    Assert.assertEquals("second part must be called signature.asc", "signature.asc", MimeUtility.getHeaderParameter(contentType, "name"));
    assertContentOfBodyPartEquals("content must match the supplied detached signature", signatureBodyPart, new byte[] { 1, 2, 3 });
}
Also used : TextBody(com.fsck.k9.mail.internet.TextBody) BodyPart(com.fsck.k9.mail.BodyPart) Callback(com.fsck.k9.message.MessageBuilder.Callback) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) OpenPgpDataSource(org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource) Test(org.junit.Test)

Example 13 with MimeMultipart

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

the class PgpMessageBuilderTest method buildEncrypt__shouldSucceed.

@Test
public void buildEncrypt__shouldSucceed() throws MessagingException {
    ComposeCryptoStatus cryptoStatus = cryptoStatusBuilder.setCryptoMode(CryptoMode.PRIVATE).setRecipients(Collections.singletonList(new Recipient("test", "test@example.org", "labru", -1, "key"))).build();
    pgpMessageBuilder.setCryptoStatus(cryptoStatus);
    ArgumentCaptor<Intent> capturedApiIntent = ArgumentCaptor.forClass(Intent.class);
    Intent returnIntent = new Intent();
    returnIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
    when(openPgpApi.executeApi(capturedApiIntent.capture(), any(OpenPgpDataSource.class), any(OutputStream.class))).thenReturn(returnIntent);
    Callback mockCallback = mock(Callback.class);
    pgpMessageBuilder.buildAsync(mockCallback);
    Intent expectedApiIntent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
    expectedApiIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, TEST_SIGN_KEY_ID);
    expectedApiIntent.putExtra(OpenPgpApi.EXTRA_KEY_IDS, new long[] { TEST_SELF_ENCRYPT_KEY_ID });
    expectedApiIntent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
    expectedApiIntent.putExtra(OpenPgpApi.EXTRA_ENCRYPT_OPPORTUNISTIC, false);
    expectedApiIntent.putExtra(OpenPgpApi.EXTRA_USER_IDS, cryptoStatus.getRecipientAddresses());
    assertIntentEqualsActionAndExtras(expectedApiIntent, capturedApiIntent.getValue());
    ArgumentCaptor<MimeMessage> captor = ArgumentCaptor.forClass(MimeMessage.class);
    verify(mockCallback).onMessageBuildSuccess(captor.capture(), eq(false));
    verifyNoMoreInteractions(mockCallback);
    MimeMessage message = captor.getValue();
    Assert.assertEquals("message must be multipart/encrypted", "multipart/encrypted", message.getMimeType());
    MimeMultipart multipart = (MimeMultipart) message.getBody();
    Assert.assertEquals("multipart/encrypted must consist of two parts", 2, multipart.getCount());
    BodyPart dummyBodyPart = multipart.getBodyPart(0);
    Assert.assertEquals("first part must be pgp encrypted dummy part", "application/pgp-encrypted", dummyBodyPart.getContentType());
    assertContentOfBodyPartEquals("content must match the supplied detached signature", dummyBodyPart, "Version: 1");
    BodyPart encryptedBodyPart = multipart.getBodyPart(1);
    Assert.assertEquals("second part must be octet-stream of encrypted data", "application/octet-stream; name=\"encrypted.asc\"", encryptedBodyPart.getContentType());
    Assert.assertTrue("message body must be BinaryTempFileBody", encryptedBodyPart.getBody() instanceof BinaryTempFileBody);
    Assert.assertEquals(MimeUtil.ENC_7BIT, ((BinaryTempFileBody) encryptedBodyPart.getBody()).getEncoding());
}
Also used : BodyPart(com.fsck.k9.mail.BodyPart) Callback(com.fsck.k9.message.MessageBuilder.Callback) BinaryTempFileBody(com.fsck.k9.mail.internet.BinaryTempFileBody) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) ComposeCryptoStatus(com.fsck.k9.activity.compose.ComposeCryptoStatus) Recipient(com.fsck.k9.view.RecipientSelectView.Recipient) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) OpenPgpDataSource(org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource) Test(org.junit.Test)

Example 14 with MimeMultipart

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

the class MessageBuilderTest method build_usingHtmlFormat_shouldUseMultipartAlternativeInCorrectOrder.

@Test
public void build_usingHtmlFormat_shouldUseMultipartAlternativeInCorrectOrder() {
    MessageBuilder messageBuilder = createHtmlMessageBuilder();
    messageBuilder.buildAsync(callback);
    MimeMessage message = getMessageFromCallback();
    assertEquals(MimeMultipart.class, message.getBody().getClass());
    assertEquals("multipart/alternative", ((MimeMultipart) message.getBody()).getMimeType());
    List<BodyPart> parts = ((MimeMultipart) message.getBody()).getBodyParts();
    //RFC 2046 - 5.1.4. - Best type is last displayable
    assertEquals("text/plain", parts.get(0).getMimeType());
    assertEquals("text/html", parts.get(1).getMimeType());
}
Also used : BodyPart(com.fsck.k9.mail.BodyPart) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) Test(org.junit.Test)

Example 15 with MimeMultipart

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

the class LocalStoreTest method findPartById__withNestedLocalBodyPart.

@Test
public void findPartById__withNestedLocalBodyPart() throws Exception {
    LocalBodyPart searchRoot = new LocalBodyPart(null, null, 1L, -1L);
    LocalBodyPart needlePart = new LocalBodyPart(null, null, 123L, -1L);
    MimeMultipart mimeMultipart = new MimeMultipart("boundary");
    mimeMultipart.addBodyPart(needlePart);
    searchRoot.setBody(mimeMultipart);
    Part part = LocalStore.findPartById(searchRoot, 123L);
    assertSame(needlePart, part);
}
Also used : MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) Part(com.fsck.k9.mail.Part) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart) Test(org.junit.Test)

Aggregations

MimeMultipart (com.fsck.k9.mail.internet.MimeMultipart)18 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)14 Test (org.junit.Test)10 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)9 Part (com.fsck.k9.mail.Part)8 BodyPart (com.fsck.k9.mail.BodyPart)7 TextBody (com.fsck.k9.mail.internet.TextBody)7 Body (com.fsck.k9.mail.Body)3 PendingIntent (android.app.PendingIntent)2 Intent (android.content.Intent)2 MessagingException (com.fsck.k9.mail.MessagingException)2 BinaryTempFileBody (com.fsck.k9.mail.internet.BinaryTempFileBody)2 Viewable (com.fsck.k9.mail.internet.Viewable)2 ViewableExtractedText (com.fsck.k9.mailstore.MessageViewInfoExtractor.ViewableExtractedText)2 Callback (com.fsck.k9.message.MessageBuilder.Callback)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 OutputStream (java.io.OutputStream)2 ArrayList (java.util.ArrayList)2 OpenPgpDataSource (org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource)2 Nullable (android.support.annotation.Nullable)1