Search in sources :

Example 21 with Mountpoint

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

the class ImapHandler method accumulatePaths.

private void accumulatePaths(Object mboxobj, String owner, ImapPath relativeTo, Map<ImapPath, ItemId> paths) throws ServiceException {
    String root = relativeTo == null ? "" : "/" + relativeTo.asResolvedPath();
    if (mboxobj instanceof Mailbox) {
        Mailbox mbox = (Mailbox) mboxobj;
        Collection<Folder> folders = mbox.getVisibleFolders(getContext());
        if (folders == null) {
            folders = mbox.getFolderById(getContext(), relativeTo == null ? Mailbox.ID_FOLDER_USER_ROOT : relativeTo.asItemId().getId()).getSubfolderHierarchy();
        }
        boolean isMailFolders = Provisioning.getInstance().getLocalServer().isImapDisplayMailFoldersOnly();
        for (Folder folder : folders) {
            if (!folder.getPath().startsWith(root) || folder.getPath().equals(root)) {
                continue;
            }
            //bug 6418 ..filter out folders which are contacts and chat for LIST command.
            if (isMailFolders) {
                //  chat has item type of message.hence ignoring the chat folder by name.
                MailItem.Type view = folder.getDefaultView();
                if ((view == MailItem.Type.CHAT) || (folder.getName().equals("Chats"))) {
                    continue;
                }
            }
            ImapPath path = relativeTo == null ? new ImapPath(owner, folder, credentials) : new ImapPath(owner, folder, relativeTo);
            if (path.isVisible()) {
                if (userAgent != null && userAgent.startsWith(IDInfo.DATASOURCE_IMAP_CLIENT_NAME) && folder.isTagged(Flag.FlagInfo.SYNCFOLDER)) {
                    //bug 72577 - do not display folders synced with IMAP datasource to downstream IMAP datasource connections
                    continue;
                }
                boolean alreadyTraversed = paths.put(path, path.asItemId()) != null;
                if (folder instanceof Mountpoint && !alreadyTraversed) {
                    accumulatePaths(path.getOwnerMailbox(), owner, path, paths);
                }
            }
        }
    } else if (mboxobj instanceof ZMailbox) {
        ZMailbox zmbx = (ZMailbox) mboxobj;
        for (ZFolder zfolder : zmbx.getAllFolders()) {
            if (!zfolder.getPath().startsWith(root) || zfolder.getPath().equals(root)) {
                continue;
            }
            ImapPath path = relativeTo == null ? new ImapPath(owner, zfolder, credentials) : new ImapPath(owner, zfolder, relativeTo);
            if (path.isVisible()) {
                paths.put(path, path.asItemId());
            }
        }
    }
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) ZMailbox(com.zimbra.client.ZMailbox) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ZFolder(com.zimbra.client.ZFolder) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) Folder(com.zimbra.cs.mailbox.Folder) ZFolder(com.zimbra.client.ZFolder) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 22 with Mountpoint

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

the class ImapPath method isValidImapPath.

/**
     * Mostly checking that the path doesn't clash with any paths we don't want to expose via IMAP.
     * Separated out from isVisible() to aid IMAP LSUB command support.
     */
