Search in sources :

Example 66 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class CalendarMailSender method createCalendarMessage.

public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, String subject, String desc, String descHtml, String uid, ZCalendar.ZVCalendar cal, List<Attach> attaches, boolean replyToSender) throws ServiceException {
    if (desc == null)
        desc = "";
    try {
        MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
        MimeMultipart mpAlternatives = new ZMimeMultipart("alternative");
        if (attaches != null && !attaches.isEmpty()) {
            MimeMultipart mpMixed = new ZMimeMultipart("mixed");
            mm.setContent(mpMixed);
            MimeBodyPart mbpWrapper = new ZMimeBodyPart();
            mbpWrapper.setContent(mpAlternatives);
            mpMixed.addBodyPart(mbpWrapper);
            for (Attach attach : attaches) {
                byte[] rawData = attach.getDecodedData();
                if (rawData == null) {
                    continue;
                }
                ContentDisposition cdisp = new ContentDisposition(Part.ATTACHMENT, true);
                String ctypeAsString = attach.getContentType();
                if (ctypeAsString == null) {
                    ctypeAsString = MimeConstants.CT_APPLICATION_OCTET_STREAM;
                }
                ContentType ctype = new ContentType(ctypeAsString);
                if (attach.getFileName() != null) {
                    ctype.setParameter("name", attach.getFileName());
                    cdisp.setParameter("filename", attach.getFileName());
                }
                MimeBodyPart mbp2 = new ZMimeBodyPart();
                ByteArrayDataSource bads = new ByteArrayDataSource(rawData, ctypeAsString);
                mbp2.setDataHandler(new DataHandler(bads));
                mbp2.setHeader("Content-Type", ctype.toString());
                mbp2.setHeader("Content-Disposition", cdisp.toString());
                mbp2.setHeader("Content-Transfer-Encoding", "base64");
                mpMixed.addBodyPart(mbp2);
            }
        } else {
            mm.setContent(mpAlternatives);
        }
        // Add the text as DESCRIPTION property in the iCalendar part.
        // MS Entourage for Mac wants this.  It ignores text/plain and
        // text/html MIME parts.
        cal.addDescription(desc, null);
        // ///////
        // TEXT part (add me first!)
        MimeBodyPart textPart = new ZMimeBodyPart();
        textPart.setText(desc, MimeConstants.P_CHARSET_UTF8);
        mpAlternatives.addBodyPart(textPart);
        // HTML part is needed to keep Outlook happy as it doesn't know
        // how to deal with a message with only text/plain but no HTML.
        MimeBodyPart htmlPart = new ZMimeBodyPart();
        if (descHtml != null) {
            ContentType ct = new ContentType(MimeConstants.CT_TEXT_HTML);
            ct.setParameter(MimeConstants.P_CHARSET, MimeConstants.P_CHARSET_UTF8);
            htmlPart.setText(descHtml, MimeConstants.P_CHARSET_UTF8);
            htmlPart.setHeader("Content-Type", ct.toString());
        } else {
            htmlPart.setDataHandler(new DataHandler(new HtmlPartDataSource(desc)));
        }
        mpAlternatives.addBodyPart(htmlPart);
        // ///////
        // CALENDAR part
        MimeBodyPart icalPart = makeICalIntoMimePart(cal);
        mpAlternatives.addBodyPart(icalPart);
        // MESSAGE HEADERS
        if (subject != null) {
            mm.setSubject(subject, MimeConstants.P_CHARSET_UTF8);
        }
        if (toAddrs != null) {
            Address[] addrs = new Address[toAddrs.size()];
            toAddrs.toArray(addrs);
            mm.addRecipients(javax.mail.Message.RecipientType.TO, addrs);
        }
        if (fromAddr != null)
            mm.setFrom(fromAddr);
        if (senderAddr != null) {
            mm.setSender(senderAddr);
            if (replyToSender) {
                mm.setReplyTo(new Address[] { senderAddr });
            }
        }
        mm.setSentDate(new Date());
        mm.saveChanges();
        return mm;
    } catch (MessagingException e) {
        throw ServiceException.FAILURE("Messaging Exception while building MimeMessage from invite", e);
    }
}
Also used : ContentType(javax.mail.internet.ContentType) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) Attach(com.zimbra.common.calendar.Attach) DataHandler(javax.activation.DataHandler) Date(java.util.Date) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Example 67 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class SendShareNotification method generateShareNotification.

