Search in sources :

Example 6 with ZAttendee

use of com.zimbra.cs.mailbox.calendar.ZAttendee in project zm-mailbox by Zimbra.

the class CalendarUtils method cancelInvite.

private static Invite cancelInvite(Account acct, Account senderAcct, boolean allowPrivateAccess, boolean onBehalfOf, Invite inv, String comment, List<ZAttendee> forAttendees, RecurId recurId, boolean incrementSeq) throws ServiceException {
    Invite cancel = new Invite(inv.getItemType(), ICalTok.CANCEL.toString(), inv.getTimeZoneMap(), inv.isOrganizer());
    // ORGANIZER
    if (inv.hasOrganizer()) {
        ZOrganizer org = new ZOrganizer(inv.getOrganizer());
        if (onBehalfOf && senderAcct != null)
            org.setSentBy(senderAcct.getName());
        cancel.setOrganizer(org);
    }
    // ATTENDEEs
    List<ZAttendee> attendees = forAttendees != null ? forAttendees : inv.getAttendees();
    for (ZAttendee a : attendees) cancel.addAttendee(a);
    cancel.setClassProp(inv.getClassProp());
    boolean showAll = inv.isPublic() || allowPrivateAccess;
    Locale locale = acct.getLocale();
    if (!showAll) {
        // SUMMARY
        String sbj = L10nUtil.getMessage(MsgKey.calendarSubjectWithheld, locale);
        cancel.setName(CalendarMailSender.getCancelSubject(sbj, locale));
    } else {
        // SUMMARY
        cancel.setName(CalendarMailSender.getCancelSubject(inv.getName(), locale));
        // COMMENT
        if (comment != null && !comment.equals(""))
            cancel.addComment(comment);
    }
    // UID
    cancel.setUid(inv.getUid());
    // RECURRENCE-ID
    if (inv.hasRecurId()) {
        // FIXME: if RECURRENCE-ID can be a range (THISANDFUTURE) then we'll
        // need to be smarter here
        cancel.setRecurId(inv.getRecurId());
    } else {
        if (recurId != null) {
            cancel.setRecurId(recurId);
        }
    }
    // all-day
    // bug 30121
    cancel.setIsAllDayEvent(inv.isAllDayEvent());
    // DTSTART, DTEND, and LOCATION (Outlook seems to require these, even
    // though they are optional according to RFC2446.)
    ParsedDateTime dtStart = recurId == null ? inv.getStartTime() : recurId.getDt();
    if (dtStart != null) {
        cancel.setDtStart(dtStart);
        ParsedDuration dur = inv.getEffectiveDuration();
        if (dur != null)
            cancel.setDtEnd(dtStart.add(dur));
    }
    // LOCATION
    cancel.setLocation(inv.getLocation());
    // SEQUENCE
    int seq = inv.getSeqNo();
    if (incrementSeq) {
        // present value.  (bug 8465)
        if (acct != null && inv.isOrganizer())
            seq++;
    }
    cancel.setSeqNo(seq);
    // STATUS
    cancel.setStatus(IcalXmlStrMap.STATUS_CANCELLED);
    // DTSTAMP
    cancel.setDtStamp(new Date().getTime());
    return cancel;
}
Also used : Locale(java.util.Locale) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite) Date(java.util.Date)

Example 7 with ZAttendee

use of com.zimbra.cs.mailbox.calendar.ZAttendee in project zm-mailbox by Zimbra.

the class CalendarUtils method getRemovedAttendees.

