Search in sources :

Example 1 with FixedMimeMessage

use of com.zimbra.cs.mime.Mime.FixedMimeMessage in project zm-mailbox by Zimbra.

the class MailSenderTest method updateReferenceHeaders.

@Test
public void updateReferenceHeaders() throws Exception {
    MailSender sender = new MailSender();
    Provisioning prov = Provisioning.getInstance();
    Account account = prov.getAccount(MockProvisioning.DEFAULT_ACCOUNT_ID);
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
    String from = "sender@example.com";
    String to = "recipient@example.com";
    String subject = "test subject";
    MessageBuilder builder = new MessageBuilder().withFrom(from).withToRecipient(to).withSubject(subject).withBody("test body");
    String content = builder.create();
    MimeMessage msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    // default
    Assert.assertNull(msg.getHeader("Thread-Index"));
    Assert.assertNull(msg.getHeader("Thread-Topic"));
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    // technically the normalized subject, but our test message already had normalized subject
    Assert.assertEquals(subject, msg.getHeader("Thread-Topic")[0]);
    // index set by sending agent (bg 96107)
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    String presetIndex = "1234";
    msg.setHeader("Thread-Index", presetIndex);
    Assert.assertNull(msg.getHeader("Thread-Topic"));
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(subject, msg.getHeader("Thread-Topic")[0]);
    Assert.assertEquals(presetIndex, msg.getHeader("Thread-Index")[0]);
    // topic set by sending agent (bug 96107)
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    Assert.assertNull(msg.getHeader("Thread-Index"));
    String presetTopic = "mytopic";
    msg.setHeader("Thread-Topic", presetTopic);
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(presetTopic, msg.getHeader("Thread-Topic")[0]);
    // both
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    msg.setHeader("Thread-Topic", presetTopic);
    msg.setHeader("Thread-Index", presetIndex);
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(presetTopic, msg.getHeader("Thread-Topic")[0]);
    Assert.assertEquals(presetIndex, msg.getHeader("Thread-Index")[0]);
    // subject changed from orig parent subject (bug 96954)
    String parentSubject = "parent subject";
    builder = new MessageBuilder().withFrom(from).withToRecipient(to).withSubject(parentSubject).withBody("parent body");
    String parentContent = builder.create();
    MimeMessage parentMsg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(parentContent.getBytes()));
    sender.updateReferenceHeaders(parentMsg, null, account);
    ParsedMessage pm = new ParsedMessage(parentMsg, false);
    Message mboxMessage = mbox.addMessage(null, pm, MailboxTest.STANDARD_DELIVERY_OPTIONS, null);
    sender = new MailSender();
    sender.setOriginalMessageId(new ItemId(mboxMessage));
    sender.setReplyType(MailSender.MSGTYPE_REPLY);
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(subject, msg.getHeader("Thread-Topic")[0]);
    // keep agent specified topic and/or index even when parent specified
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    msg.setHeader("Thread-Topic", presetTopic);
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(presetTopic, msg.getHeader("Thread-Topic")[0]);
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    msg.setHeader("Thread-Index", presetIndex);
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(subject, msg.getHeader("Thread-Topic")[0]);
    Assert.assertEquals(presetIndex, msg.getHeader("Thread-Index")[0]);
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    msg.setHeader("Thread-Topic", presetTopic);
    msg.setHeader("Thread-Index", presetIndex);
    sender.updateReferenceHeaders(msg, null, account);
    Assert.assertEquals(1, msg.getHeader("Thread-Index").length);
    Assert.assertEquals(1, msg.getHeader("Thread-Topic").length);
    Assert.assertEquals(presetTopic, msg.getHeader("Thread-Topic")[0]);
    Assert.assertEquals(presetIndex, msg.getHeader("Thread-Index")[0]);
}
Also used : Account(com.zimbra.cs.account.Account) MessageBuilder(com.zimbra.qa.unittest.MessageBuilder) MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) ItemId(com.zimbra.cs.service.util.ItemId) MockProvisioning(com.zimbra.cs.account.MockProvisioning) Provisioning(com.zimbra.cs.account.Provisioning) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream) Test(org.junit.Test)

Example 2 with FixedMimeMessage

use of com.zimbra.cs.mime.Mime.FixedMimeMessage in project zm-mailbox by Zimbra.

the class FixedMimeMessageTest method contentTransferEncoding.