protected MimeMessage generateShareNotification(Account authAccount, Account ownerAccount, ShareInfoData sid, String notes, Action action, Collection<String> internlaRecipients, String externalRecipient) throws ServiceException, MessagingException {
    Locale locale = authAccount.getLocale();
    String charset = authAccount.getAttr(Provisioning.A_zimbraPrefMailDefaultCharset, MimeConstants.P_CHARSET_UTF8);
    MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(authAccount));
    MsgKey subjectKey;
    if (action == null) {
        subjectKey = MsgKey.shareNotifSubject;
    } else {
        switch(action) {
            case edit:
                subjectKey = MsgKey.shareModifySubject;
                break;
            case revoke:
                subjectKey = MsgKey.shareRevokeSubject;
                break;
            case expire:
                subjectKey = MsgKey.shareExpireSubject;
                break;
            default:
                subjectKey = MsgKey.shareNotifSubject;
        }
    }
    String subject = L10nUtil.getMessage(subjectKey, locale);
    String ownerAcctDisplayName = ownerAccount.getDisplayName();
    if (ownerAcctDisplayName == null) {
        ownerAcctDisplayName = ownerAccount.getName();
    }
    subject += L10nUtil.getMessage(MsgKey.sharedBySubject, locale, sid.getName(), ownerAcctDisplayName);
    mm.setSubject(subject, CharsetUtil.checkCharset(subject, charset));
    mm.setSentDate(new Date());
    // from the owner
    mm.setFrom(AccountUtil.getFriendlyEmailAddress(ownerAccount));
    // sent by auth account
    mm.setSender(AccountUtil.getFriendlyEmailAddress(authAccount));
    // to the grantee
    if (internlaRecipients != null) {
        assert (externalRecipient == null);
        for (String recipient : internlaRecipients) {
            try {
                mm.addRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(recipient));
            } catch (AddressException e) {
                sLog.warn("Ignoring error while sending share notification to " + recipient, e);
            }
        }
    } else if (externalRecipient != null) {
        mm.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(externalRecipient));
    } else {
        String recipient = sid.getGranteeName();
        mm.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(recipient));
    }
    MimeMultipart mmp = ShareInfo.NotificationSender.genNotifBody(sid, notes, locale, action, externalRecipient);
    mm.setContent(mmp);
    mm.saveChanges();
    if (sLog.isDebugEnabled()) {
        // log4j.logger.com.zimbra.cs.service.mail=DEBUG
        try {
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            mm.writeTo(buf);
            String mmDump = new String(buf.toByteArray());
            sLog.debug("********\n" + mmDump);
        } catch (MessagingException e) {
            sLog.debug("failed log debug share notification message", e);
        } catch (IOException e) {
            sLog.debug("failed log debug share notification message", e);
        }
    }
    return mm;
}
Also used : Locale(java.util.Locale) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) MessagingException(javax.mail.MessagingException) MsgKey(com.zimbra.common.util.L10nUtil.MsgKey) AddressException(javax.mail.internet.AddressException) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Date(java.util.Date)

Example 68 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class SpamHandler method sendReport.

private void sendReport(SpamReport sr) throws ServiceException, MessagingException {
    Config config = Provisioning.getInstance().getConfig();
    String isSpamString = sr.isSpam ? config.getSpamReportTypeSpam() : config.getSpamReportTypeHam();
    SMTPMessage out = new SMTPMessage(JMSession.getSmtpSession());
    Mailbox mbox = MailboxManager.getInstance().getMailboxById(sr.mailboxId);
    Message msg = mbox.getMessageById(null, sr.messageId);
    MimeMultipart mmp = new ZMimeMultipart("mixed");
    MimeBodyPart infoPart = new ZMimeBodyPart();
    infoPart.setHeader("Content-Description", "Zimbra spam classification report");
    String body = String.format("Classified-By: %s\r\n" + "Classified-As: %s\r\n" + "Action: %s\r\n" + "Source-Folder: %s\r\n" + "Destination-Folder: %s\r\n" + "Destination-Mailbox: %s\r\n", Strings.nullToEmpty(sr.accountName), isSpamString, Strings.nullToEmpty(sr.action), Strings.nullToEmpty(sr.sourceFolder), Strings.nullToEmpty(sr.destFolder), Strings.nullToEmpty(sr.destAccountName));
    infoPart.setText(body);
    mmp.addBodyPart(infoPart);
    MailboxBlob blob = msg.getBlob();
    MimeBodyPart mbp = new ZMimeBodyPart();
    mbp.setDataHandler(new DataHandler(new MailboxBlobDataSource(blob)));
    mbp.setHeader("Content-Type", MimeConstants.CT_MESSAGE_RFC822);
    mbp.setHeader("Content-Disposition", Part.ATTACHMENT);
    mmp.addBodyPart(mbp);
    out.setContent(mmp);
    out.addHeader(config.getSpamReportSenderHeader(), sr.accountName);
    out.addHeader(config.getSpamReportTypeHeader(), isSpamString);
    if (config.isSmtpSendAddOriginatingIP() && sr.origIp != null)
        out.addHeader(MailSender.X_ORIGINATING_IP, MailSender.formatXOrigIpHeader(sr.origIp));
    out.setRecipient(javax.mail.Message.RecipientType.TO, sr.reportRecipient);
    out.setEnvelopeFrom(config.getSpamReportEnvelopeFrom());
    out.setSubject(config.getSpamTrainingSubjectPrefix() + " " + sr.accountName + ": " + isSpamString);
    Transport.send(out);
    ZimbraLog.misc.info("Sent " + sr);
}
Also used : SMTPMessage(com.sun.mail.smtp.SMTPMessage) Mailbox(com.zimbra.cs.mailbox.Mailbox) Message(com.zimbra.cs.mailbox.Message) SMTPMessage(com.sun.mail.smtp.SMTPMessage) MimeMessage(javax.mail.internet.MimeMessage) MailboxBlob(com.zimbra.cs.store.MailboxBlob) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MailboxBlobDataSource(com.zimbra.cs.mime.MailboxBlobDataSource) Config(com.zimbra.cs.account.Config) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) DataHandler(javax.activation.DataHandler) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 69 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class UUEncodeConverter method visitMessage.

