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());
}
}
}
}
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();
}
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) {
}
}
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;
}
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;
}
Aggregations