use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class FolderAction method revokeOrphanGrants.
private void revokeOrphanGrants(OperationContext octxt, Mailbox mbox, ItemId iid, String granteeId, byte gtype) throws ServiceException {
// check if the grantee still exists
SearchDirectoryOptions opts = new SearchDirectoryOptions();
if (gtype == ACL.GRANTEE_USER) {
opts.addType(SearchDirectoryOptions.ObjectType.accounts);
opts.addType(SearchDirectoryOptions.ObjectType.resources);
} else if (gtype == ACL.GRANTEE_GROUP) {
opts.addType(SearchDirectoryOptions.ObjectType.distributionlists);
} else if (gtype == ACL.GRANTEE_COS) {
opts.addType(SearchDirectoryOptions.ObjectType.coses);
} else if (gtype == ACL.GRANTEE_DOMAIN) {
opts.addType(SearchDirectoryOptions.ObjectType.domains);
} else {
throw ServiceException.INVALID_REQUEST("invalid grantee type for revokeOrphanGrants", null);
}
String query = "(" + Provisioning.A_zimbraId + "=" + granteeId + ")";
opts.setFilterString(FilterId.SEARCH_GRANTEE, query);
// search the grantee on LDAP master
opts.setOnMaster(true);
List<NamedEntry> entries = Provisioning.getInstance().searchDirectory(opts);
if (entries.size() != 0) {
throw ServiceException.INVALID_REQUEST("grantee " + granteeId + " exists", null);
}
// the grantee indeed does not exist, revoke all grants granted to the grantee
// in this folder and all subfolders
FolderNode rootNode = mbox.getFolderTree(octxt, iid, true);
revokeOrphanGrants(octxt, mbox, rootNode, granteeId, gtype);
}
use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class Sync method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
SyncRequest syncRequest = JaxbUtil.elementToJaxb(request);
String token = syncRequest.getToken();
Element response = zsc.createElement(MailConstants.SYNC_RESPONSE);
response.addAttribute(MailConstants.A_CHANGE_DATE, System.currentTimeMillis() / 1000);
// the sync token is of the form "last fully synced change id" (e.g. "32425") or
// last fully synced change id-last item synced in next change id" (e.g. "32425-99213") or
// last fully synced change id-last item synced in next change id and last fully synced delete change id" (e.g. "32425-99213:d1231232") or
// last fully synced change id-last item synced in next change id and
// last fully synced delete id-last item synced in next delete id (e.g. "32425-99213:d12312-82134")
SyncToken syncToken = null;
int tokenInt = 0;
if (!StringUtil.isNullOrEmpty(token)) {
syncToken = new SyncToken(token);
tokenInt = syncToken.getChangeId();
}
if (syncToken == null) {
syncToken = new SyncToken(0);
}
int deleleLimit = syncRequest.getDeleteLimit();
int changeLimit = syncRequest.getChangeLimit();
// server can apply delete pagination through debugconfig/localconfig.
if (deleleLimit <= 0) {
deleleLimit = DebugConfig.syncMaximumDeleteCount;
}
// client specify more than DebugConfig.syncMaximumChangeCount It will use DebugConfig.syncMaximumChangeCount
if (changeLimit <= 0 || changeLimit > DebugConfig.syncMaximumChangeCount) {
changeLimit = DebugConfig.syncMaximumChangeCount;
}
boolean initialSync = tokenInt <= 0;
// permit the caller to restrict initial sync only to calendar items with a recurrence after a given date
long calendarStart = (syncRequest.getCalendarCutoff() != null) ? syncRequest.getCalendarCutoff() : -1;
int messageSyncStart = (syncRequest.getMsgCutoff() != null) ? syncRequest.getMsgCutoff() : -1;
// if the sync is constrained to a folder subset, we need to first figure out what can be seen
Folder root = null;
ItemId iidFolder = null;
try {
iidFolder = new ItemId(request.getAttribute(MailConstants.A_FOLDER, DEFAULT_FOLDER_ID + ""), zsc);
OperationContext octxtOwner = new OperationContext(mbox);
root = mbox.getFolderById(octxtOwner, iidFolder.getId());
} catch (MailServiceException.NoSuchItemException nsie) {
}
Set<Folder> visible = octxt.isDelegatedRequest(mbox) ? mbox.getVisibleFolders(octxt) : null;
FolderNode rootNode = null;
if (root == null || iidFolder == null) {
// resolve grantee names of all ACLs on the mailbox
rootNode = mbox.getFolderTree(octxt, null, true);
} else {
// resolve grantee names of all ACLs on all sub-folders of the requested folder
rootNode = mbox.getFolderTree(octxt, iidFolder, true);
}
OperationContextData.addGranteeNames(octxt, rootNode);
// actually perform the sync
mbox.lock.lock();
try {
mbox.beginTrackingSync();
if (initialSync) {
response.addAttribute(MailConstants.A_TOKEN, mbox.getLastChangeID());
response.addAttribute(MailConstants.A_SIZE, mbox.getSize());
boolean anyFolders = folderSync(response, octxt, ifmt, mbox, root, visible, calendarStart, messageSyncStart, SyncPhase.INITIAL);
// if no folders are visible, add an empty "<folder/>" as a hint
if (!anyFolders) {
response.addElement(MailConstants.E_FOLDER);
}
} else {
boolean typedDeletes = request.getAttributeBool(MailConstants.A_TYPED_DELETES, false);
String newToken = deltaSync(response, octxt, ifmt, mbox, syncToken, deleleLimit, changeLimit, typedDeletes, root, visible, messageSyncStart);
response.addAttribute(MailConstants.A_TOKEN, newToken);
}
} finally {
mbox.lock.release();
}
return response;
}
use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class SoapSession method putRefresh.
/** Serializes basic folder/tag structure to a SOAP response header.
* <p>
* Adds a <refresh> block to the existing <context> element.
* This <refresh> block contains the basic folder, tag, and mailbox
* size information needed to display and update the web UI's overview
* pane. The <refresh> block is sent when a new session is created.
*
* This API implicitly clears all cached notifications and therefore
* should only been used during session creation.
* @param ctxt An existing SOAP header <context> element
* @param zsc The SOAP request's encapsulated context */
public void putRefresh(Element ctxt, ZimbraSoapContext zsc) throws ServiceException {
Mailbox mbox = mailbox;
if (mbox == null) {
return;
}
synchronized (sentChanges) {
for (QueuedNotifications ntfn : sentChanges) {
ntfn.clearMailboxChanges();
}
}
Element eRefresh = ctxt.addUniqueElement(ZimbraNamespace.E_REFRESH);
eRefresh.addAttribute(AccountConstants.E_VERSION, BuildInfo.FULL_VERSION, Element.Disposition.CONTENT);
OperationContext octxt = DocumentHandler.getOperationContext(zsc, this);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
// dump current mailbox status (currently just size)
ToXML.encodeMailbox(eRefresh, octxt, mbox);
// dump all tags under a single <tags> parent
List<Tag> tags = mbox.getTagList(octxt);
if (tags != null && tags.size() > 0) {
Element eTags = eRefresh.addUniqueElement(ZimbraNamespace.E_TAGS);
for (Tag tag : tags) {
if (tag != null && !(tag instanceof Flag)) {
ToXML.encodeTag(eTags, ifmt, octxt, tag);
}
}
}
// first, get the user's folder hierarchy
FolderNode root = mbox.getFolderTree(octxt, null, false);
OperationContextData.setNeedGranteeName(octxt, false);
GetFolder.encodeFolderNode(root, eRefresh, ifmt, octxt);
// The Boolean of the Pair indicates whether the mountpoint is found to be broken
Map<ItemId, Pair<Boolean, Element>> mountpoints = new HashMap<ItemId, Pair<Boolean, Element>>();
// for mountpoints pointing to this host, get the serialized folder subhierarchy
expandLocalMountpoints(octxt, root, eRefresh.getFactory(), mountpoints);
// for mountpoints pointing to other hosts, get the folder structure from the remote server
expandRemoteMountpoints(octxt, zsc, mountpoints);
// graft in subfolder trees from the other user's mailbox, making sure that mountpoints reflect the counts (etc.) of the target folder
if (!mountpoints.isEmpty()) {
transferMountpointContents(eRefresh.getOptionalElement(MailConstants.E_FOLDER), octxt, mountpoints);
}
}
Aggregations