boolean isValidImapPath() throws ServiceException {
    if (mCredentials != null) {
        if (mCredentials.isHackEnabled(ImapCredentials.EnabledHack.WM5)) {
            String lcname = mPath.toLowerCase();
            if (lcname.startsWith("sent items") && (lcname.length() == 10 || lcname.charAt(10) == '/'))
                return false;
        }
    }
    try {
        // you cannot access your own mailbox via the /home/username mechanism
        if (mOwner != null && belongsTo(mCredentials))
            return false;
        getFolder();
        if (mFolder instanceof Folder) {
            Folder folder = (Folder) mFolder;
            // hide all system folders and the user root folder
            if (folder.getId() == Mailbox.ID_FOLDER_USER_ROOT && mScope != Scope.REFERENCE) {
                return false;
            }
            // hide spam folder unless anti-spam feature is enabled.
            if (folder.getId() == Mailbox.ID_FOLDER_SPAM && !getOwnerAccount().isFeatureAntispamEnabled()) {
                return false;
            }
            boolean isMailFolders = Provisioning.getInstance().getLocalServer().isImapDisplayMailFoldersOnly();
            if (!isVisible(folder.getDefaultView(), isMailFolders)) {
                return false;
            }
            // hide subfolders of trashed mountpoints
            if (mReferent != this && folder.inTrash() && !((Mountpoint) folder).getTarget().equals(mReferent.asItemId())) {
                return false;
            }
            // hide other users' mountpoints and mountpoints that point to the same mailbox
            if (folder instanceof Mountpoint && mReferent == this && mScope != Scope.UNPARSED) {
                return false;
            }
            // search folder visibility depends on an account setting
            if (folder instanceof SearchFolder) {
                return ((SearchFolder) folder).isImapVisible() && ImapFolder.getTypeConstraint((SearchFolder) folder).size() > 0;
            }
        } else {
            ZFolder zfolder = (ZFolder) mFolder;
            int folderId = asItemId().getId();
            // the mailbox root folder is not visible
            if (folderId == Mailbox.ID_FOLDER_USER_ROOT && mScope != Scope.REFERENCE) {
                return false;
            }
            // hide spam folder unless anti-spam feature is enabled.
            if (folderId == Mailbox.ID_FOLDER_SPAM && !getOwnerAccount().isFeatureAntispamEnabled()) {
                return false;
            }
            // calendars, briefcases, etc. are not surfaced in IMAP
            ZFolder.View view = zfolder.getDefaultView();
            if (view == ZFolder.View.appointment || view == ZFolder.View.task || view == ZFolder.View.wiki || view == ZFolder.View.document) {
                return false;
            }
            // hide other users' mountpoints and mountpoints that point to the same mailbox
            if (zfolder instanceof ZMountpoint && mReferent == this && mScope != Scope.UNPARSED) {
                return false;
            }
            // hide all remote searchfolders
            if (zfolder instanceof ZSearchFolder) {
                return false;
            }
        }
    } catch (NoSuchItemException ignore) {
    // 6.3.9.  LSUB Command
    //   The server MUST NOT unilaterally remove an existing mailbox name from the subscription list even if a
    //   mailbox by that name no longer exists.
    } catch (AccountServiceException ase) {
        if (!AccountServiceException.NO_SUCH_ACCOUNT.equals(ase.getCode())) {
            throw ase;
        }
    } catch (ServiceException se) {
        if (ServiceException.PERM_DENIED.equals(se.getCode())) {
            // Path probably OK.  For subscriptions, don't disallow path for possibly temporary permissions issue
            return true;
        }
        throw se;
    }
    return mReferent == this ? true : mReferent.isValidImapPath();
}
Also used : ZMountpoint(com.zimbra.client.ZMountpoint) ZSearchFolder(com.zimbra.client.ZSearchFolder) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) ZSearchFolder(com.zimbra.client.ZSearchFolder) ZFolder(com.zimbra.client.ZFolder) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) Folder(com.zimbra.cs.mailbox.Folder) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ZMountpoint(com.zimbra.client.ZMountpoint) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZFolder(com.zimbra.client.ZFolder) ZMountpoint(com.zimbra.client.ZMountpoint) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) ZSearchFolder(com.zimbra.client.ZSearchFolder)

Example 23 with Mountpoint

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

the class TestTags method cleanUp.

private void cleanUp() throws Exception {
    Set<Integer> messageIds = search("subject:\"Test tags\"", MailItem.Type.MESSAGE);
    for (int id : messageIds) {
        mMbox.delete(null, id, MailItem.Type.MESSAGE);
    }
    List<Tag> tags = mMbox.getTagList(null);
    if (tags == null) {
        return;
    }
    for (Tag tag : tags) {
        if (tag.getName().startsWith(TAG_PREFIX)) {
            mMbox.delete(null, tag.getId(), tag.getType());
        }
    }
    if (mountpoint != null) {
        try {
            mMbox.delete(null, mountpoint.getId(), MailItem.Type.MOUNTPOINT);
        } catch (Exception e) {
        }
        mountpoint = null;
    }
    try {
        TestUtil.deleteAccount(remoteUser);
    } catch (Exception e) {
    }
}
Also used : Tag(com.zimbra.cs.mailbox.Tag) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException)

