Search in sources :

Example 26 with JavaMailInternetAddress

use of com.zimbra.common.mime.shim.JavaMailInternetAddress in project zm-mailbox by Zimbra.

the class Notification method notifyIfNecessary.

/**
 * If the recipient's account is set up for email notification, sends a notification
 * message to the user's notification address.
 */
private void notifyIfNecessary(Account account, Message msg, String rcpt) throws MessagingException, ServiceException {
    // Does user have new mail notification turned on
    boolean notify = account.getBooleanAttr(Provisioning.A_zimbraPrefNewMailNotificationEnabled, false);
    if (!notify) {
        return;
    }
    // Validate notification address
    String destination = account.getAttr(Provisioning.A_zimbraPrefNewMailNotificationAddress);
    if (destination == null) {
        nfailed("destination not set", null, rcpt, msg, null);
        return;
    }
    try {
        new JavaMailInternetAddress(destination);
    } catch (AddressException ae) {
        nfailed("invalid destination", destination, rcpt, msg, ae);
        return;
    }
    // filter rules, we assume it's not interesting.
    if (msg.inSpam()) {
        nfailed("in spam", destination, rcpt, msg);
        return;
    }
    try {
        if (msg.inTrash()) {
            nfailed("in trash", destination, rcpt, msg);
            return;
        }
    } catch (ServiceException e) {
        nfailed("call to Message.inTrash() failed", destination, rcpt, msg, e);
        return;
    }
    // If precedence is bulk or junk
    MimeMessage mm = msg.getMimeMessage();
    String[] precedence = mm.getHeader("Precedence");
    if (hasPrecedence(precedence, "bulk")) {
        nfailed("precedence bulk", destination, rcpt, msg);
        return;
    }
    if (hasPrecedence(precedence, "junk")) {
        nfailed("precedence junk", destination, rcpt, msg);
        return;
    }
    // Check for mail loop
    String[] autoSubmittedHeaders = mm.getHeader("Auto-Submitted");
    if (autoSubmittedHeaders != null) {
        for (int i = 0; i < autoSubmittedHeaders.length; i++) {
            String headerValue = autoSubmittedHeaders[i].toLowerCase();
            if (headerValue.indexOf("notification") != -1) {
                nfailed("detected a mail loop", destination, rcpt, msg);
                return;
            }
        }
    }
    // Send the message
    try {
        Domain domain = Provisioning.getInstance().getDomain(account);
        Session smtpSession = JMSession.getSmtpSession(domain);
        // Assemble message components
        MimeMessage out = assembleNotificationMessage(account, msg, rcpt, destination, smtpSession);
        if (out == null) {
            return;
        }
        String envFrom = "<>";
        try {
            if (!Provisioning.getInstance().getConfig().getBooleanAttr(Provisioning.A_zimbraAutoSubmittedNullReturnPath, true)) {
                envFrom = account.getName();
            }
        } catch (ServiceException se) {
            ZimbraLog.mailbox.warn("error encoutered looking up return path configuration, using null return path instead", se);
        }
        smtpSession.getProperties().setProperty("mail.smtp.from", envFrom);
        Transport.send(out);
        MailSender.logMessage(out, out.getAllRecipients(), envFrom, smtpSession.getProperties().getProperty("mail.smtp.host"), String.valueOf(msg.getId()), null, null, "notify");
    } catch (MessagingException me) {
        nfailed("send failed", destination, rcpt, msg, me);
    }
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) MessagingException(javax.mail.MessagingException) AddressException(javax.mail.internet.AddressException) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Domain(com.zimbra.cs.account.Domain) JMSession(com.zimbra.cs.util.JMSession) Session(javax.mail.Session)

Example 27 with JavaMailInternetAddress

use of com.zimbra.common.mime.shim.JavaMailInternetAddress in project zm-mailbox by Zimbra.

the class Notification method interceptIfNecessary.

/**
 * If <tt>zimbraInterceptAddress</tt> is specified, sends a message to that
 * address with the given message attached.
 *
 * @param operation name of the operation being performed (send, add message, save draft, etc.)
 * @param folder the folder that the message was filed into, or <tt>null</tt>
 */
