use of com.zimbra.cs.util.AccountUtil.AccountAddressMatcher in project zm-mailbox by Zimbra.
the class CalDavUtils method removeAttendeeForOrganizer.
// Fixup for ATTENDEE properties set by Apple iCal
// Don't let the organizer to be also listed as an attendee.
public static void removeAttendeeForOrganizer(ZComponent comp) {
if (!DebugConfig.caldavAllowAttendeeForOrganizer && (ICalTok.VEVENT.equals(comp.getTok()) || ICalTok.VTODO.equals(comp.getTok()))) {
String organizer = comp.getPropVal(ICalTok.ORGANIZER, null);
if (organizer != null) {
organizer = organizer.trim();
AccountAddressMatcher acctMatcher = null;
String address = stripMailto(organizer);
if (address != null) {
try {
Account acct = Provisioning.getInstance().get(AccountBy.name, address);
if (acct != null) {
acctMatcher = new AccountAddressMatcher(acct);
}
} catch (ServiceException e) {
// ignore
ZimbraLog.dav.warn("could not get the account matcher for " + address, e);
}
}
for (Iterator<ZProperty> propIter = comp.getPropertyIterator(); propIter.hasNext(); ) {
ZProperty prop = propIter.next();
if (ICalTok.ATTENDEE.equals(prop.getToken())) {
String att = prop.getValue();
if (att != null) {
att = att.trim();
try {
// iCal has a habit of listing the organizer as an ATTENDEE. Undo it.
if (att.equalsIgnoreCase(organizer) || (acctMatcher != null && acctMatcher.matches(stripMailto(att)))) {
propIter.remove();
}
} catch (ServiceException e) {
// ignore
ZimbraLog.dav.warn("exception while matching the attendee address " + att, e);
}
} else {
// We haven't seen this case occur, but just in case.
propIter.remove();
}
}
}
}
}
}
use of com.zimbra.cs.util.AccountUtil.AccountAddressMatcher in project zm-mailbox by Zimbra.
the class MailSender method getSenderHeaders.
/**
* Determines an acceptable set of {@code From} and {@code Sender} header
* values for a message. The message's existing {@code from} and {@code
* sender} values are examined in light of the authenticated account's
* settings and are reset to the account's default return address if
* they aren't acceptable.
* @return a {@link Pair} containing the approved {@code from} and {@code
* sender} header addresses, in that order.
*/
public Pair<InternetAddress, InternetAddress> getSenderHeaders(InternetAddress from, InternetAddress sender, Account acct, Account authuser, boolean asAdmin) throws ServiceException {
if (from != null && authuser.isAllowAnyFromAddress()) {
return new Pair<InternetAddress, InternetAddress>(from, sender);
}
if (from == null && sender == null) {
return new Pair<InternetAddress, InternetAddress>(AccountUtil.getFriendlyEmailAddress(authuser), null);
}
if (Objects.equal(sender, from)) {
// no need for matching Sender and From addresses
sender = null;
}
if (from == null && sender != null) {
// if only one value is given, set From and unset Sender
from = sender;
sender = null;
}
AccessManager amgr = AccessManager.getInstance();
if (// send-as requested
sender == null && (// either it's my address
AccountUtil.addressMatchesAccount(authuser, from.getAddress()) || amgr.canSendAs(authuser, acct, from.getAddress(), asAdmin))) {
// or I've been granted permission
return new Pair<InternetAddress, InternetAddress>(from, null);
}
if (sender != null) {
// send-obo requested.
// Restrict Sender value to owned addresses. Not even zimbraAllowFromAddress is acceptable.
AccountAddressMatcher matcher = new AccountAddressMatcher(authuser, true);
if (!matcher.matches(sender.getAddress())) {
sender = AccountUtil.getFriendlyEmailAddress(authuser);
}
} else if (!isDataSourceSender()) {
// Downgrade disallowed send-as to send-obo.
sender = AccountUtil.getFriendlyEmailAddress(authuser);
}
if (mCalendarMode) {
// In calendar mode any user may send on behalf of any other user.
return new Pair<InternetAddress, InternetAddress>(from, sender);
} else if (amgr.canSendOnBehalfOf(authuser, acct, from.getAddress(), asAdmin)) {
// Allow based on rights granted.
return new Pair<InternetAddress, InternetAddress>(from, sender);
} else if (AccountUtil.isAllowedDataSourceSendAddress(authuser, from.getAddress())) {
// Allow send-obo if address is a pop/imap/caldav data source address. (bugs 38813/46378)
return new Pair<InternetAddress, InternetAddress>(from, sender);
} else {
// Not allowed to use the requested From value. Send as self.
return new Pair<InternetAddress, InternetAddress>(sender, null);
}
}
use of com.zimbra.cs.util.AccountUtil.AccountAddressMatcher in project zm-mailbox by Zimbra.
the class Mailbox method processICalReplies.
private void processICalReplies(OperationContext octxt, ZVCalendar cal, String sender) throws ServiceException {
// Reply from Outlook will usually have PRODID set to the following:
//
// Outlook2007+ZCO: PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
// Outlook2010+ZCO: PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN
// Outlook20xx+Exchange: PRODID:Microsoft Exchange Server 2007
// (if Exchange is Exchange 2007; Exchange 2010 probably works similarly)
//
// Lowest common denominator is "Microsoft" substring.
String prodId = cal.getPropVal(ICalTok.PRODID, null);
boolean fromOutlook = prodId != null && prodId.toLowerCase().contains("microsoft");
AccountAddressMatcher acctMatcher = new AccountAddressMatcher(getAccount());
List<Invite> components = Invite.createFromCalendar(getAccount(), null, cal, false);
for (Invite inv : components) {
String orgAddress;
if (inv.hasOrganizer()) {
ZOrganizer org = inv.getOrganizer();
orgAddress = org.getAddress();
} else {
ZimbraLog.calendar.warn("No ORGANIZER found in REPLY. Assuming current mailbox.");
orgAddress = getAccount().getName();
}
if (acctMatcher.matches(orgAddress)) {
// RECURRENCE-ID.
if (fromOutlook && !inv.isAllDayEvent() && inv.hasRecurId()) {
RecurId rid = inv.getRecurId();
if (rid.getDt() != null && rid.getDt().hasZeroTime()) {
CalendarItem calItem = getCalendarItemByUid(octxt, inv.getUid());
if (calItem != null) {
Invite seriesInv = calItem.getDefaultInviteOrNull();
if (seriesInv != null) {
ParsedDateTime seriesDtStart = seriesInv.getStartTime();
if (seriesDtStart != null) {
ParsedDateTime fixedDt = seriesDtStart.cloneWithNewDate(rid.getDt());
RecurId fixedRid = new RecurId(fixedDt, rid.getRange());
ZimbraLog.calendar.debug("Fixed up invalid RECURRENCE-ID with zero time; before=[%s], after=[%s]", rid, fixedRid);
inv.setRecurId(fixedRid);
}
}
}
}
}
processICalReply(octxt, inv, sender);
} else {
Account orgAccount = inv.getOrganizerAccount();
// Unknown organizer
if (orgAccount == null) {
ZimbraLog.calendar.warn("Unknown organizer " + orgAddress + " in REPLY");
continue;
}
if (Provisioning.onLocalServer(orgAccount)) {
// Run in the context of organizer's mailbox.
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(orgAccount);
OperationContext orgOctxt = new OperationContext(mbox);
mbox.processICalReply(orgOctxt, inv, sender);
} else {
// Organizer's mailbox is on a remote server.
String uri = AccountUtil.getSoapUri(orgAccount);
if (uri == null) {
ZimbraLog.calendar.warn("Unable to determine URI for organizer account %s", orgAddress);
continue;
}
try {
// TODO: Get the iCalendar data from the
// MIME part since we already have it.
String ical;
StringWriter sr = null;
try {
sr = new StringWriter();
inv.setMethod(ICalTok.REPLY.toString());
inv.newToICalendar(true).toICalendar(sr);
ical = sr.toString();
} finally {
if (sr != null) {
sr.close();
}
}
Options options = new Options();
AuthToken authToken = AuthToken.getCsrfUnsecuredAuthToken(getAuthToken(octxt));
options.setAuthToken(authToken.toZAuthToken());
options.setTargetAccount(orgAccount.getName());
options.setTargetAccountBy(AccountBy.name);
options.setUri(uri);
options.setNoSession(true);
ZMailbox zmbox = ZMailbox.getMailbox(options);
zmbox.setAccountId(orgAccount.getId());
zmbox.iCalReply(ical, sender);
} catch (IOException e) {
throw ServiceException.FAILURE("Error while posting REPLY to organizer mailbox host", e);
}
}
}
}
}
use of com.zimbra.cs.util.AccountUtil.AccountAddressMatcher in project zm-mailbox by Zimbra.
the class Invite method getMatchingAttendee.
public ZAttendee getMatchingAttendee(ZAttendee matchAttendee) throws ServiceException {
// Look up internal account for the attendee. For internal users we want to match
// on all email addresses of the account.
AccountAddressMatcher acctMatcher = null;
String matchAddress = matchAttendee.getAddress();
if (matchAddress != null) {
Account matchAcct = Provisioning.getInstance().get(AccountBy.name, matchAddress);
if (matchAcct != null) {
acctMatcher = new AccountAddressMatcher(matchAcct);
}
}
for (ZAttendee at : getAttendees()) {
if (matchAttendee.addressesMatch(at) || (acctMatcher != null && acctMatcher.matches(at.getAddress()))) {
return at;
}
}
return null;
}
use of com.zimbra.cs.util.AccountUtil.AccountAddressMatcher in project zm-mailbox by Zimbra.
the class Invite method thisAcctIsOrganizer.
/**
* @param acct
* @return TRUE if this account is the "organizer" of the Event
* @throws ServiceException
*/
private boolean thisAcctIsOrganizer(Account acct) throws ServiceException {
if (hasOrganizer()) {
AccountAddressMatcher acctMatcher = new AccountAddressMatcher(acct);
String addr = getOrganizer().getAddress();
boolean isOrg = acctMatcher.matches(addr);
if (!isOrg && acct != null) {
// bug 41638: Let's also check if address matches zimbraPrefFromAddress.
String prefFromAddr = acct.getPrefFromAddress();
if (prefFromAddr != null && prefFromAddr.equalsIgnoreCase(addr))
isOrg = true;
}
return isOrg;
} else {
// method for more info.
return !hasOtherAttendees();
}
}
Aggregations