use of com.zimbra.cs.dav.DavException in project zm-mailbox by Zimbra.
the class DavServlet method service.
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ZimbraLog.clearContext();
addRemoteIpToLoggingContext(req);
ZimbraLog.addUserAgentToContext(req.getHeader(DavProtocol.HEADER_USER_AGENT));
//bug fix - send 400 for Range requests
String rangeHeader = req.getHeader(DavProtocol.HEADER_RANGE);
if (null != rangeHeader) {
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Range header not supported", null, Level.debug);
return;
}
RequestType rtype = getAllowedRequestType(req);
ZimbraLog.dav.debug("Allowable request types %s", rtype);
if (rtype == RequestType.none) {
sendError(resp, HttpServletResponse.SC_NOT_ACCEPTABLE, "Not an allowed request type", null, Level.debug);
return;
}
logRequestInfo(req);
Account authUser = null;
DavContext ctxt;
try {
AuthToken at = AuthProvider.getAuthToken(req, false);
if (at != null && (at.isExpired() || !at.isRegistered())) {
at = null;
}
if (at != null && (rtype == RequestType.both || rtype == RequestType.authtoken)) {
authUser = Provisioning.getInstance().get(AccountBy.id, at.getAccountId());
} else if (at == null && (rtype == RequestType.both || rtype == RequestType.password)) {
AuthUtil.AuthResult result = AuthUtil.basicAuthRequest(req, resp, true, this);
if (result.sendErrorCalled) {
logResponseInfo(resp);
return;
}
authUser = result.authorizedAccount;
}
if (authUser == null) {
try {
sendError(resp, HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed", null, Level.debug);
} catch (Exception e) {
}
return;
}
ZimbraLog.addToContext(ZimbraLog.C_ANAME, authUser.getName());
ctxt = new DavContext(req, resp, authUser);
} catch (AuthTokenException e) {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
return;
} catch (ServiceException e) {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
return;
}
DavMethod method = sMethods.get(req.getMethod());
if (method == null) {
setAllowHeader(resp);
sendError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Not an allowed method", null, Level.debug);
return;
}
long t0 = System.currentTimeMillis();
CacheStates cache = null;
try {
if (ZimbraLog.dav.isDebugEnabled()) {
try {
Upload upload = ctxt.getUpload();
if (upload.getSize() > 0 && upload.getContentType().startsWith("text")) {
if (ZimbraLog.dav.isDebugEnabled()) {
StringBuilder logMsg = new StringBuilder("REQUEST\n").append(new String(ByteUtil.readInput(upload.getInputStream(), -1, 20480), "UTF-8"));
ZimbraLog.dav.debug(logMsg.toString());
}
}
} catch (DavException de) {
throw de;
} catch (Exception e) {
ZimbraLog.dav.debug("ouch", e);
}
}
cache = checkCachedResponse(ctxt, authUser);
if (!ctxt.isResponseSent() && !isProxyRequest(ctxt, method)) {
method.checkPrecondition(ctxt);
method.handle(ctxt);
method.checkPostcondition(ctxt);
if (!ctxt.isResponseSent()) {
resp.setStatus(ctxt.getStatus());
}
}
if (!ctxt.isResponseSent()) {
logResponseInfo(resp);
}
} catch (DavException e) {
if (e.getCause() instanceof MailServiceException.NoSuchItemException || e.getStatus() == HttpServletResponse.SC_NOT_FOUND)
ZimbraLog.dav.info(ctxt.getUri() + " not found");
else if (e.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY || e.getStatus() == HttpServletResponse.SC_MOVED_PERMANENTLY)
ZimbraLog.dav.info("sending redirect");
try {
if (e.isStatusSet()) {
resp.setStatus(e.getStatus());
if (e.hasErrorMessage())
e.writeErrorMsg(resp.getOutputStream());
if (ZimbraLog.dav.isDebugEnabled()) {
ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage(), e);
} else {
ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage());
}
if (e.getCause() != null)
ZimbraLog.dav.debug("exception: ", e.getCause());
} else {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
}
} catch (IllegalStateException ise) {
ZimbraLog.dav.debug("can't write error msg", ise);
}
} catch (ServiceException e) {
if (e instanceof MailServiceException.NoSuchItemException) {
sendError(resp, HttpServletResponse.SC_NOT_FOUND, ctxt.getUri() + " not found", null, Level.info);
return;
}
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
} catch (Exception e) {
try {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
} catch (Exception ex) {
}
} finally {
long t1 = System.currentTimeMillis();
ZimbraLog.dav.info("DavServlet operation " + method.getName() + " to " + req.getPathInfo() + " (depth: " + ctxt.getDepth().name() + ") finished in " + (t1 - t0) + "ms");
if (cache != null)
cacheCleanUp(ctxt, cache);
ctxt.cleanup();
}
}
use of com.zimbra.cs.dav.DavException in project zm-mailbox by Zimbra.
the class ScheduleInbox method updateCalendarFreeBusySet.
private void updateCalendarFreeBusySet(DavContext ctxt, ArrayList<String> urls) throws ServiceException, DavException {
String prefix = DavServlet.DAV_PATH + "/" + getOwner();
Mailbox mbox = getMailbox(ctxt);
HashMap<String, Folder> folders = new HashMap<String, Folder>();
for (Folder f : getCalendarFolders(ctxt)) {
folders.put(f.getPath(), f);
}
for (String origurl : urls) {
// Clients often encode the "@" we use in our URLs
String url = HttpUtil.urlUnescape(origurl);
if (!url.startsWith(prefix)) {
continue;
}
String path = url.substring(prefix.length());
if (path.endsWith("/"))
path = path.substring(0, path.length() - 1);
Folder f = folders.remove(path);
if (f == null) {
// check for recently renamed folders
DavResource rs = UrlNamespace.checkRenamedResource(getOwner(), path);
if (rs == null || !rs.isCollection())
throw new DavException("folder not found " + url, DavProtocol.STATUS_FAILED_DEPENDENCY);
f = mbox.getFolderById(ctxt.getOperationContext(), ((MailItemResource) rs).getId());
}
if ((f.getFlagBitmask() & Flag.BITMASK_EXCLUDE_FREEBUSY) == 0)
continue;
ZimbraLog.dav.debug("clearing EXCLUDE_FREEBUSY for " + path);
mbox.alterTag(ctxt.getOperationContext(), f.getId(), MailItem.Type.FOLDER, Flag.FlagInfo.EXCLUDE_FREEBUSY, false, null);
}
if (!folders.isEmpty()) {
for (Folder f : folders.values()) {
ZimbraLog.dav.debug("setting EXCLUDE_FREEBUSY for " + f.getPath());
mbox.alterTag(ctxt.getOperationContext(), f.getId(), MailItem.Type.FOLDER, Flag.FlagInfo.EXCLUDE_FREEBUSY, true, null);
}
}
}
use of com.zimbra.cs.dav.DavException in project zm-mailbox by Zimbra.
the class ScheduleInbox method patchProperties.
@Override
public void patchProperties(DavContext ctxt, java.util.Collection<Element> set, java.util.Collection<QName> remove) throws DavException, IOException {
ArrayList<Element> newSet = null;
for (Element el : set) {
if (el.getQName().equals(DavElements.E_CALENDAR_FREE_BUSY_SET)) {
Iterator<?> hrefs = el.elementIterator(DavElements.E_HREF);
ArrayList<String> urls = new ArrayList<String>();
while (hrefs.hasNext()) urls.add(((Element) hrefs.next()).getText());
try {
updateCalendarFreeBusySet(ctxt, urls);
} catch (ServiceException e) {
ctxt.getResponseProp().addPropError(DavElements.E_CALENDAR_FREE_BUSY_SET, new DavException("error", DavProtocol.STATUS_FAILED_DEPENDENCY));
} catch (DavException e) {
ctxt.getResponseProp().addPropError(DavElements.E_CALENDAR_FREE_BUSY_SET, e);
}
if (newSet == null) {
newSet = new ArrayList<Element>(set);
}
newSet.remove(el);
}
}
if (newSet != null)
set = newSet;
super.patchProperties(ctxt, set, remove);
}
use of com.zimbra.cs.dav.DavException in project zm-mailbox by Zimbra.
the class ScheduleOutbox method handleEventRequest.
private void handleEventRequest(DavContext ctxt, ZCalendar.ZVCalendar cal, ZComponent req, DelegationInfo delegationInfo, String rcpt, Element resp) throws ServiceException, DavException {
if (!DavResource.isSchedulingEnabled()) {
resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
resp.addElement(DavElements.E_REQUEST_STATUS).setText("5.3;No scheduling for the user");
return;
}
ArrayList<Address> recipients = new java.util.ArrayList<Address>();
InternetAddress from, sender, to;
Account target = null;
try {
sender = new JavaMailInternetAddress(delegationInfo.getOriginatorEmail());
Provisioning prov = Provisioning.getInstance();
if (ctxt.getActingAsDelegateFor() != null) {
target = prov.getAccountByName(ctxt.getActingAsDelegateFor());
}
if (target != null) {
from = AccountUtil.getFriendlyEmailAddress(target);
} else {
if (delegationInfo.getOwnerEmail() != null) {
from = new JavaMailInternetAddress(delegationInfo.getOwnerEmail());
} else {
target = getMailbox(ctxt).getAccount();
if (AccountUtil.addressMatchesAccount(target, delegationInfo.getOriginatorEmail())) {
// Make sure we don't use two different aliases for From and Sender.
// This is a concern with Apple iCal, which picks a random alias as originator.
from = sender;
} else {
from = AccountUtil.getFriendlyEmailAddress(target);
}
}
}
if (sender.getAddress() != null && sender.getAddress().equalsIgnoreCase(from.getAddress())) {
sender = null;
}
to = new JavaMailInternetAddress(CalDavUtils.stripMailto(rcpt));
recipients.add(to);
} catch (AddressException e) {
resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
resp.addElement(DavElements.E_REQUEST_STATUS).setText("3.7;" + rcpt);
return;
}
String status = req.getPropVal(ICalTok.STATUS, "");
String method = cal.getPropVal(ICalTok.METHOD, "REQUEST");
String subject = "";
if (method.equals("REQUEST")) {
ZProperty organizerProp = req.getProperty(ICalTok.ORGANIZER);
if (organizerProp != null) {
String organizerStr = this.getAddressFromPrincipalURL(new ZOrganizer(organizerProp).getAddress());
if (!AccountUtil.addressMatchesAccount(getMailbox(ctxt).getAccount(), organizerStr)) {
ZimbraLog.dav.debug("scheduling appointment on behalf of %s", organizerStr);
}
}
} else if (method.equals("REPLY")) {
ZProperty attendeeProp = req.getProperty(ICalTok.ATTENDEE);
if (attendeeProp == null)
throw new DavException("missing property ATTENDEE", HttpServletResponse.SC_BAD_REQUEST);
ZAttendee attendee = new ZAttendee(attendeeProp);
String partStat = attendee.getPartStat();
if (partStat.equals(IcalXmlStrMap.PARTSTAT_ACCEPTED)) {
subject = "Accept: ";
} else if (partStat.equals(IcalXmlStrMap.PARTSTAT_TENTATIVE)) {
subject = "Tentative: ";
} else if (partStat.equals(IcalXmlStrMap.PARTSTAT_DECLINED)) {
subject = "Decline: ";
}
}
if (status.equals("CANCELLED"))
subject = "Cancelled: ";
subject += req.getPropVal(ICalTok.SUMMARY, "");
String uid = req.getPropVal(ICalTok.UID, null);
if (uid == null) {
resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
resp.addElement(DavElements.E_REQUEST_STATUS).setText("3.1;UID");
return;
}
try {
List<Invite> components = Invite.createFromCalendar(ctxt.getAuthAccount(), null, cal, false);
FriendlyCalendaringDescription friendlyDesc = new FriendlyCalendaringDescription(components, ctxt.getAuthAccount());
String desc = friendlyDesc.getAsPlainText();
String descHtml = req.getDescriptionHtml();
if ((descHtml == null) || (descHtml.length() == 0))
descHtml = friendlyDesc.getAsHtml();
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(ctxt.getAuthAccount());
MimeMessage mm = CalendarMailSender.createCalendarMessage(target, from, sender, recipients, subject, desc, descHtml, uid, cal);
mbox.getMailSender().setSendPartial(true).sendMimeMessage(ctxt.getOperationContext(), mbox, true, mm, null, null, null, null, false);
} catch (ServiceException e) {
resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
resp.addElement(DavElements.E_REQUEST_STATUS).setText("5.1");
return;
}
resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
resp.addElement(DavElements.E_REQUEST_STATUS).setText("2.0;Success");
}
use of com.zimbra.cs.dav.DavException in project zm-mailbox by Zimbra.
the class UrlNamespace method getPrincipalAtUrl.
public static DavResource getPrincipalAtUrl(DavContext ctxt, String url) throws DavException {
String name = ctxt.getAuthAccount().getName();
String proxyPrincipal = "";
if (url != null) {
int index = url.indexOf(PRINCIPALS_PATH);
if (index == -1 || url.endsWith(PRINCIPALS_PATH)) {
try {
return new Principal(ctxt.getAuthAccount(), url);
} catch (ServiceException se) {
throw new DavException("invalid uri", HttpServletResponse.SC_NOT_FOUND, se);
}
}
index += PRINCIPALS_PATH.length();
name = url.substring(index);
if (name.indexOf('/') > 0) {
proxyPrincipal = name.substring(name.indexOf('/') + 1);
if (proxyPrincipal.endsWith("/")) {
proxyPrincipal = proxyPrincipal.substring(0, proxyPrincipal.indexOf('/'));
}
name = name.substring(0, name.indexOf('/'));
}
name = name.replaceAll("%40", "@");
} else {
url = "/";
}
ZimbraLog.dav.debug("getPrincipalAtUrl name='%s' url='%s' proxyPrincipal='%s'", name, url, proxyPrincipal);
try {
Account acct = Provisioning.getInstance().get(Key.AccountBy.name, name);
if (acct == null) {
throw new DavException("user not found", HttpServletResponse.SC_NOT_FOUND, null);
}
if (CalendarProxyRead.CALENDAR_PROXY_READ.equals(proxyPrincipal)) {
if (!ctxt.useIcalDelegation()) {
throw new DavException("Not available because zimbraPrefAppleIcalDelegationEnabled=FALSE", HttpServletResponse.SC_NOT_FOUND, null);
}
return new CalendarProxyRead(acct, url);
}
if (CalendarProxyWrite.CALENDAR_PROXY_WRITE.equals(proxyPrincipal)) {
if (!ctxt.useIcalDelegation()) {
throw new DavException("Not available because zimbraPrefAppleIcalDelegationEnabled=FALSE", HttpServletResponse.SC_NOT_FOUND, null);
}
return new CalendarProxyWrite(acct, url);
}
return new User(ctxt, acct, url);
} catch (ServiceException se) {
throw new DavException("user not found", HttpServletResponse.SC_NOT_FOUND, null);
}
}
Aggregations