void interceptIfNecessary(Mailbox mbox, MimeMessage msg, String operation, Folder folder) throws ServiceException {
    // Don't do anything if intercept is turned off.
    Account account = mbox.getAccount();
    String[] interceptAddresses = account.getMultiAttr(Provisioning.A_zimbraInterceptAddress);
    if (interceptAddresses.length == 0) {
        return;
    }
    for (String interceptAddress : interceptAddresses) {
        try {
            ZimbraLog.mailbox.info("Sending intercept of message %s to %s.", msg.getMessageID(), interceptAddress);
            // Fill templates
            String folderName = "none";
            String folderId = "none";
            if (folder != null) {
                folderName = folder.getName();
                folderId = Integer.toString(folder.getId());
            }
            Map<String, String> vars = new HashMap<String, String>();
            vars.put("ACCOUNT_DOMAIN", getDomain(account.getName()));
            vars.put("ACCOUNT_ADDRESS", account.getName());
            vars.put("MESSAGE_SUBJECT", Mime.getSubject(msg));
            vars.put("OPERATION", operation);
            vars.put("FOLDER_NAME", folderName);
            vars.put("FOLDER_ID", folderId);
            vars.put("NEWLINE", "\r\n");
            String from = StringUtil.fillTemplate(account.getAttr(Provisioning.A_zimbraInterceptFrom), vars);
            String subject = StringUtil.fillTemplate(account.getAttr(Provisioning.A_zimbraInterceptSubject), vars);
            String bodyText = StringUtil.fillTemplate(account.getAttr(Provisioning.A_zimbraInterceptBody), vars);
            // Assemble outgoing message
            MimeMessage attached = msg;
            boolean headersOnly = account.getBooleanAttr(Provisioning.A_zimbraInterceptSendHeadersOnly, false);
            if (headersOnly) {
                attached = new MimeMessageWithId(msg.getMessageID());
                Enumeration e = msg.getAllHeaderLines();
                while (e.hasMoreElements()) {
                    attached.addHeaderLine((String) e.nextElement());
                }
                attached.setContent("", msg.getContentType());
                attached.saveChanges();
            }
            SMTPMessage out = AccountUtil.getSmtpMessageObj(account);
            out.setHeader("Auto-Submitted", "auto-replied (zimbra; intercept)");
            InternetAddress address = new JavaMailInternetAddress(from);
            out.setFrom(address);
            address = new JavaMailInternetAddress(interceptAddress);
            out.setRecipient(javax.mail.Message.RecipientType.TO, address);
            String charset = getCharset(account, subject);
            out.setSubject(subject, charset);
            charset = getCharset(account, bodyText);
            MimeMultipart multi = new ZMimeMultipart();
            // Add message body
            MimeBodyPart part = new ZMimeBodyPart();
            part.setText(bodyText, charset);
            multi.addBodyPart(part);
            // Add original message
            MimeBodyPart part2 = new ZMimeBodyPart();
            part2.setContent(attached, MimeConstants.CT_MESSAGE_RFC822);
            multi.addBodyPart(part2);
            out.setContent(multi);
            String envFrom = "<>";
            out.setEnvelopeFrom(envFrom);
            out.saveChanges();
            Transport.send(out);
            // clean up after ourselves...
            multi.removeBodyPart(part2);
        } catch (MessagingException e) {
            ZimbraLog.lmtp.warn("Unable to send intercept message to %s.", interceptAddress, e);
        }
    }
}
Also used : Account(com.zimbra.cs.account.Account) SMTPMessage(com.sun.mail.smtp.SMTPMessage) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Enumeration(java.util.Enumeration) HashMap(java.util.HashMap) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 28 with JavaMailInternetAddress

use of com.zimbra.common.mime.shim.JavaMailInternetAddress in project zm-mailbox by Zimbra.