@Override
protected boolean visitMessage(MimeMessage mm, VisitPhase visitKind) throws MessagingException {
    // do the decode in the exit phase
    if (visitKind != VisitPhase.VISIT_END)
        return false;
    MimeMultipart mmp = null;
    try {
        // only check "text/plain" parts for uudecodeable attachments
        if (!mm.isMimeType(MimeConstants.CT_TEXT_PLAIN))
            return false;
        // don't check transfer-encoded parts for uudecodeable attachments
        String cte = mm.getHeader("Content-Transfer-Encoding", null);
        if (cte != null) {
            cte = cte.trim().toLowerCase();
            if (!cte.equals(MimeConstants.ET_7BIT) && !cte.equals(MimeConstants.ET_8BIT) && !cte.equals(MimeConstants.ET_BINARY))
                return false;
        }
        List<UUDecodedFile> uufiles = null;
        // go through top-level text/plain part and extract uuencoded files
        PositionInputStream is = null;
        long size;
        try {
            is = new PositionInputStream(new BufferedInputStream(mm.getInputStream()));
            for (int c = is.read(); c != -1; ) {
                long start = is.getPosition() - 1;
                // check for uuencode header: "begin NNN filename"
                if (c == 'b' && (c = is.read()) == 'e' && (c = is.read()) == 'g' && (c = is.read()) == 'i' && (c = is.read()) == 'n' && ((c = is.read()) == ' ' || c == '\t') && Character.isDigit((c = is.read())) && Character.isDigit(c = is.read()) && Character.isDigit(c = is.read()) && ((c = is.read()) == ' ' || c == '\t')) {
                    StringBuilder sb = new StringBuilder();
                    while ((c = is.read()) != '\r' && c != '\n' && c != -1) sb.append((char) c);
                    String filename = FileUtil.trimFilename(sb.toString().trim());
                    if (c != -1 && filename.length() > 0) {
                        if (uufiles == null)
                            uufiles = new ArrayList<UUDecodedFile>(3);
                        try {
                            uufiles.add(new UUDecodedFile(is, filename, start));
                            // check to make sure that the caller's OK with altering the message
                            if (uufiles.size() == 1 && mCallback != null && !mCallback.onModification())
                                return false;
                        } catch (IOException ioe) {
                        }
                    }
                }
                // skip to the beginning of the next line
                while (c != '\r' && c != '\n' && c != -1) c = is.read();
                while (c == '\r' || c == '\n') c = is.read();
            }
            size = is.getPosition();
        } finally {
            ByteUtil.closeStream(is);
        }
        if (uufiles == null || uufiles.isEmpty())
            return false;
        // create MimeParts for the extracted files
        mmp = new ZMimeMultipart("mixed");
        for (UUDecodedFile uu : uufiles) {
            MimeBodyPart mbp = new ZMimeBodyPart();
            mbp.setHeader("Content-Type", uu.getContentType());
            mbp.setHeader("Content-Disposition", new ContentDisposition(Part.ATTACHMENT).setParameter("filename", uu.getFilename()).toString());
            mbp.setDataHandler(new DataHandler(uu.getDataSource()));
            mmp.addBodyPart(mbp);
            size -= uu.getEndOffset() - uu.getStartOffset();
        }
        // take the remaining text and put it in as the first "related" part
        InputStream isOrig = null;
        try {
            isOrig = mm.getInputStream();
            long offset = 0;
            ByteArrayOutputStream baos = new ByteArrayOutputStream((int) size);
            byte[] buffer = new byte[8192];
            for (UUDecodedFile uu : uufiles) {
                long count = uu.getStartOffset() - offset, numRead;
                while (count > 0 && (numRead = isOrig.read(buffer, 0, (int) Math.min(count, 8192))) >= 0) {
                    baos.write(buffer, 0, (int) numRead);
                    count -= numRead;
                }
                isOrig.skip(uu.getEndOffset() - uu.getStartOffset());
                offset = uu.getEndOffset();
            }
            ByteUtil.copy(isOrig, true, baos, true);
            MimeBodyPart mbp = new ZMimeBodyPart();
            mbp.setDataHandler(new DataHandler(new ByteArrayDataSource(baos.toByteArray(), MimeConstants.CT_TEXT_PLAIN)));
            mmp.addBodyPart(mbp, 0);
        } finally {
            ByteUtil.closeStream(isOrig);
        }
    } catch (MessagingException e) {
        ZimbraLog.extensions.warn("exception while uudecoding message part; skipping part", e);
        return false;
    } catch (IOException e) {
        ZimbraLog.extensions.warn("exception while uudecoding message part; skipping part", e);
        return false;
    }
    // replace the top-level part with a new multipart/related
    mm.setContent(mmp);
    mm.setHeader("Content-Type", mmp.getContentType() + "; generated=true");
    return true;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) BufferedInputStream(java.io.BufferedInputStream) PositionInputStream(com.zimbra.common.util.ByteUtil.PositionInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) DataHandler(javax.activation.DataHandler) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ContentDisposition(com.zimbra.common.mime.ContentDisposition) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) BufferedInputStream(java.io.BufferedInputStream) PositionInputStream(com.zimbra.common.util.ByteUtil.PositionInputStream) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Example 70 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class TnefConverter method visitMessage.