// Compare the old and new attendee lists to figure out which attendees are being removed.
// Distribution lists are taken into consideration if requested.
public static List<ZAttendee> getRemovedAttendees(List<ZAttendee> oldAttendees, List<ZAttendee> newAttendees, boolean checkListMembership, Account account) throws ServiceException {
    List<ZAttendee> list = new ArrayList<ZAttendee>();
    Provisioning prov = Provisioning.getInstance();
    // if attendees have been removed, then we need to send them individual cancellation messages
    for (ZAttendee old : oldAttendees) {
        boolean matches = false;
        String oldAddr = old.getAddress();
        if (oldAddr != null) {
            Account oldAcct = prov.get(AccountBy.name, oldAddr);
            if (oldAcct != null) {
                // local user - consider aliases
                AccountAddressMatcher acctMatcher = new AccountAddressMatcher(oldAcct);
                for (ZAttendee newAt : newAttendees) {
                    if (acctMatcher.matches(newAt.getAddress())) {
                        matches = true;
                        break;
                    }
                }
            } else {
                // external email - simple string comparison of email addresses
                for (ZAttendee newAt : newAttendees) {
                    if (oldAddr.equalsIgnoreCase(newAt.getAddress())) {
                        matches = true;
                        break;
                    }
                }
            }
        }
        if (!matches)
            list.add(old);
    }
    if (list.isEmpty())
        return list;
    //bug 68728, skip checking in ZD
    checkListMembership = checkListMembership && LC.check_dl_membership_enabled.booleanValue();
    // Find out which of the new attendees are local distribution lists or GAL groups.
    if (checkListMembership) {
        List<DistributionList> newAtsDL = new ArrayList<DistributionList>();
        List<String> /* GAL group email */
        newAtsGALGroup = new ArrayList<String>();
        for (ZAttendee at : newAttendees) {
            String addr = at.getAddress();
            if (addr != null) {
                DistributionList dl = prov.get(Key.DistributionListBy.name, addr);
                if (dl != null)
                    newAtsDL.add(dl);
                else if (GalGroup.isGroup(addr, account))
                    newAtsGALGroup.add(addr);
            }
        }
        // GAL groups: Iterate over GAL groups first because fetching member list is expensive.
        for (String galAddr : newAtsGALGroup) {
            if (list.isEmpty())
                break;
            Set<String> galMembers = GalGroupMembers.getGroupMembers(galAddr, account);
            for (Iterator<ZAttendee> removedIter = list.iterator(); removedIter.hasNext(); ) {
                ZAttendee removedAt = removedIter.next();
                String addr = removedAt.getAddress();
                if (addr != null && galMembers.contains(addr))
                    removedIter.remove();
            }
        }
        Set<String> remoteAddrs = new HashSet<String>();
        // via alias address.
        for (Iterator<ZAttendee> removedIter = list.iterator(); removedIter.hasNext(); ) {
            ZAttendee removedAt = removedIter.next();
            String addr = removedAt.getAddress();
            if (addr != null) {
                Account removedAcct = prov.get(AccountBy.name, addr);
                if (removedAcct != null) {
                    Set<String> acctDLs = prov.getDistributionLists(removedAcct);
                    for (DistributionList dl : newAtsDL) {
                        if (acctDLs.contains(dl.getId())) {
                            removedIter.remove();
                            break;
                        }
                    }
                } else {
                    // Removed address is not a local account.
                    remoteAddrs.add(addr);
                }
            }
        }
        // Check non-local attendee membership in local DLs.  Only direct membership is checked.
        if (!remoteAddrs.isEmpty()) {
            for (DistributionList dl : newAtsDL) {
                // Get list members.  We won't do recursive expansion; let's keep it sane.
                String[] members = dl.getAllMembers();
                if (members != null && members.length > 0) {
                    Set<String> membersLower = new HashSet<String>();
                    for (String member : members) {
                        membersLower.add(member.toLowerCase());
                    }
                    for (Iterator<ZAttendee> removedIter = list.iterator(); removedIter.hasNext(); ) {
                        ZAttendee removedAt = removedIter.next();
                        String addr = removedAt.getAddress();
                        if (addr != null && remoteAddrs.contains(addr) && membersLower.contains(addr.toLowerCase())) {
                            removedIter.remove();
                        }
                    }
                }
            }
        }
    }
    return list;
}
Also used : Account(com.zimbra.cs.account.Account) ArrayList(java.util.ArrayList) Provisioning(com.zimbra.cs.account.Provisioning) AccountAddressMatcher(com.zimbra.cs.util.AccountUtil.AccountAddressMatcher) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) DistributionList(com.zimbra.cs.account.DistributionList) HashSet(java.util.HashSet)

Example 8 with ZAttendee

use of com.zimbra.cs.mailbox.calendar.ZAttendee in project zm-mailbox by Zimbra.

the class CompleteTaskInstance method createCompletedInstanceInvite.