the class SendInviteReply method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    Account acct = getRequestedAccount(zsc);
    Account authAcct = getAuthenticatedAccount(zsc);
    boolean isAdmin = zsc.isUsingAdminPrivileges();
    OperationContext octxt = getOperationContext(zsc, context);
    boolean onBehalfOf = isOnBehalfOfRequest(zsc);
    ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
    int compNum = (int) request.getAttributeLong(MailConstants.A_CAL_COMPONENT_NUM);
    String verbStr = request.getAttribute(MailConstants.A_VERB);
    Verb verb = CalendarMailSender.parseVerb(verbStr);
    boolean isDecline = CalendarMailSender.VERB_DECLINE.equals(verb);
    boolean updateOrg = request.getAttributeBool(MailConstants.A_CAL_UPDATE_ORGANIZER, true);
    // Get the identity/persona being used in the reply.  It is set at the request level, but
    // let's also look for it in the <m> child element too, because that is the precedent in
    // the SendMsg request.  For SendInviteReply we have to insist it at request level because
    // <m> is an optional element.
    String identityId = request.getAttribute(MailConstants.A_IDENTITY_ID, null);
    if (identityId == null) {
        Element msgElem = request.getOptionalElement(MailConstants.E_MSG);
        if (msgElem != null)
            identityId = msgElem.getAttribute(MailConstants.A_IDENTITY_ID, null);
    }
    Element response = getResponseElement(zsc);
    boolean intendedForMe = true;
    Invite oldInv = null;
    int calItemId;
    int inviteMsgId;
    CalendarItem calItem = null;
    boolean wasInTrash = false;
    String stat = null;
    // calendar item (id="aaaa-nnnn") --- work in both cases
    if (iid.hasSubpart()) {
        // directly accepting the calendar item
        calItemId = iid.getId();
        inviteMsgId = iid.getSubpartId();
        calItem = safeGetCalendarItemById(mbox, octxt, iid.getId());
        if (calItem == null)
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Could not find calendar item");
        oldInv = calItem.getInvite(inviteMsgId, compNum);
    } else {
        // accepting the message: go find the calendar item and then the invite
        inviteMsgId = iid.getId();
        Message msg = mbox.getMessageById(octxt, inviteMsgId);
        Message.CalendarItemInfo info = msg.getCalendarItemInfo(compNum);
        if (info == null)
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Could not find calendar item");
        String intendedFor = msg.getCalendarIntendedFor();
        Account intendedAcct = null;
        if (intendedFor != null) {
            try {
                InternetAddress intendedForAddr = new JavaMailInternetAddress(intendedFor);
                intendedAcct = Provisioning.getInstance().get(AccountBy.name, intendedForAddr.getAddress());
            } catch (AddressException e) {
                throw ServiceException.INVALID_REQUEST("The intended account " + intendedFor + " is invalid", e);
            }
            if (intendedAcct == null) {
                throw ServiceException.INVALID_REQUEST("The intended account " + intendedFor + " was not found", null);
            }
            // Special case: intended account = me.
            if (intendedAcct.equals(mbox.getAccount()))
                intendedAcct = null;
            else
                intendedForMe = false;
        }
        if (intendedAcct != null) {
            // trace logging: let's just indicate we're replying to a remote appointment
            ZimbraLog.calendar.info("<SendInviteReply> (remote mbox) id=%s, verb=%s, notifyOrg=%s", new ItemIdFormatter(zsc).formatItemId(iid), verb.toString(), Boolean.toString(updateOrg));
            // Replying to a remote appointment
            calItem = null;
            calItemId = 0;
            ZMailbox zmbx = getRemoteZMailbox(octxt, authAcct, intendedAcct);
            // Try to add the appointment to remote mailbox.
            AddInviteResult addInviteResult = sendAddInvite(zmbx, octxt, msg);
            if (addInviteResult == null)
                throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
            // Forward the reply request.
            remoteSendInviteReply(zmbx, request, addInviteResult);
        } else {
            // Replying to a local appointment
            if (info.getInvite() != null) {
                calItem = mbox.getCalendarItemByUid(octxt, info.getInvite().getUid());
                wasInTrash = calItem != null && calItem.inTrash();
                if (calItem != null && !wasInTrash) {
                    Invite newInv = info.getInvite();
                    // If appointment exists, check if our invite has been outdated.
                    Invite curr = calItem.getInvite(newInv.getRecurId());
                    if (curr != null && !newInv.isSameOrNewerVersion(curr))
                        throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
                }
                Invite inv = info.getInvite().newCopy();
                Invite.setDefaultAlarm(inv, acct);
                inv.setMailItemId(inviteMsgId);
                // (TODO: Is it better to delete the existing appointment/instance when declining?)
                if (calItem != null || !isDecline) {
                    // Add the invite.  This will either create or update the appointment.
                    int folder;
                    boolean untrashing = wasInTrash && !isDecline;
                    if (calItem == null || untrashing) {
                        // If appointment/task doesn't exist, create in default folder.
                        // If it exists but is in Trash and is not a decline, move it out of Trash.
                        // If it's in trash and we're declining, leave it in trash.
                        folder = inv.isTodo() ? Mailbox.ID_FOLDER_TASKS : Mailbox.ID_FOLDER_CALENDAR;
                    } else {
                        folder = calItem.getFolderId();
                    }
                    ParsedMessage pm = new ParsedMessage(msg.getMimeMessage(false), false);
                    AddInviteData aid = mbox.addInvite(octxt, inv, folder, pm, false, untrashing, true);
                    if (aid == null)
                        throw ServiceException.FAILURE("Could not create/update calendar item", null);
                    calItemId = aid.calItemId;
                    // Refetch updated item.
                    calItem = safeGetCalendarItemById(mbox, octxt, aid.calItemId);
                    if (calItem == null)
                        throw ServiceException.FAILURE("Could not refetch created/updated calendar item", null);
                } else {
                    calItemId = 0;
                }
                oldInv = inv;
            } else if (info.calItemCreated()) {
                // legacy case (before we added Invite info to Message metadata)
                calItem = safeGetCalendarItemById(mbox, octxt, info.getCalendarItemId());
                if (calItem == null)
                    throw ServiceException.FAILURE("Missing invite data", null);
                // Must be for this mailbox
                calItemId = info.getCalendarItemId().getId();
                wasInTrash = calItem.inTrash();
                oldInv = calItem.getInvite(inviteMsgId, compNum);
            } else {
                throw ServiceException.FAILURE("Missing invite data", null);
            }
        }
    }
    if (intendedForMe) {
        if (oldInv == null)
            throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
        if (calItem != null && (mbox.getEffectivePermissions(octxt, calItemId, MailItem.Type.UNKNOWN) & ACL.RIGHT_ACTION) == 0) {
            throw ServiceException.PERM_DENIED("You do not have ACTION rights for CalendarItem " + calItemId);
        }
        // check if invite organizer requested rsvp or not
        if (oldInv.hasRsvp()) {
            updateOrg = updateOrg && oldInv.getRsvp();
        }
        // Don't allow creating/editing a private appointment on behalf of another user,
        // unless that other user is a calendar resource.
        boolean allowPrivateAccess = calItem != null ? calItem.allowPrivateAccess(authAcct, isAdmin) : true;
        boolean isCalendarResource = acct instanceof CalendarResource;
        if (!allowPrivateAccess && !oldInv.isPublic() && !isCalendarResource)
            throw ServiceException.PERM_DENIED("Cannot reply to a private appointment/task on behalf of another user");
        // see if there is a specific Exception being referenced by this reply...
        Element exc = request.getOptionalElement(MailConstants.E_CAL_EXCEPTION_ID);
        ParsedDateTime exceptDt = null;
        if (exc != null) {
            TimeZoneMap tzmap = oldInv.getTimeZoneMap();
            Element tzElem = request.getOptionalElement(MailConstants.E_CAL_TZ);
            ICalTimeZone tz = null;
            if (tzElem != null) {
                tz = CalendarUtils.parseTzElement(tzElem);
                tzmap.add(tz);
            }
            exceptDt = CalendarUtils.parseDateTime(exc, tzmap);
        } else if (oldInv.hasRecurId()) {
            exceptDt = oldInv.getRecurId().getDt();
        }
        // trace logging
        String calItemIdStr = calItem != null ? Integer.toString(calItem.getId()) : "none";
        String folderIdStr = calItem != null ? Integer.toString(calItem.getFolderId()) : "none";
        if (exceptDt == null)
            ZimbraLog.calendar.info("<SendInviteReply> id=%s, folderId=%s, verb=%s, notifyOrg=%s, subject=\"%s\", UID=%s", calItemIdStr, folderIdStr, verb.toString(), Boolean.toString(updateOrg), oldInv.isPublic() ? oldInv.getName() : "(private)", oldInv.getUid());
        else
            ZimbraLog.calendar.info("<SendInviteReply> id=%s, folderId=%s, verb=%s, notifyOrg=%s, subject=\"%s\", UID=%s, recurId=%s", calItemIdStr, folderIdStr, verb.toString(), Boolean.toString(updateOrg), oldInv.isPublic() ? oldInv.getName() : "(private)", oldInv.getUid(), exceptDt.getUtcString());
        // exception instance first.  Then reply to it.
        if (calItem != null && oldInv.isRecurrence() && exceptDt != null) {
            Invite localException = oldInv.makeInstanceInvite(exceptDt);
            long now = octxt != null ? octxt.getTimestamp() : System.currentTimeMillis();
            localException.setDtStamp(now);
            String partStat = verb.getXmlPartStat();
            localException.setPartStat(partStat);
            ZAttendee at = localException.getMatchingAttendee(acct, identityId);
            if (at != null)
                at.setPartStat(partStat);
            // Carry over the MimeMessage/ParsedMessage to preserve any attachments.
            MimeMessage mmInv = calItem.getSubpartMessage(oldInv.getMailItemId());
            ParsedMessage pm = mmInv != null ? new ParsedMessage(mmInv, false) : null;
            int folder;
            boolean untrashing = wasInTrash && !isDecline;
            if (untrashing) {
                // If it exists but is in Trash and is not a decline, move it out of Trash.
                // If it's in trash and we're declining, leave it in trash.
                folder = localException.isTodo() ? Mailbox.ID_FOLDER_TASKS : Mailbox.ID_FOLDER_CALENDAR;
            } else {
                folder = calItem.getFolderId();
            }
            mbox.addInvite(octxt, localException, folder, pm, true, untrashing, true);
            // Refetch the updated calendar item and set oldInv to refetched local exception instance.
            calItem = safeGetCalendarItemById(mbox, octxt, calItemId);
            if (calItem == null)
                throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Could not find calendar item");
            oldInv = calItem.getInvite(new RecurId(exceptDt, RecurId.RANGE_NONE));
        }
        ZAttendee att = oldInv.getMatchingAttendee(mbox.getAccount());
        if (att != null) {
            stat = att.getPartStat();
        }
        if (updateOrg && oldInv.hasOrganizer()) {
            Locale locale;
            Account organizer = oldInv.getOrganizerAccount();
            if (organizer != null)
                locale = organizer.getLocale();
            else
                locale = !onBehalfOf ? acct.getLocale() : authAcct.getLocale();
            String subject;
            if (!allowPrivateAccess && !oldInv.isPublic())
                subject = L10nUtil.getMessage(MsgKey.calendarSubjectWithheld, locale);
            else
                subject = oldInv.getName();
            String replySubject = CalendarMailSender.getReplySubject(verb, subject, locale);
            CalSendData csd = new CalSendData();
            csd.mOrigId = new ItemId(mbox, oldInv.getMailItemId());
            csd.mReplyType = MailSender.MSGTYPE_REPLY;
            csd.mInvite = CalendarMailSender.replyToInvite(acct, identityId, authAcct, onBehalfOf, allowPrivateAccess, oldInv, verb, replySubject, exceptDt);
            ZVCalendar iCal = csd.mInvite.newToICalendar(true);
            ParseMimeMessage.MimeMessageData parsedMessageData = new ParseMimeMessage.MimeMessageData();
            // did they specify a custom <m> message?  If so, then we don't have to build one...
            Element msgElem = request.getOptionalElement(MailConstants.E_MSG);
            if (msgElem != null) {
                String text = ParseMimeMessage.getTextPlainContent(msgElem);
                String html = ParseMimeMessage.getTextHtmlContent(msgElem);
                iCal.addDescription(text, html);
                MimeBodyPart[] mbps = new MimeBodyPart[1];
                mbps[0] = CalendarMailSender.makeICalIntoMimePart(iCal);
                // the <inv> element is *NOT* allowed -- we always build it manually
                // based on the params to the <SendInviteReply> and stick it in the
                // mbps (additionalParts) parameter...
                csd.mMm = ParseMimeMessage.parseMimeMsgSoap(zsc, octxt, mbox, msgElem, mbps, ParseMimeMessage.NO_INV_ALLOWED_PARSER, parsedMessageData);
            } else {
                // build a default "Accepted" response
                if (!(acct instanceof CalendarResource)) {
                    csd.mMm = CalendarMailSender.createDefaultReply(acct, identityId, authAcct, identityId, isAdmin, onBehalfOf, calItem, oldInv, null, replySubject, verb, null, iCal);
                } else {
                    // different template for calendar resources
                    RecurId rid = oldInv.getRecurId();
                    ParsedDateTime ridDt = rid != null ? rid.getDt() : null;
                    Invite replyInv = CalendarMailSender.replyToInvite(acct, authAcct, onBehalfOf, allowPrivateAccess, oldInv, verb, replySubject, ridDt);
                    MimeMessage mmInv = calItem.getSubpartMessage(oldInv.getMailItemId());
                    csd.mMm = CalendarMailSender.createResourceAutoReply(octxt, identityId, identityId, mbox, verb, false, null, calItem, oldInv, new Invite[] { replyInv }, mmInv, true);
                }
            }
            int apptFolderId;
            if (calItem != null)
                apptFolderId = calItem.getFolderId();
            else
                apptFolderId = oldInv.isTodo() ? Mailbox.ID_FOLDER_TASKS : Mailbox.ID_FOLDER_CALENDAR;
            MailSendQueue sendQueue = new MailSendQueue();
            try {
                if (stat != null && IcalXmlStrMap.PARTSTAT_DECLINED.equals(stat) && !CalendarMailSender.VERB_DECLINE.equals(verb)) {
                    sendCalendarMessage(zsc, octxt, apptFolderId, acct, mbox, csd, response, sendQueue, true);
                } else {
                    sendCalendarMessage(zsc, octxt, apptFolderId, acct, mbox, csd, response, sendQueue);
                }
            } finally {
                sendQueue.send();
            }
        }
        RecurId recurId = null;
        if (exceptDt != null) {
            recurId = new RecurId(exceptDt, RecurId.RANGE_NONE);
        }
        ZAttendee me = oldInv.getMatchingAttendee(acct);
        String cnStr = null;
        String addressStr = acct.getName();
        String role = IcalXmlStrMap.ROLE_OPT_PARTICIPANT;
        int seqNo = oldInv.getSeqNo();
        long dtStamp = oldInv.getDTStamp();
        if (me != null) {
            if (me.hasCn()) {
                cnStr = me.getCn();
            }
            addressStr = me.getAddress();
            if (me.hasRole()) {
                role = me.getRole();
            }
        }
        if (calItem != null)
            mbox.modifyPartStat(octxt, calItemId, recurId, cnStr, addressStr, null, role, verb.getXmlPartStat(), Boolean.FALSE, seqNo, dtStamp);
    }
    // move the invite to the Trash if the user wants it
    if (deleteInviteOnReply(acct)) {
        try {
            if (onBehalfOf) {
                // HACK: Run the move in the context of the organizer
                // mailbox because the authenticated account doesn't
                // have rights on Inbox and Trash folders.
                octxt = new OperationContext(mbox);
            }
            mbox.move(octxt, inviteMsgId, MailItem.Type.MESSAGE, Mailbox.ID_FOLDER_TRASH);
        } catch (MailServiceException.NoSuchItemException nsie) {
            ZimbraLog.calendar.debug("can't move nonexistent invite to Trash: " + inviteMsgId);
        }
    }
    return response;
}
Also used : Locale(java.util.Locale) Account(com.zimbra.cs.account.Account) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Message(com.zimbra.cs.mailbox.Message) MimeMessage(javax.mail.internet.MimeMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) AddInviteData(com.zimbra.cs.mailbox.Mailbox.AddInviteData) Element(com.zimbra.common.soap.Element) RecurId(com.zimbra.cs.mailbox.calendar.RecurId) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) ZMailbox(com.zimbra.client.ZMailbox) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) MimeMessage(javax.mail.internet.MimeMessage) Verb(com.zimbra.cs.mailbox.calendar.CalendarMailSender.Verb) AddressException(javax.mail.internet.AddressException) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) CalendarResource(com.zimbra.cs.account.CalendarResource) OperationContext(com.zimbra.cs.mailbox.OperationContext) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) MimeBodyPart(javax.mail.internet.MimeBodyPart) Invite(com.zimbra.cs.mailbox.calendar.Invite) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone)