@Test
public void contentTransferEncoding() throws Exception {
    String raw = "From: sender@zimbra.com\n" + "To: recipient@zimbra.com\n" + "Subject: test\n" + "Content-Type: text/plain; charset=ISO-2022-JP\n" + "\n" + "\u3042\u3042\u3042\u3044\u3044\u3044\u3046\u3046\u3046\u3048\u3048\u3048\u304a\u304a\u304a";
    MimeMessage message = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(raw.getBytes(Charsets.UTF_8)));
    Assert.assertNull(message.getEncoding());
    message.setHeader("X-TEST", "test");
    message.saveChanges();
    // Assert.assertNull(message.getEncoding());
    message = new FixedMimeMessage(JMSession.getSession());
    message.setHeader("X-TEST", "test");
    message.setText("\u3042\u3042\u3042\u3044\u3044\u3044\u3046\u3046\u3046\u3048\u3048\u3048\u304a\u304a\u304a", "ISO-2022-JP");
    message.saveChanges();
    Assert.assertEquals("7bit", message.getEncoding());
    message = new FixedMimeMessage(JMSession.getSession());
    message.setHeader("X-TEST", "test");
    message.setText("\u3042\u3042\u3042\u3044\u3044\u3044\u3046\u3046\u3046\u3048\u3048\u3048\u304a\u304a\u304a", "UTF-8");
    message.saveChanges();
    Assert.assertEquals("8bit", message.getEncoding());
}
Also used : FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream) Test(org.junit.Test)

Example 3 with FixedMimeMessage

use of com.zimbra.cs.mime.Mime.FixedMimeMessage in project zm-mailbox by Zimbra.

the class TestMailSender method testRestrictEnvelopeSender.

@Test
public void testRestrictEnvelopeSender() throws Exception {
    Server server = Provisioning.getInstance().getLocalServer();
    server.setSmtpPort(TEST_SMTP_PORT);
    Mailbox mbox = TestUtil.getMailbox(SENDER_NAME);
    Account account = mbox.getAccount();
    // Create a message with a different From header value.
    String from = TestUtil.getAddress("testRestrictEnvelopeSender");
    String subject = NAME_PREFIX + " testRestrictEnvelopeSender";
    MessageBuilder builder = new MessageBuilder().withFrom(from).withToRecipient(RECIPIENT_NAME).withSubject(subject).withBody("Who are you?");
    String content = builder.create();
    MimeMessage msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    account.setSmtpRestrictEnvelopeFrom(true);
    // Restrict envelope sender, disallow custom from.
    account.setAllowAnyFromAddress(false);
    DummySmtpServer smtp = startDummySmtpServer(null, null);
    mbox.getMailSender().sendMimeMessage(null, mbox, msg);
    Assert.assertEquals(account.getName(), smtp.getMailFrom());
    // Test contains to handle personal name
    Assert.assertTrue(getHeaderValue(smtp.getDataLines(), "From").contains(account.getName()));
    // Restrict envelope sender, allow custom from.
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    account.setAllowAnyFromAddress(true);
    smtp = startDummySmtpServer(null, null);
    mbox.getMailSender().sendMimeMessage(null, mbox, msg);
    Assert.assertEquals(account.getName(), smtp.getMailFrom());
    Assert.assertEquals(from, getHeaderValue(smtp.getDataLines(), "From"));
    account.setSmtpRestrictEnvelopeFrom(false);
    // Don't restrict envelope sender, disallow custom from.
    account.setAllowAnyFromAddress(false);
    smtp = startDummySmtpServer(null, null);
    mbox.getMailSender().sendMimeMessage(null, mbox, msg);
    Assert.assertEquals(account.getName(), smtp.getMailFrom());
    Assert.assertTrue(getHeaderValue(smtp.getDataLines(), "From").contains(account.getName()));
    // Don't restrict envelope sender, allow custom from.
    msg = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(content.getBytes()));
    account.setAllowAnyFromAddress(true);
    smtp = startDummySmtpServer(null, null);
    mbox.getMailSender().sendMimeMessage(null, mbox, msg);
    Assert.assertEquals(from, smtp.getMailFrom());
    Assert.assertEquals(from, getHeaderValue(smtp.getDataLines(), "From"));
}
Also used : Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream) Test(org.junit.Test)

Example 4 with FixedMimeMessage

use of com.zimbra.cs.mime.Mime.FixedMimeMessage in project zm-mailbox by Zimbra.

the class FixedMimeMessageTest method messageId.