private Invite createCompletedInstanceInvite(Invite recur, ParsedDateTime dtStart) throws ServiceException {
    Invite inst = new Invite(MailItem.Type.TASK, recur.getMethod(), (recur.getTimeZoneMap() != null) ? recur.getTimeZoneMap().clone() : null, recur.isOrganizer());
    long now = System.currentTimeMillis();
    // Assign a new UID.
    String uid = LdapUtil.generateUUID();
    inst.setUid(uid);
    inst.setSeqNo(0);
    // Set completed status/pct/time.
    inst.setStatus(IcalXmlStrMap.STATUS_COMPLETED);
    inst.setPercentComplete("100");
    inst.setCompleted(now);
    // Set time fields.
    inst.setDtStart(dtStart);
    ParsedDuration dur = recur.getEffectiveDuration();
    if (dur != null) {
        ParsedDateTime due = dtStart.add(dur);
        inst.setDtEnd(due);
    }
    inst.setDtStamp(now);
    // Recurrence-related fields should be unset.
    inst.setRecurrence(null);
    inst.setRecurId(null);
    // Copy the rest of the fields.
    inst.setPriority(recur.getPriority());
    inst.setOrganizer(recur.getOrganizer());
    List<ZAttendee> attendees = recur.getAttendees();
    for (ZAttendee at : attendees) inst.addAttendee(at);
    inst.setName(recur.getName());
    inst.setLocation(recur.getLocation());
    inst.setFlags(recur.getFlags());
    inst.setDescription(recur.getDescription(), recur.getDescriptionHtml());
    inst.setFragment(recur.getFragment());
    return inst;
}
Also used : ParsedDuration(com.zimbra.common.calendar.ParsedDuration) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 9 with ZAttendee

use of com.zimbra.cs.mailbox.calendar.ZAttendee in project zm-mailbox by Zimbra.

the class TestCalendarMailSender method testInternalPrefCalendarAllowedTargetsForInviteDeniedAutoReply.

public void testInternalPrefCalendarAllowedTargetsForInviteDeniedAutoReply() throws Exception {
    Account organizerAccount = TestUtil.createAccount(ORGANIZERACCT);
    Account senderAccount = organizerAccount;
    Account attendeeAccount = TestUtil.createAccount(ATTENDEEACCT);
    Mailbox mbox = TestUtil.getMailbox(ATTENDEEACCT);
    String senderEmail = senderAccount.getName();
    Map<String, Object> prefs = Maps.newHashMap();
    prefs.put(Provisioning.A_zimbraPrefCalendarSendInviteDeniedAutoReply, ProvisioningConstants.TRUE);
    prefs.put(Provisioning.A_zimbraPrefCalendarAllowedTargetsForInviteDeniedAutoReply, "internal");
    Provisioning.getInstance().modifyAttrs(attendeeAccount, prefs, true, null);
    ZAttendee matchingAttendee = new ZAttendee(attendeeAccount.getName(), attendeeAccount.getCn(), /* cn */
    senderAccount.getName(), /* sentBy */
    null, /* dir */
    null, /* language */
    IcalXmlStrMap.CUTYPE_INDIVIDUAL, /* cutype */
    null, /* role */
    IcalXmlStrMap.PARTSTAT_NEEDS_ACTION, /* ptst */
    true, /* rsvp */
    null, /* member */
    null, /* delegatedTo */
    null, /* delegatedFrom */
    null);
    boolean allowed;
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, true, /* applyToCalendar */
    matchingAttendee);
    assertTrue(String.format("Should be allowed to send auto-decline because %s=true & %s=internal", Provisioning.A_zimbraPrefCalendarSendInviteDeniedAutoReply, Provisioning.A_zimbraPrefCalendarAllowedTargetsForInviteDeniedAutoReply), allowed);
    senderAccount = null;
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, true, /* applyToCalendar */
    matchingAttendee);
    assertFalse(String.format("Should NOT be allowed to send auto-decline for non-internal because %s=true & %s=internal", Provisioning.A_zimbraPrefCalendarSendInviteDeniedAutoReply, Provisioning.A_zimbraPrefCalendarAllowedTargetsForInviteDeniedAutoReply), allowed);
}
Also used : Account(com.zimbra.cs.account.Account) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee)

Example 10 with ZAttendee

use of com.zimbra.cs.mailbox.calendar.ZAttendee in project zm-mailbox by Zimbra.

the class TestCalendarMailSender method testPrefCalendarSendInviteDeniedAutoReplyTrue.