Example 29 with JavaMailInternetAddress

use of com.zimbra.common.mime.shim.JavaMailInternetAddress in project zm-mailbox by Zimbra.

the class SendVerificationCode method sendVerificationCode.

static void sendVerificationCode(String emailAddr, String code, Mailbox mbox) throws MessagingException, ServiceException {
    MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(mbox.getAccount()));
    mm.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(emailAddr));
    mm.setText(L10nUtil.getMessage(L10nUtil.MsgKey.deviceSendVerificationCodeText, mbox.getAccount().getLocale(), code), MimeConstants.P_CHARSET_UTF8);
    mm.saveChanges();
    MailSender mailSender = mbox.getMailSender();
    mailSender.setSaveToSent(false);
    mailSender.sendMimeMessage(null, mbox, mm);
}
Also used : MimeMessage(javax.mail.internet.MimeMessage) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) MailSender(com.zimbra.cs.mailbox.MailSender)

Example 30 with JavaMailInternetAddress

use of com.zimbra.common.mime.shim.JavaMailInternetAddress in project zm-mailbox by Zimbra.

the class CalendarItem method processNewInviteReply.

/**
 * @param updatePrevFolders - If set, update the record of previous folders
 * @param itemIdGetter - Used in newly created pseudo exceptions
 * @return false if the invite being updated is out of date
 * @throws ServiceException
 */