@Override
protected boolean visitMessage(MimeMessage msg, VisitPhase visitKind) throws MessagingException {
    // do the decode in the exit phase
    if (visitKind == VisitPhase.VISIT_BEGIN) {
        mMimeMessage = msg;
        return false;
    }
    try {
        // we only care about "application/ms-tnef" content
        if (!TNEFUtils.isTNEFMimeType(msg.getContentType()))
            return false;
        // check to make sure that the caller's OK with altering the message
        if (mCallback != null && !mCallback.onModification())
            return false;
    } catch (MessagingException e) {
        ZimbraLog.extensions.warn("exception while checking message for TNEF content; skipping part");
        return false;
    }
    MimeMultipart multi = null;
    MimeBodyPart tnefPart = null;
    try {
        Object content = msg.getContent();
        if (!(content instanceof MimeBodyPart))
            return false;
        tnefPart = (MimeBodyPart) content;
        // try to expand the TNEF into a suitable multipart
        multi = expandTNEF(tnefPart);
        if (multi == null)
            return false;
        // add the TNEF to the expanded multipart
        multi.addBodyPart(tnefPart, 0);
    } catch (MessagingException e) {
        ZimbraLog.extensions.warn("exception while decoding TNEF message content; skipping part", e);
        return false;
    } catch (IOException e) {
        ZimbraLog.extensions.warn("exception while decoding TNEF message content; skipping part", e);
        return false;
    }
    // and put the new multipart/alternative where the TNEF used to be
    msg.setContent(multi);
    msg.setHeader("Content-Type", multi.getContentType() + "; generated=true");
    return true;
}
Also used : MessagingException(javax.mail.MessagingException) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) IOException(java.io.IOException) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Aggregations

MimeMultipart (javax.mail.internet.MimeMultipart)213 MimeBodyPart (javax.mail.internet.MimeBodyPart)134 MimeMessage (javax.mail.internet.MimeMessage)85 MessagingException (javax.mail.MessagingException)69 ByteArrayOutputStream (java.io.ByteArrayOutputStream)55 BodyPart (javax.mail.BodyPart)55 IOException (java.io.IOException)47 ByteString (com.linkedin.data.ByteString)37 DataHandler (javax.activation.DataHandler)33 InternetAddress (javax.mail.internet.InternetAddress)33 Test (org.testng.annotations.Test)31 ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)27 HashMap (java.util.HashMap)27 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)26 Multipart (javax.mail.Multipart)26 Properties (java.util.Properties)25 Session (javax.mail.Session)24 ByteArrayDataSource (javax.mail.util.ByteArrayDataSource)24 InputStream (java.io.InputStream)23 Date (java.util.Date)21