@Test
public void messageId() throws Exception {
    String raw = "From: sender@zimbra.com\n" + "To: recipient@zimbra.com\n" + "Subject: test\n" + "\n" + "Hello World.";
    MimeMessage message = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(raw.getBytes()));
    Assert.assertNull(message.getMessageID());
    message.setHeader("X-TEST", "test");
    message.saveChanges();
    Assert.assertNotNull(message.getMessageID());
    raw = "From: sender@zimbra.com\n" + "To: recipient@zimbra.com\n" + "Subject: test\n" + "Message-ID: <12345@zimbra.com>" + "\n" + "Hello World.";
    message = new FixedMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(raw.getBytes()));
    Assert.assertEquals("<12345@zimbra.com>", message.getMessageID());
    message.setHeader("X-TEST", "test");
    message.saveChanges();
    Assert.assertEquals("<12345@zimbra.com>", message.getMessageID());
}
Also used : FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream) Test(org.junit.Test)

Example 5 with FixedMimeMessage

use of com.zimbra.cs.mime.Mime.FixedMimeMessage in project zm-mailbox by Zimbra.

the class CalendarRequest method sendCalendarMessageInternal.

/**
 * Send an iCalendar email message and optionally create/update/cancel
 * corresponding appointment/invite in sender's calendar.
 * @param zsc
 * @param apptFolderId
 * @param acct
 * @param mbox
 * @param csd
 * @param response
 * @param updateOwnAppointment if true, corresponding change is made to
 *                             sender's calendar
 * @param forceSend
 * @param sendQueue
 * @param updatePrevFolders if true, updates prevFolders field with Trash in database
 * @return
 * @throws ServiceException
 */
