Search in sources :

Example 16 with NoSuchItemException

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;
}
Also used : DbMailItem(com.zimbra.cs.db.DbMailItem) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)

Example 17 with NoSuchItemException

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);
    }
}
Also used : DbMailItem(com.zimbra.cs.db.DbMailItem) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)

Example 18 with NoSuchItemException

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();
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) ServletException(javax.servlet.ServletException) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ContentType(com.zimbra.common.mime.ContentType) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) OctopusPatchFormatter(com.zimbra.cs.service.formatter.OctopusPatchFormatter) ZipFormatter(com.zimbra.cs.service.formatter.ZipFormatter) TarFormatter(com.zimbra.cs.service.formatter.TarFormatter) IfbFormatter(com.zimbra.cs.service.formatter.IfbFormatter) Formatter(com.zimbra.cs.service.formatter.Formatter) Folder(com.zimbra.cs.mailbox.Folder) ZFolder(com.zimbra.client.ZFolder) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)

Example 19 with NoSuchItemException

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;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Folder(com.zimbra.cs.mailbox.Folder) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 20 with NoSuchItemException

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);
        }
    }
}
Also used : Element(com.zimbra.common.soap.Element) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) ItemId(com.zimbra.cs.service.util.ItemId) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)

Aggregations

NoSuchItemException (com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)50 Mailbox (com.zimbra.cs.mailbox.Mailbox)21 ServiceException (com.zimbra.common.service.ServiceException)20 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)15 MailItem (com.zimbra.cs.mailbox.MailItem)11 Test (org.junit.Test)11 Account (com.zimbra.cs.account.Account)10 OperationContext (com.zimbra.cs.mailbox.OperationContext)10 ItemId (com.zimbra.cs.service.util.ItemId)10 Folder (com.zimbra.cs.mailbox.Folder)9 MimeMessage (javax.mail.internet.MimeMessage)8 Element (com.zimbra.common.soap.Element)7 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)7 IOException (java.io.IOException)7 AccountServiceException (com.zimbra.cs.account.AccountServiceException)6 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)6 ArrayList (java.util.ArrayList)6 DbMailItem (com.zimbra.cs.db.DbMailItem)5 DbTag (com.zimbra.cs.db.DbTag)5 Document (com.zimbra.cs.mailbox.Document)5