protected boolean processNewInviteReply(Invite reply, String sender, boolean updatePrevFolders, Mailbox.ItemIdGetter itemIdGetter) throws ServiceException {
    List<ZAttendee> attendees = reply.getAttendees();
    String senderAddress = null;
    if (sender != null && !sender.isEmpty()) {
        try {
            JavaMailInternetAddress address = new JavaMailInternetAddress(sender);
            senderAddress = address.getAddress();
        } catch (AddressException e) {
        // ignore invalid sender address.
        }
    }
    if (senderAddress != null && !attendees.isEmpty()) {
        AccountAddressMatcher acctMatcher = null;
        Account acct = Provisioning.getInstance().get(AccountBy.name, senderAddress);
        if (acct != null) {
            acctMatcher = new AccountAddressMatcher(acct);
        }
        Iterator<ZAttendee> iter = attendees.iterator();
        while (iter.hasNext()) {
            ZAttendee att = iter.next();
            // Remove the attendee if not same as the sender.
            if (!(att.addressMatches(senderAddress) || (acctMatcher != null && acctMatcher.matches(att.getAddress())))) {
                iter.remove();
            }
        }
    }
    // trace logging
    ZAttendee att1 = !attendees.isEmpty() ? attendees.get(0) : null;
    if (att1 != null) {
        String ptst = IcalXmlStrMap.sPartStatMap.toIcal(att1.getPartStat());
        if (!reply.hasRecurId())
            ZimbraLog.calendar.info("Processing CalendarItem reply: attendee=%s, partstat=%s, id=%d, folderId=%d, subject=\"%s\", UID=%s", att1.getAddress(), ptst, mId, getFolderId(), reply.isPublic() ? reply.getName() : "(private)", mUid);
        else
            ZimbraLog.calendar.info("Processing CalendarItem reply: attendee=%s, partstat=%s, id=%d, folderId=%d, subject=\"%s\", UID=%s, recurId=%s", att1.getAddress(), ptst, mId, getFolderId(), reply.isPublic() ? reply.getName() : "(private)", mUid, reply.getRecurId().getDtZ());
    }
    // Require private access permission only when we're replying to a private series/instance.
    boolean requirePrivateCheck = requirePrivateCheck(reply);
    OperationContext octxt = getMailbox().getOperationContext();
    Account authAccount = octxt != null ? octxt.getAuthenticatedUser() : null;
    boolean asAdmin = octxt != null ? octxt.isUsingAdminPrivileges() : false;
    if (!canAccess(ACL.RIGHT_ACTION, authAccount, asAdmin, requirePrivateCheck))
        throw ServiceException.PERM_DENIED("you do not have sufficient permissions to change this appointment/task's state");
    boolean dirty = false;
    // unique ID: UID+RECURRENCE_ID
    // See RFC2446: 2.1.5 Message Sequencing
    // UID already matches...next check if RecurId matches
    // if so, then seqNo is next
    // finally use DTStamp
    Invite matchingInvite = matchingInvite(reply.getRecurId());
    if (matchingInvite != null) {
        // up to date with the organizer's event, provided there were no major changes.
        if ((matchingInvite.isOrganizer() && (matchingInvite.getLastFullSeqNo() > reply.getSeqNo())) || (!matchingInvite.isOrganizer() && (matchingInvite.getSeqNo() > reply.getSeqNo()))) {
            sLog.info("Invite-Reply %s is outdated (Calendar entry has higher SEQUENCE), ignoring!", reply);
            return false;
        }
    // maybeStoreNewReply does some further checks which might invalidate this reply
    // so, postpone updating attendee information until after that.
    }
    // they must be replying to a arbitrary instance)
    for (ZAttendee at : attendees) {
        if (mReplyList.maybeStoreNewReply(reply, at, this))
            dirty = true;
    }
    if (!dirty) {
        sLog.info("Invite-Reply %s is outdated ignoring!", reply);
        return false;
    }
    if (matchingInvite != null) {
        matchingInvite.updateMatchingAttendeesFromReply(reply);
        updateLocalExceptionsWhichMatchSeriesReply(reply);
    } else {
        createPseudoExceptionForSingleInstanceReplyIfNecessary(reply, itemIdGetter);
    }
    if (updatePrevFolders) {
        performSetPrevFoldersOperation(octxt);
    }
    saveMetadata();
    return true;
}
Also used : Account(com.zimbra.cs.account.Account) AccountAddressMatcher(com.zimbra.cs.util.AccountUtil.AccountAddressMatcher) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) AddressException(javax.mail.internet.AddressException) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Aggregations

JavaMailInternetAddress (com.zimbra.common.mime.shim.JavaMailInternetAddress)46 InternetAddress (javax.mail.internet.InternetAddress)31 MimeMessage (javax.mail.internet.MimeMessage)25 AddressException (javax.mail.internet.AddressException)17 Date (java.util.Date)15 MessagingException (javax.mail.MessagingException)14 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)13 Account (com.zimbra.cs.account.Account)12 MailSender (com.zimbra.cs.mailbox.MailSender)9 UnsupportedEncodingException (java.io.UnsupportedEncodingException)9 ArrayList (java.util.ArrayList)9 Address (javax.mail.Address)9 ServiceException (com.zimbra.common.service.ServiceException)8 Locale (java.util.Locale)8 SMTPMessage (com.sun.mail.smtp.SMTPMessage)7 MimeBodyPart (javax.mail.internet.MimeBodyPart)7 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)6 ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)6 IOException (java.io.IOException)6 MimeMultipart (javax.mail.internet.MimeMultipart)6