private static Element sendCalendarMessageInternal(ZimbraSoapContext zsc, OperationContext octxt, int apptFolderId, Account acct, Mailbox mbox, CalSendData csd, Element response, boolean updateOwnAppointment, boolean forceSend, MailSendQueue sendQueue, boolean updatePrevFolders) throws ServiceException {
    boolean onBehalfOf = isOnBehalfOfRequest(zsc);
    boolean notifyOwner = onBehalfOf && acct.getBooleanAttr(Provisioning.A_zimbraPrefCalendarNotifyDelegatedChanges, false);
    if (notifyOwner) {
        try {
            InternetAddress addr = AccountUtil.getFriendlyEmailAddress(acct);
            csd.mMm.addRecipient(javax.mail.Message.RecipientType.TO, addr);
        } catch (MessagingException e) {
            throw ServiceException.FAILURE("count not add calendar owner to recipient list", e);
        }
    }
    // in a non-delegated request.
    if (!onBehalfOf) {
        String[] aliases = acct.getMailAlias();
        String[] addrs;
        if (aliases != null && aliases.length > 0) {
            addrs = new String[aliases.length + 1];
            addrs[0] = acct.getAttr(Provisioning.A_mail);
            for (int i = 0; i < aliases.length; i++) {
                addrs[i + 1] = aliases[i];
            }
        } else {
            addrs = new String[1];
            addrs[0] = acct.getAttr(Provisioning.A_mail);
        }
        try {
            Mime.removeRecipients(csd.mMm, addrs);
        } catch (MessagingException e) {
        }
    }
    ParsedMessage pm = new ParsedMessage(csd.mMm, false);
    if (csd.mInvite.getFragment() == null || csd.mInvite.getFragment().equals("")) {
        csd.mInvite.setFragment(pm.getFragment(acct.getLocale()));
    }
    boolean willNotify = false;
    if (!csd.mDontNotifyAttendees) {
        try {
            Address[] rcpts = csd.mMm.getAllRecipients();
            willNotify = rcpts != null && rcpts.length > 0;
        } catch (MessagingException e) {
            throw ServiceException.FAILURE("Checking recipients of outgoing msg ", e);
        }
    }
    // Validate the addresses first.
    if (!csd.mInvite.isCancel() && !forceSend && willNotify) {
        try {
            MailUtil.validateRcptAddresses(JMSession.getSmtpSession(mbox.getAccount()), csd.mMm.getAllRecipients());
        } catch (MessagingException mex) {
            if (mex instanceof SendFailedException) {
                SendFailedException sfex = (SendFailedException) mex;
                throw MailServiceException.SEND_ABORTED_ADDRESS_FAILURE("invalid addresses", sfex, sfex.getInvalidAddresses(), sfex.getValidUnsentAddresses());
            }
        }
    }
    AddInviteData aid = null;
    File tempMmFile = null;
    boolean queued = false;
    try {
        if (willNotify) {
            // Write out the MimeMessage to a temp file and create a new MimeMessage from the file.
            // If we don't do this, we get into trouble during modify appointment call.  If the blob
            // is bigger than the streaming threshold (e.g. appointment has a big attachment), the
            // MimeMessage object is attached to the current blob file.  But the Mailbox.addInvite()
            // call below updates the blob to a new mod_content (hence new path).  The attached blob
            // thus having been deleted, the MainSender.sendMimeMessage() call that follows will attempt
            // to read from a non-existent file and fail.  We can avoid this situation by writing the
            // to-be-emailed mime message to a temp file, thus detaching it from the appointment's
            // current blob file.  This is inefficient, but safe.
            OutputStream os = null;
            InputStream is = null;
            try {
                tempMmFile = File.createTempFile("zcal", "tmp");
                os = new FileOutputStream(tempMmFile);
                csd.mMm.writeTo(os);
                ByteUtil.closeStream(os);
                os = null;
                is = new ZSharedFileInputStream(tempMmFile);
                csd.mMm = new FixedMimeMessage(JMSession.getSmtpSession(acct), is);
            } catch (IOException e) {
                if (tempMmFile != null)
                    tempMmFile.delete();
                throw ServiceException.FAILURE("error creating calendar message content", e);
            } catch (MessagingException e) {
                if (tempMmFile != null)
                    tempMmFile.delete();
                throw ServiceException.FAILURE("error creating calendar message content", e);
            } finally {
                ByteUtil.closeStream(os);
                ByteUtil.closeStream(is);
            }
        }
        // because email send will delete uploaded attachments as a side-effect.
        if (updateOwnAppointment) {
            aid = mbox.addInvite(octxt, csd.mInvite, apptFolderId, pm, updatePrevFolders);
        }
        // Next, notify any attendees.
        if (willNotify) {
            MailSendQueueEntry entry = new MailSendQueueEntry(octxt, mbox, csd, tempMmFile);
            sendQueue.add(entry);
            queued = true;
        }
    } finally {
        // Delete the temp file if it wasn't queued.
        if (tempMmFile != null && !queued) {
            tempMmFile.delete();
        }
    }
    if (updateOwnAppointment && response != null && aid != null) {
        csd.mAddInvData = aid;
        ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
        String id = ifmt.formatItemId(aid.calItemId);
        response.addAttribute(MailConstants.A_CAL_ID, id);
        if (csd.mInvite.isEvent())
            // for backward compat
            response.addAttribute(MailConstants.A_APPT_ID_DEPRECATE_ME, id);
        response.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(aid.calItemId, aid.invId));
        if (Invite.isOrganizerMethod(csd.mInvite.getMethod())) {
            response.addAttribute(MailConstants.A_MODIFIED_SEQUENCE, aid.modSeq);
            response.addAttribute(MailConstants.A_REVISION, aid.rev);
        }
    }
    return response;
}
Also used : InternetAddress(javax.mail.internet.InternetAddress) SendFailedException(javax.mail.SendFailedException) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) MessagingException(javax.mail.MessagingException) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) AddInviteData(com.zimbra.cs.mailbox.Mailbox.AddInviteData) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) IOException(java.io.IOException) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) FileOutputStream(java.io.FileOutputStream) File(java.io.File)

Aggregations

FixedMimeMessage (com.zimbra.cs.mime.Mime.FixedMimeMessage)6 MimeMessage (javax.mail.internet.MimeMessage)5 SharedByteArrayInputStream (javax.mail.util.SharedByteArrayInputStream)5 Test (org.junit.Test)4 Account (com.zimbra.cs.account.Account)2 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 MessagingException (javax.mail.MessagingException)2 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)1 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)1 ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)1 ZSharedFileInputStream (com.zimbra.common.zmime.ZSharedFileInputStream)1 MockProvisioning (com.zimbra.cs.account.MockProvisioning)1 Provisioning (com.zimbra.cs.account.Provisioning)1 Server (com.zimbra.cs.account.Server)1 Mailbox (com.zimbra.cs.mailbox.Mailbox)1 AddInviteData (com.zimbra.cs.mailbox.Mailbox.AddInviteData)1 ItemId (com.zimbra.cs.service.util.ItemId)1 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)1