Example 24 with Mountpoint

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

the class DavServlet method isProxyRequest.

private boolean isProxyRequest(DavContext ctxt, DavMethod m) throws IOException, DavException, ServiceException, HttpException {
    Provisioning prov = Provisioning.getInstance();
    ItemId target = null;
    String extraPath = null;
    String requestPath = ctxt.getPath();
    try {
        if (ctxt.getUser() == null) {
            return false;
        }
        if (requestPath == null || requestPath.length() < 2) {
            return false;
        }
        Account account = prov.getAccountByName(ctxt.getUser());
        if (account == null) {
            return false;
        }
        Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
        Pair<Folder, String> match = mbox.getFolderByPathLongestMatch(ctxt.getOperationContext(), Mailbox.ID_FOLDER_USER_ROOT, requestPath);
        Folder targetFolder = match.getFirst();
        if (!(targetFolder instanceof Mountpoint)) {
            return false;
        }
        Mountpoint mp = (Mountpoint) targetFolder;
        target = new ItemId(mp.getOwnerId(), mp.getRemoteId());
        extraPath = match.getSecond();
    } catch (ServiceException e) {
        ZimbraLog.dav.debug("can't get path", e);
        return false;
    }
    // we also don't proxy DELETE on a mountpoint.
    if (extraPath == null && (m.getName().equals(PropFind.PROPFIND) && ctxt.getDepth() == DavContext.Depth.zero || m.getName().equals(PropPatch.PROPPATCH) || m.getName().equals(Delete.DELETE))) {
        return false;
    }
    String prefix = ctxt.getPath();
    if (extraPath != null) {
        prefix = prefix.substring(0, prefix.indexOf(extraPath));
    }
    prefix = HttpUtil.urlEscape(DAV_PATH + "/" + ctxt.getUser() + prefix);
    if (!prefix.endsWith("/")) {
        prefix += "/";
    }
    // make sure the target account exists.
    Account acct = prov.getAccountById(target.getAccountId());
    if (acct == null) {
        return false;
    }
    Server server = prov.getServer(acct);
    if (server == null) {
        return false;
    }
    // get the path to the target mail item
    AuthToken authToken = AuthProvider.getAuthToken(ctxt.getAuthAccount());
    ZMailbox.Options zoptions = new ZMailbox.Options(authToken.toZAuthToken(), AccountUtil.getSoapUri(acct));
    zoptions.setNoSession(true);
    zoptions.setTargetAccount(target.getAccountId());
    zoptions.setTargetAccountBy(Key.AccountBy.id);
    ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
    ZFolder f = zmbx.getFolderById("" + target.toString());
    if (f == null) {
        return false;
    }
    String path = f.getPath();
    String newPrefix = HttpUtil.urlEscape(DAV_PATH + "/" + acct.getName() + f.getPath());
    if (ctxt.hasRequestMessage()) {
        // replace the path in <href> of the request with the path to the target mail item.
        Document req = ctxt.getRequestMessage();
        for (Object hrefObj : req.getRootElement().elements(DavElements.E_HREF)) {
            if (!(hrefObj instanceof Element)) {
                continue;
            }
            Element href = (Element) hrefObj;
            String v = href.getText();
            // prefix matching is not as straightforward as we have jetty redirect from /dav to /home/dav.
            href.setText(newPrefix + "/" + v.substring(v.lastIndexOf('/') + 1));
        }
    }
    // build proxy request
    String url = getProxyUrl(ctxt.getRequest(), server, DAV_PATH) + HttpUtil.urlEscape("/" + acct.getName() + path + "/" + (extraPath == null ? "" : extraPath));
    BasicCookieStore state = new BasicCookieStore();
    authToken.encode(state, false, server.getAttr(Provisioning.A_zimbraServiceHostname));
    HttpClientBuilder clientBuilder = ZimbraHttpConnectionManager.getInternalHttpConnMgr().newHttpClient();
    clientBuilder.setDefaultCookieStore(state);
    HttpClient client = clientBuilder.build();
    HttpRequestBase method = m.toHttpMethod(ctxt, url);
    method.addHeader(new BasicHeader(DavProtocol.HEADER_USER_AGENT, "Zimbra-DAV/" + BuildInfo.VERSION));
    if (ZimbraLog.dav.isDebugEnabled()) {
        Enumeration<String> headers = ctxt.getRequest().getHeaderNames();
        while (headers.hasMoreElements()) {
            String hdr = headers.nextElement();
            if (!PROXY_REQUEST_HEADERS.contains(hdr) && !IGNORABLE_PROXY_REQUEST_HEADERS.contains(hdr)) {
                ZimbraLog.dav.debug("Dropping header(s) with name [%s] from proxy request (not in PROXY_REQUEST_HEADERS)", hdr);
            }
        }
    }
    for (String h : PROXY_REQUEST_HEADERS) {
        String hval = ctxt.getRequest().getHeader(h);
        if (hval != null) {
            method.addHeader(h, hval);
        }
    }
    HttpResponse httpResponse = HttpClientUtil.executeMethod(client, method);
    int statusCode = httpResponse.getStatusLine().getStatusCode();
    if (ZimbraLog.dav.isDebugEnabled()) {
        for (Header hval : httpResponse.getAllHeaders()) {
            String hdrName = hval.getName();
            if (!PROXY_RESPONSE_HEADERS.contains(hdrName) && !IGNORABLE_PROXY_RESPONSE_HEADERS.contains(hdrName)) {
                ZimbraLog.dav.debug("Dropping header [%s] from proxy response (not in PROXY_RESPONSE_HEADERS)", hval);
            }
        }
    }
    for (String h : PROXY_RESPONSE_HEADERS) {
        for (Header hval : httpResponse.getHeaders(h)) {
            String hdrValue = hval.getValue();
            if (DavProtocol.HEADER_LOCATION.equals(h)) {
                int pfxLastSlashPos = prefix.lastIndexOf('/');
                int lastSlashPos = hdrValue.lastIndexOf('/');
                if ((lastSlashPos > 0) && (pfxLastSlashPos > 0)) {
                    hdrValue = prefix.substring(0, pfxLastSlashPos) + hdrValue.substring(lastSlashPos);
                    ZimbraLog.dav.debug("Original [%s] from proxy response new value '%s'", hval, hdrValue);
                }
            }
            ctxt.getResponse().addHeader(h, hdrValue);
        }
    }
    ctxt.getResponse().setStatus(statusCode);
    ctxt.setStatus(statusCode);
    if (httpResponse.getEntity() != null && httpResponse.getEntity().getContent() != null) {
        try (InputStream in = httpResponse.getEntity().getContent()) {
            switch(statusCode) {
                case DavProtocol.STATUS_MULTI_STATUS:
                    // rewrite the <href> element in the response to point to local mountpoint.
                    try {
                        Document response = W3cDomUtil.parseXMLToDom4jDocUsingSecureProcessing(in);
                        Element top = response.getRootElement();
                        for (Object responseObj : top.elements(DavElements.E_RESPONSE)) {
                            if (!(responseObj instanceof Element)) {
                                continue;
                            }
                            Element href = ((Element) responseObj).element(DavElements.E_HREF);
                            String v = href.getText();
                            v = URLDecoder.decode(v);
                            // Bug:106438, because v contains URL encoded value(%40) for '@' the comparison fails
                            if (v.startsWith(newPrefix)) {
                                href.setText(prefix + v.substring(newPrefix.length() + 1));
                            }
                        }
                        if (ZimbraLog.dav.isDebugEnabled()) {
                            ZimbraLog.dav.debug("PROXY RESPONSE:\n%s", new String(DomUtil.getBytes(response), "UTF-8"));
                        }
                        DomUtil.writeDocumentToStream(response, ctxt.getResponse().getOutputStream());
                        ctxt.responseSent();
                    } catch (XmlParseException e) {
                        ZimbraLog.dav.warn("proxy request failed", e);
                        return false;
                    }
                    break;
                default:
                    if (in != null) {
                        ByteUtil.copy(in, true, ctxt.getResponse().getOutputStream(), false);
                    }
                    ctxt.responseSent();
                    break;
            }
            return true;
        }
    }
    return true;
}
Also used : Account(com.zimbra.cs.account.Account) Options(com.zimbra.cs.dav.service.method.Options) HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) Server(com.zimbra.cs.account.Server) Element(org.dom4j.Element) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder) Folder(com.zimbra.cs.mailbox.Folder) ZFolder(com.zimbra.client.ZFolder) Document(org.dom4j.Document) ItemId(com.zimbra.cs.service.util.ItemId) Provisioning(com.zimbra.cs.account.Provisioning) ZMailbox(com.zimbra.client.ZMailbox) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ZFolder(com.zimbra.client.ZFolder) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) GZIPInputStream(java.util.zip.GZIPInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) HttpResponse(org.apache.http.HttpResponse) XmlParseException(com.zimbra.common.soap.XmlParseException) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) BasicCookieStore(org.apache.http.impl.client.BasicCookieStore) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Header(org.apache.http.Header) BasicHeader(org.apache.http.message.BasicHeader) HttpClient(org.apache.http.client.HttpClient) AuthToken(com.zimbra.cs.account.AuthToken) BasicHeader(org.apache.http.message.BasicHeader)

