use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method doLSUB.
private boolean doLSUB(String tag, String referenceName, String mailboxName) throws ImapException, IOException {
checkCommandThrottle(new LsubCommand(referenceName, mailboxName));
if (!checkState(tag, State.AUTHENTICATED)) {
return true;
}
Pair<String, Pattern> resolved = resolvePath(referenceName, mailboxName);
String resolvedPath = resolved.getFirst();
Pattern pattern = resolved.getSecond();
Pattern childPattern = Pattern.compile(pattern.pattern() + "/.*");
ImapPath patternPath = new ImapPath(resolvedPath, credentials, ImapPath.Scope.UNPARSED);
List<String> subscriptions = null;
try {
// you cannot access your own mailbox via the /home/username mechanism
String owner = patternPath.getOwner();
if (owner == null || owner.indexOf('*') != -1 || owner.indexOf('%') != -1 || !patternPath.belongsTo(credentials)) {
Map<SubscribedImapPath, Boolean> hits = new HashMap<SubscribedImapPath, Boolean>();
if (owner == null) {
MailboxStore mbox = credentials.getMailbox();
boolean isMailFolders = Provisioning.getInstance().getLocalServer().isImapDisplayMailFoldersOnly();
for (FolderStore folder : mbox.getUserRootSubfolderHierarchy(getContext())) {
// chat has item type of message.hence ignoring the chat folder by name.
if ((isMailFolders) && (folder.isChatsFolder() || (folder.getName().equals("Chats")))) {
continue;
}
String fAcctId = folder.getFolderItemIdentifier().accountId;
if ((fAcctId != null) && !fAcctId.equals(credentials.getAccountId())) {
// ignore imapSubscribed flag on remote folders - they apply to the remote acct
continue;
}
if (folder.isIMAPSubscribed()) {
checkSubscription(new SubscribedImapPath(new ImapPath(null, folder, credentials)), pattern, childPattern, hits);
}
}
}
Set<String> remoteSubscriptions = credentials.listSubscriptions();
if (remoteSubscriptions != null && !remoteSubscriptions.isEmpty()) {
for (String sub : remoteSubscriptions) {
ImapPath subscribed = new ImapPath(sub, credentials);
if ((owner == null) == (subscribed.getOwner() == null)) {
checkSubscription(new SubscribedImapPath(subscribed), pattern, childPattern, hits);
}
}
}
subscriptions = new ArrayList<String>(hits.size());
for (Entry<SubscribedImapPath, Boolean> hit : hits.entrySet()) {
String attrs = hit.getValue() ? "" : "\\NoSelect";
subscriptions.add("LSUB (" + attrs + ") \"/\" " + hit.getKey().asUtf7String());
}
}
} catch (ServiceException e) {
ZimbraLog.imap.warn("LSUB failed", e);
sendNO(tag, "LSUB failed");
return canContinue(e);
}
if (subscriptions != null) {
for (String sub : subscriptions) {
sendUntagged(sub);
}
}
sendNotifications(true, false);
sendOK(tag, "LSUB completed");
return true;
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method status.
private String status(ImapPath path, byte status) throws ImapException, ServiceException {
StringBuilder data = new StringBuilder("STATUS ").append(path.asUtf7String()).append(" (");
int empty = data.length();
int messages;
int recent;
int uidnext;
int uvv;
int unread;
int modseq;
MailboxStore mboxStore = path.getOwnerMailbox();
if (mboxStore != null) {
FolderStore folder = path.getFolder();
if (folder == null) {
throw MailServiceException.NO_SUCH_FOLDER(path.asImapPath());
}
ImapFolder i4folder = getSelectedFolder();
messages = folder.getImapMessageCount();
if ((status & StatusDataItemNames.STATUS_RECENT) == 0) {
recent = -1;
} else if (messages == 0) {
recent = 0;
} else if (i4folder != null && i4folder.getItemIdentifier().sameAndFullyDefined(folder.getFolderItemIdentifier())) {
recent = i4folder.getRecentCount();
} else if (i4folder != null && path.isEquivalent(i4folder.getPath())) {
recent = i4folder.getRecentCount();
} else {
ImapMailboxStore imapStore = path.getOwnerImapMailboxStore();
recent = imapStore.getImapRECENT(this.getContext(), folder);
}
uidnext = folder.isSearchFolder() ? -1 : folder.getImapUIDNEXT();
uvv = folder.getUIDValidity();
unread = folder.getImapUnreadCount();
modseq = folder.isSearchFolder() ? 0 : folder.getImapMODSEQ();
ZimbraLog.imap.debug("STATUS for %s. unread %d, recent %d, count %d", folder.getPath(), unread, recent, messages);
} else {
throw AccountServiceException.NO_SUCH_ACCOUNT(path.getOwner());
}
if (messages >= 0 && (status & StatusDataItemNames.STATUS_MESSAGES) != 0) {
data.append(data.length() != empty ? " " : "").append("MESSAGES ").append(messages);
}
if (recent >= 0 && (status & StatusDataItemNames.STATUS_RECENT) != 0) {
data.append(data.length() != empty ? " " : "").append("RECENT ").append(recent);
}
// note: we're not supporting UIDNEXT for search folders; see the comments in selectFolder()
if (uidnext > 0 && (status & StatusDataItemNames.STATUS_UIDNEXT) != 0) {
data.append(data.length() != empty ? " " : "").append("UIDNEXT ").append(uidnext);
}
if (uvv > 0 && (status & StatusDataItemNames.STATUS_UIDVALIDITY) != 0) {
data.append(data.length() != empty ? " " : "").append("UIDVALIDITY ").append(uvv);
}
if (unread >= 0 && (status & StatusDataItemNames.STATUS_UNSEEN) != 0) {
data.append(data.length() != empty ? " " : "").append("UNSEEN ").append(unread);
}
if (modseq >= 0 && (status & StatusDataItemNames.STATUS_HIGHESTMODSEQ) != 0) {
data.append(data.length() != empty ? " " : "").append("HIGHESTMODSEQ ").append(modseq);
}
return data.append(')').toString();
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method doDELETEACL.
private boolean doDELETEACL(String tag, ImapPath path, String principal) throws IOException {
if (!checkState(tag, State.AUTHENTICATED)) {
return true;
}
try {
// make sure the requester has sufficient permissions to make the request
if ((path.getFolderRights() & ACL.RIGHT_ADMIN) == 0) {
ZimbraLog.imap.info("DELETEACL failed: user does not have admin access: " + path);
sendNO(tag, "DELETEACL failed");
return true;
}
// figure out whose permissions are being revoked
GranteeIdAndType grantee = getPrincipalGranteeInfo(principal);
if (grantee.id == null) {
ZimbraLog.imap.info("DELETEACL failed: cannot resolve principal: %s", principal);
sendNO(tag, "DELETEACL failed");
return true;
}
// and revoke the permissions appropriately
MailboxStore mboxStore = path.getOwnerMailbox();
if (mboxStore != null) {
FolderStore folder = path.getFolder();
if (!folder.getACLGrants().isEmpty()) {
mboxStore.modifyFolderRevokeGrant(getContext(), folder.getFolderIdAsString(), grantee.id);
if (grantee.id == GuestAccount.GUID_AUTHUSER) {
mboxStore.modifyFolderRevokeGrant(getContext(), folder.getFolderIdAsString(), GuestAccount.GUID_PUBLIC);
}
}
}
} catch (ServiceException e) {
if (e.getCode().equals(ServiceException.PERM_DENIED)) {
ZimbraLog.imap.info("DELETEACL failed: permission denied on folder: %s", path);
} else if (e.getCode().equals(MailServiceException.NO_SUCH_FOLDER)) {
ZimbraLog.imap.info("DELETEACL failed: no such folder: %s", path);
} else if (e.getCode().equals(AccountServiceException.NO_SUCH_ACCOUNT)) {
ZimbraLog.imap.info("DELETEACL failed: no such account: %s", principal);
} else {
ZimbraLog.imap.warn("DELETEACL failed", e);
}
sendNO(tag, "DELETEACL failed");
return true;
}
sendNotifications(true, false);
sendOK(tag, "DELETEACL completed");
return true;
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method sendNotifications.
public void sendNotifications(boolean notifyExpunges, boolean flush) throws IOException {
ImapProxy proxy = imapProxy;
if (proxy != null) {
proxy.fetchNotifications();
return;
}
ImapListener i4selected = getCurrentImapListener();
if (i4selected == null || !i4selected.hasNotifications()) {
return;
}
MailboxStore mbox = i4selected.getMailbox();
if (mbox == null) {
return;
}
ImapFolder i4folder;
try {
i4folder = i4selected.getImapFolder();
} catch (ImapSessionClosedException e) {
return;
}
List<String> notifications = new ArrayList<String>();
// XXX: is this the right thing to synchronize on?
mbox.lock(true);
try {
if (i4folder.areTagsDirty()) {
notifications.add("FLAGS (" + StringUtil.join(" ", i4folder.getFlagList(false)) + ')');
i4folder.setTagsDirty(false);
}
int oldRecent = i4folder.getRecentCount();
boolean removed = false;
boolean received = i4folder.checkpointSize();
if (notifyExpunges) {
List<Integer> expunged = i4folder.collapseExpunged(sessionActivated(ImapExtension.QRESYNC));
removed = !expunged.isEmpty();
if (removed) {
if (sessionActivated(ImapExtension.QRESYNC)) {
notifications.add("VANISHED " + ImapFolder.encodeSubsequence(expunged));
} else {
for (Integer index : expunged) {
notifications.add(index + " EXPUNGE");
}
}
}
}
i4folder.checkpointSize();
// notify of any message flag changes
boolean sendModseq = sessionActivated(ImapExtension.CONDSTORE);
for (Iterator<ImapFolder.DirtyMessage> it = i4folder.dirtyIterator(); it.hasNext(); ) {
ImapFolder.DirtyMessage dirty = it.next();
if (dirty.i4msg.isAdded()) {
dirty.i4msg.setAdded(false);
} else {
notifications.add(dirty.i4msg.sequence + " FETCH (" + dirty.i4msg.getFlags(i4folder) + (sendModseq && dirty.modseq > 0 ? " MODSEQ (" + dirty.modseq + ')' : "") + ')');
}
}
i4folder.clearDirty();
if (received || removed) {
notifications.add(i4folder.getSize() + " EXISTS");
}
if (received || oldRecent != i4folder.getRecentCount()) {
notifications.add(i4folder.getRecentCount() + " RECENT");
}
} finally {
mbox.unlock();
}
// no I/O while the Mailbox is locked...
for (String ntfn : notifications) {
sendUntagged(ntfn);
}
if (flush) {
output.flush();
}
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method doCREATE.
private boolean doCREATE(String tag, ImapPath path) throws IOException, ImapThrottledException {
checkCommandThrottle(new CreateCommand(path));
if (!checkState(tag, State.AUTHENTICATED)) {
return true;
}
if (!path.isCreatable()) {
ZimbraLog.imap.info("CREATE failed: hidden folder or parent: " + path);
sendNO(tag, "CREATE failed");
return true;
}
try {
MailboxStore mbox = path.getOwnerMailbox();
if (mbox != null) {
mbox.createFolderForMsgs(getContext(), path.asResolvedPath());
} else {
throw AccountServiceException.NO_SUCH_ACCOUNT(path.getOwner());
}
} catch (ServiceException e) {
String cause = "CREATE failed";
if (e.getCode().equals(MailServiceException.CANNOT_CONTAIN)) {
cause += ": superior mailbox has \\Noinferiors set";
} else if (e.getCode().equals(MailServiceException.ALREADY_EXISTS)) {
cause += ": mailbox already exists";
} else if (e.getCode().equals(MailServiceException.INVALID_NAME)) {
cause += ": invalid mailbox name";
} else if (e.getCode().equals(ServiceException.PERM_DENIED)) {
cause += ": permission denied";
}
if ("CREATE failed".equals(cause)) {
ZimbraLog.imap.warn(cause, e);
} else {
ZimbraLog.imap.info("%s: %s", cause, path);
}
sendNO(tag, cause);
return canContinue(e);
}
sendNotifications(true, false);
sendOK(tag, "CREATE completed");
return true;
}
Aggregations