use of com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException in project zm-mailbox by Zimbra.
the class Mailbox method getItemByUuid.
MailItem getItemByUuid(String uuid, MailItem.Type type, boolean fromDumpster) throws ServiceException {
if (fromDumpster) {
MailItem item = null;
try {
item = MailItem.getByUuid(this, uuid, type, true);
if (item != null && !isVisibleInDumpster(item)) {
item = null;
}
} catch (NoSuchItemException e) {
}
// fault.
if (item == null) {
throw MailItem.noSuchItemUuid(uuid, type);
}
return item;
}
// try the cache first
MailItem item = getCachedItemByUuid(uuid, type);
if (item != null) {
return item;
}
// the tag and folder caches contain ALL tags and folders, so cache miss == doesn't exist
if (isCachedType(type)) {
throw MailItem.noSuchItemUuid(uuid, type);
}
// cache miss, so fetch from the database
item = MailItem.getByUuid(this, uuid, type);
return item;
}
use of com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException in project zm-mailbox by Zimbra.
the class Mailbox method getItemByImapId.
/**
* Fetches a <tt>MailItem</tt> by its IMAP id.
* @throws MailServiceException if there is no <tt>MailItem</tt> with the given id.
* @see MailServiceException#NO_SUCH_ITEM
*/
public MailItem getItemByImapId(OperationContext octxt, int imapId, int folderId) throws ServiceException {
boolean success = false;
try {
// tag/folder caches are populated in beginTransaction...
beginTransaction("getItemByImapId", octxt);
MailItem item = checkAccess(getCachedItem(imapId));
// in general, the item will not have been moved and its id will be the same as its IMAP id.
if (item == null) {
try {
item = checkAccess(MailItem.getById(this, imapId));
if (item.getImapUid() != imapId) {
item = null;
}
} catch (NoSuchItemException nsie) {
}
}
// if it's not found, we have to search on the non-indexed IMAP_ID column...
if (item == null) {
item = checkAccess(MailItem.getByImapId(this, imapId, folderId));
}
if (isCachedType(item.getType()) || item.getImapUid() != imapId || item.getFolderId() != folderId) {
throw MailServiceException.NO_SUCH_ITEM(imapId);
}
success = true;
return item;
} finally {
endTransaction(success);
}
}
use of com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException in project zm-mailbox by Zimbra.
the class UserServlet method doPost.
/**
* Adds an item to a folder specified in the URI. The item content is provided in the POST request's body.
*/
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
UserServletContext context = null;
ZimbraLog.clearContext();
addRemoteIpToLoggingContext(req);
try {
context = new UserServletContext(req, resp, this);
if (!checkAuthentication(context)) {
sendError(context, req, resp, L10nUtil.getMessage(MsgKey.errMustAuthenticate, req));
return;
}
checkTargetAccountStatus(context);
if (proxyIfRemoteTargetAccount(req, resp, context))
return;
if (context.getAuthAccount() != null) {
ZimbraLog.addAccountNameToContext(context.getAuthAccount().getName());
}
boolean doCsrfCheck = false;
if (req.getAttribute(CsrfFilter.CSRF_TOKEN_CHECK) != null) {
doCsrfCheck = (Boolean) req.getAttribute(CsrfFilter.CSRF_TOKEN_CHECK);
}
if (doCsrfCheck) {
String csrfToken = req.getHeader(Constants.CSRF_TOKEN);
if (log.isDebugEnabled()) {
String paramValue = req.getParameter(QP_AUTH);
log.debug("CSRF check is: %s, CSRF token is: %s, Authentication recd with request is: %s", doCsrfCheck, csrfToken, paramValue);
}
if (!StringUtil.isNullOrEmpty(csrfToken)) {
if (!CsrfUtil.isValidCsrfToken(csrfToken, context.authToken)) {
context.setCsrfAuthSucceeded(Boolean.FALSE);
log.debug("CSRF token validation failed for account: %s" + ", Auth token is CSRF enabled: %s" + "CSRF token is: %s", context.authToken, context.authToken.isCsrfTokenEnabled(), csrfToken);
sendError(context, req, resp, L10nUtil.getMessage(MsgKey.errMustAuthenticate, req));
return;
} else {
context.setCsrfAuthSucceeded(Boolean.TRUE);
}
}
}
Folder folder = null;
String filename = null;
Mailbox mbox = UserServletUtil.getTargetMailbox(context);
if (mbox != null) {
ZimbraLog.addMboxToContext(mbox.getId());
log.info("POST: " + context.req.getRequestURL().toString());
context.opContext = new OperationContext(context.getAuthAccount(), isAdminRequest(req));
try {
context.target = UserServletUtil.resolveItem(context, false);
} catch (NoSuchItemException nsie) {
// perhaps it's a POST to "Notebook/new-file-name" -- find the parent folder and proceed from there
if (context.itemPath == null)
throw nsie;
int separator = context.itemPath.lastIndexOf('/');
if (separator <= 0)
throw nsie;
filename = context.itemPath.substring(separator + 1);
context.itemPath = context.itemPath.substring(0, separator);
context.target = UserServletUtil.resolveItem(context, false);
context.extraPath = filename;
}
folder = (context.target instanceof Folder ? (Folder) context.target : mbox.getFolderById(context.opContext, context.target.getFolderId()));
if (context.target != folder) {
if (filename == null)
filename = context.target.getName();
else
// need to fail on POST to "Notebook/existing-file/random-cruft"
throw MailServiceException.NO_SUCH_FOLDER(context.itemPath);
}
if (proxyIfMountpoint(req, resp, context, folder)) {
// if the target is a mountpoint, the request was already proxied to the resolved target
return;
}
}
// if they specified a filename, default to the native formatter
if (context.format == null && filename != null)
context.format = FormatType.HTML_CONVERTED;
String ctype = context.req.getContentType();
// if no format explicitly specified, try to guess it from the Content-Type header
if (context.format == null && ctype != null) {
String normalizedType = new ContentType(ctype).getContentType();
Formatter fmt = FormatterFactory.mDefaultFormatters.get(normalizedType);
if (fmt != null)
context.format = fmt.getType();
}
context.target = folder;
resolveFormatter(context);
if (!context.formatter.supportsSave())
sendError(context, req, resp, L10nUtil.getMessage(MsgKey.errUnsupportedFormat, req));
// authentication, call the formatter and let it deal with preventing harvest attacks.
if (mbox == null && context.formatter.requiresAuth())
throw ServiceException.PERM_DENIED(L10nUtil.getMessage(MsgKey.errPermissionDenied, req));
context.formatter.save(context, ctype, folder, filename);
} catch (ServiceException se) {
if (se.getCode() == ServiceException.PERM_DENIED || se instanceof NoSuchItemException) {
sendError(context, req, resp, L10nUtil.getMessage(MsgKey.errNoSuchItem, req));
} else if (se.getCode() == AccountServiceException.MAINTENANCE_MODE || se.getCode() == AccountServiceException.ACCOUNT_INACTIVE) {
sendError(context, req, resp, se.getMessage());
} else if (se.getCode() == ServiceException.INVALID_REQUEST) {
if (log.isDebugEnabled()) {
log.debug("Invalid POST Request", se);
} else {
log.info("Invalid POST Request - %s", se.getMessage());
}
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, se.getMessage());
} else {
if (log.isDebugEnabled()) {
log.info("Service Exception caught whilst processing POST", se);
} else {
log.info("Service Exception caught whilst processing POST - %s", se.getMessage());
}
throw new ServletException(se);
}
} catch (UserServletException e) {
// add check for ServiceException root cause?
if (e.getHttpStatusCode() == HttpServletResponse.SC_UNAUTHORIZED) {
sendError(context, req, resp, L10nUtil.getMessage(MsgKey.errMustAuthenticate, req));
} else {
resp.sendError(e.getHttpStatusCode(), e.getMessage());
}
} finally {
ZimbraLog.clearContext();
}
}
use of com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException in project zm-mailbox by Zimbra.
the class UserServletUtil method resolveItem.
/*
* Parses the pathInfo, then returns MailItem corresponding to the resource in pathInfo.
*
* If the formatter does not require authentication, e.g. IfbFormatter,
* then the path resolution is skipped and returns null. That's because
* IfbFormatter does not internally use the resource identified in the URL.
* It gets the ifb information directly from the Mailbox.
*
* If the formatter declares that the authentication is not required, it's
* the formatter's responsibility to make sure the MailItems returned to
* the clients has gone through the access checks.
*
*/
public static MailItem resolveItem(UserServletContext context, boolean checkExtension) throws ServiceException {
if (context.formatter != null && !context.formatter.requiresAuth() && !FormatType.FREE_BUSY.equals(context.formatter.getType())) {
return null;
}
Mailbox mbox = context.targetMailbox;
// special-case the fetch-by-IMAP-id option
if (context.imapId > 0) {
// fetch the folder from the path
Folder folder = mbox.getFolderByPath(context.opContext, context.itemPath);
// and then fetch the item from the "imap_id" query parameter
return mbox.getItemByImapId(context.opContext, context.imapId, folder.getId());
}
if (context.itemId != null) {
OperationContext opContext = null;
if (context.fromDumpster && context.isUsingAdminPrivileges()) {
//should have the admin rights to search dumpster
// use the authToken passed by invoker to generate a new one
opContext = new OperationContext(context.authToken);
} else {
// use the opContext generated from account
opContext = context.opContext;
}
context.target = mbox.getItemById(opContext, context.itemId.getId(), MailItem.Type.UNKNOWN, context.fromDumpster);
context.itemPath = context.target.getPath();
if (context.target instanceof Mountpoint || context.extraPath == null || context.extraPath.equals(""))
return context.target;
if (context.itemPath == null)
throw MailServiceException.NO_SUCH_ITEM("?id=" + context.itemId + "&name=" + context.extraPath);
context.target = null;
context.itemId = null;
}
if (context.extraPath != null && !context.extraPath.equals("")) {
context.itemPath = (context.itemPath + '/' + context.extraPath).replaceAll("//+", "/");
context.extraPath = null;
}
if (FormatType.FREE_BUSY.equals(context.format) || FormatType.IFB.equals(context.format)) {
try {
// Do the get as mailbox owner to circumvent ACL system.
context.target = mbox.getItemByPath(null, context.itemPath);
} catch (ServiceException e) {
if (!(e instanceof NoSuchItemException))
throw e;
}
} else {
// first, try the full requested path
ServiceException failure = null;
try {
context.target = mbox.getItemByPath(context.opContext, context.itemPath);
} catch (ServiceException e) {
if (!(e instanceof NoSuchItemException) && !e.getCode().equals(ServiceException.PERM_DENIED))
throw e;
failure = e;
}
if (context.target == null) {
// then we need to proxy the request to the sharer's mailbox.
try {
// to search for the mountpoint we use admin rights on the user's mailbox.
// this is done so that MailItems in the mountpoint can be resolved
// according to the ACL stored in the owner's Folder. when a mountpoint
// is found, then the request is proxied to the owner's mailbox host,
// and the current requestor's credential is used to validate against
// the ACL.
Pair<Folder, String> match = mbox.getFolderByPathLongestMatch(null, Mailbox.ID_FOLDER_USER_ROOT, context.itemPath);
Folder reachable = match.getFirst();
if (reachable instanceof Mountpoint) {
context.target = reachable;
context.itemPath = reachable.getPath();
context.extraPath = match.getSecond();
}
} catch (ServiceException e) {
}
}
if (context.target == null) {
// if they asked for something like "calendar.csv" (where "calendar" was the folder name), try again minus the extension
int dot = context.itemPath.lastIndexOf('.'), slash = context.itemPath.lastIndexOf('/');
if (checkExtension && context.format == null && dot != -1 && dot > slash) {
/* if path == /foo/bar/baz.html, then
* format -> html
* path -> /foo/bar/baz */
String unsuffixedPath = context.itemPath.substring(0, dot);
try {
context.format = FormatType.fromString(context.itemPath.substring(dot + 1));
if (context.format != null) {
context.formatter = FormatterFactory.mFormatters.get(context.format);
}
if (context.formatter != null && !context.formatter.requiresAuth()) {
// Do the get as mailbox owner to circumvent ACL system.
context.target = mbox.getItemByPath(null, unsuffixedPath);
} else {
context.target = mbox.getItemByPath(context.opContext, unsuffixedPath);
}
context.itemPath = unsuffixedPath;
} catch (ServiceException e) {
}
}
}
if (context.target == null)
throw failure;
}
return context.target;
}
use of com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException in project zm-mailbox by Zimbra.
the class ParseMimeMessage method handleAttachments.
private static void handleAttachments(Element attachElem, MimeMultipart mmp, ParseMessageContext ctxt, String contentID, String contentDisposition, boolean attachFromMessageCache) throws ServiceException, MessagingException, IOException {
if (contentID != null) {
contentID = '<' + contentID + '>';
}
String attachIds = attachElem.getAttribute(MailConstants.A_ATTACHMENT_ID, null);
if (attachIds != null) {
for (String uploadId : attachIds.split(FileUploadServlet.UPLOAD_DELIMITER)) {
Upload up = FileUploadServlet.fetchUpload(ctxt.zsc.getAuthtokenAccountId(), uploadId, ctxt.zsc.getAuthToken());
if (up == null) {
throw MailServiceException.NO_SUCH_UPLOAD(uploadId);
}
attachUpload(mmp, up, contentID, ctxt, null, null, contentDisposition);
ctxt.out.addUpload(up);
}
}
for (Element elem : attachElem.listElements()) {
String attachType = elem.getName();
boolean optional = elem.getAttributeBool(MailConstants.A_OPTIONAL, false);
try {
if (attachType.equals(MailConstants.E_MIMEPART)) {
ItemId iid = new ItemId(elem.getAttribute(MailConstants.A_MESSAGE_ID), ctxt.zsc);
String part = elem.getAttribute(MailConstants.A_PART);
attachPart(mmp, iid, part, contentID, ctxt, contentDisposition);
} else if (attachType.equals(MailConstants.E_MSG)) {
ItemId iid = new ItemId(elem.getAttribute(MailConstants.A_ID), ctxt.zsc);
attachMessage(mmp, iid, contentID, ctxt, attachFromMessageCache);
} else if (attachType.equals(MailConstants.E_CONTACT)) {
ItemId iid = new ItemId(elem.getAttribute(MailConstants.A_ID), ctxt.zsc);
attachContact(mmp, iid, contentID, ctxt);
} else if (attachType.equals(MailConstants.E_DOC)) {
String path = elem.getAttribute(MailConstants.A_PATH, null);
if (path != null) {
attachDocument(mmp, path, contentID, ctxt);
} else {
ItemId iid = new ItemId(elem.getAttribute(MailConstants.A_ID), ctxt.zsc);
int version = (int) elem.getAttributeLong(MailConstants.A_VERSION, 0);
attachDocument(mmp, iid, version, contentID, ctxt);
}
}
} catch (NoSuchItemException nsie) {
if (!optional)
throw nsie;
ZimbraLog.soap.info("skipping missing optional attachment: " + elem);
}
}
}
Aggregations