Example 25 with Mountpoint

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

the class AbstractProxyProperty method getMountpoints.

protected ArrayList<Pair<Mountpoint, ZFolder>> getMountpoints(DavContext ctxt) {
    ArrayList<Pair<Mountpoint, ZFolder>> mps = new ArrayList<Pair<Mountpoint, ZFolder>>();
    try {
        Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
        for (MailItem item : mbox.getItemList(ctxt.getOperationContext(), MailItem.Type.MOUNTPOINT)) {
            Mountpoint mp = (Mountpoint) item;
            // skip non-calendar mountpoints
            if (mp.getDefaultView() != MailItem.Type.APPOINTMENT && mp.getDefaultView() != MailItem.Type.TASK) {
                continue;
            }
            ZAuthToken zat = AuthProvider.getAuthToken(ctxt.getAuthAccount()).toZAuthToken();
            ZMailbox zmbx = RemoteCollection.getRemoteMailbox(zat, mp.getOwnerId());
            // skip dangling mountpoints
            if (zmbx == null) {
                continue;
            }
            try {
                ZFolder folder = zmbx.getFolderById(mp.getTarget().toString(account));
                // skip dangling mountpoints
                if (folder == null) {
                    continue;
                }
                mps.add(new Pair<Mountpoint, ZFolder>(mp, folder));
            } catch (ServiceException se) {
                ZimbraLog.dav.warn("can't get remote folder", se);
            }
        }
    } catch (ServiceException se) {
        ZimbraLog.dav.warn("can't get mailbox", se);
    }
    return mps;
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) ZMailbox(com.zimbra.client.ZMailbox) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ServiceException(com.zimbra.common.service.ServiceException) ArrayList(java.util.ArrayList) ZFolder(com.zimbra.client.ZFolder) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) ZAuthToken(com.zimbra.common.auth.ZAuthToken) Pair(com.zimbra.common.util.Pair)

Aggregations

Mountpoint (com.zimbra.cs.mailbox.Mountpoint)43 Folder (com.zimbra.cs.mailbox.Folder)30 ServiceException (com.zimbra.common.service.ServiceException)23 Mailbox (com.zimbra.cs.mailbox.Mailbox)18 Account (com.zimbra.cs.account.Account)17 MailItem (com.zimbra.cs.mailbox.MailItem)14 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)14 ZFolder (com.zimbra.client.ZFolder)11 ItemId (com.zimbra.cs.service.util.ItemId)11 ZMailbox (com.zimbra.client.ZMailbox)8 Element (com.zimbra.common.soap.Element)8 OperationContext (com.zimbra.cs.mailbox.OperationContext)8 IOException (java.io.IOException)8 HashMap (java.util.HashMap)8 Provisioning (com.zimbra.cs.account.Provisioning)6 SearchFolder (com.zimbra.cs.mailbox.SearchFolder)6 ZMountpoint (com.zimbra.client.ZMountpoint)5 Pair (com.zimbra.common.util.Pair)5 NoSuchItemException (com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)5 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)5