/**
     * Tests with original invite's organizer in same domain
     * and {@code zimbraPrefCalendarSendInviteDeniedAutoReply=true}
     */
public void testPrefCalendarSendInviteDeniedAutoReplyTrue() throws Exception {
    Account organizerAccount = TestUtil.createAccount(ORGANIZERACCT);
    Account senderAccount = organizerAccount;
    Account attendeeAccount = TestUtil.createAccount(ATTENDEEACCT);
    Mailbox mbox = TestUtil.getMailbox(ATTENDEEACCT);
    String senderEmail = senderAccount.getName();
    Map<String, Object> prefs = Maps.newHashMap();
    prefs.put(Provisioning.A_zimbraPrefCalendarSendInviteDeniedAutoReply, ProvisioningConstants.TRUE);
    Provisioning.getInstance().modifyAttrs(attendeeAccount, prefs, true, null);
    ZAttendee matchingAttendee = new ZAttendee(attendeeAccount.getName(), attendeeAccount.getCn(), /* cn */
    senderAccount.getName(), /* sentBy */
    null, /* dir */
    null, /* language */
    IcalXmlStrMap.CUTYPE_INDIVIDUAL, /* cutype */
    null, /* role */
    IcalXmlStrMap.PARTSTAT_NEEDS_ACTION, /* ptst */
    true, /* rsvp */
    null, /* member */
    null, /* delegatedTo */
    null, /* delegatedFrom */
    null);
    boolean allowed;
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, true, /* applyToCalendar */
    matchingAttendee);
    assertTrue(String.format("Should be allowed to send auto-decline because %s=true", Provisioning.A_zimbraPrefCalendarSendInviteDeniedAutoReply), allowed);
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, false, /* applyToCalendar */
    matchingAttendee);
    assertFalse("Should NOT be allowed to send auto-decline because appyToCalendar=false", allowed);
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, true, /* applyToCalendar */
    null);
    assertFalse("Should NOT be allowed to send auto-decline because no matching attendee in invite", allowed);
    senderEmail = null;
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, true, /* applyToCalendar */
    matchingAttendee);
    assertFalse("Should NOT be allowed to send auto-decline to null sender", allowed);
    senderEmail = "unknown@example.test";
    senderAccount = null;
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(mbox, attendeeAccount, senderEmail, senderAccount, true, /* applyToCalendar */
    matchingAttendee);
    assertFalse("Should NOT be allowed to send auto-decline - no account object for sender", allowed);
    Map<String, Object> attrs = Maps.newHashMap();
    attrs.put(Provisioning.A_zimbraIsSystemResource, ProvisioningConstants.TRUE);
    attrs.put(Provisioning.A_zimbraPrefCalendarSendInviteDeniedAutoReply, ProvisioningConstants.TRUE);
    Account resourceAcct = TestUtil.createAccount(SYSRESOURCEACCT, attrs);
    Mailbox resMbox = TestUtil.getMailbox(SYSRESOURCEACCT);
    allowed = CalendarMailSender.allowInviteAutoDeclinedNotification(resMbox, resourceAcct, senderEmail, senderAccount, true, /* applyToCalendar */
    matchingAttendee);
    assertFalse("Should NOT be allowed to send auto-decline - account is a system resource", allowed);
}
Also used : Account(com.zimbra.cs.account.Account) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee)

Aggregations

ZAttendee (com.zimbra.cs.mailbox.calendar.ZAttendee)29 Account (com.zimbra.cs.account.Account)16 Invite (com.zimbra.cs.mailbox.calendar.Invite)15 Mailbox (com.zimbra.cs.mailbox.Mailbox)10 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)9 ArrayList (java.util.ArrayList)9 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)8 ZOrganizer (com.zimbra.cs.mailbox.calendar.ZOrganizer)7 Element (com.zimbra.common.soap.Element)6 MimeMessage (javax.mail.internet.MimeMessage)6 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)5 Provisioning (com.zimbra.cs.account.Provisioning)5 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)5 AccountAddressMatcher (com.zimbra.cs.util.AccountUtil.AccountAddressMatcher)5 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)4 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)4 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)4 ServiceException (com.zimbra.common.service.ServiceException)4 CalendarResource (com.zimbra.cs.account.CalendarResource)4 Alarm (com.zimbra.cs.mailbox.calendar.Alarm)4