Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZCS-15683 - ZRFE-830 Implementation #1653

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 70 additions & 1 deletion store/src/java/com/zimbra/cs/service/mail/WaitSetRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import com.zimbra.common.mailbox.ACLGrant;
import com.zimbra.cs.index.SortBy;
import com.zimbra.cs.mailbox.Folder;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;

Expand Down Expand Up @@ -358,7 +363,9 @@ protected static List<WaitSetAccount> parseAddUpdateAccounts(ZimbraSoapContext z
id = accountDetail.getId();
}

WaitSetMgr.checkRightForAdditionalAccount(id, zsc);
if (!checkSharedFolderPermission(zsc, accountDetail, id)) {
WaitSetMgr.checkRightForAdditionalAccount(id, zsc);
}

String tokenStr = accountDetail.getToken();
SyncToken token = tokenStr != null ? new SyncToken(tokenStr) : null;
Expand All @@ -370,6 +377,68 @@ protected static List<WaitSetAccount> parseAddUpdateAccounts(ZimbraSoapContext z
return toRet;
}

private static boolean checkSharedFolderPermission(ZimbraSoapContext zsc, WaitSetAddSpec accountDetail, String id) throws ServiceException {
String authAccountId = zsc.getRequestedAccountId();
String sFolderInterests = accountDetail.getFolderInterests();
if (sFolderInterests != null && !authAccountId.equals(id)) {
List<Integer> folderInterests = convertToIntegerList(sFolderInterests);
Account account = getAccountById(id);
Mailbox mailbox = MailboxManager.getInstance().getMailboxByAccount(account);
List<Folder> folders = mailbox.getFolderList(null, SortBy.NONE);
return checkPermissions(authAccountId, folderInterests, folders);
}
return false;
}

private static List<Integer> convertToIntegerList(String folderInterests) {
return Splitter.on(',').trimResults().splitToList(folderInterests).stream()
.map(Integer::parseInt)
.collect(Collectors.toList());
}

private static Account getAccountById(String id) throws ServiceException {
Provisioning prov = Provisioning.getInstance();
Account account = prov.getAccountById(id);
if (account == null) {
throw ServiceException.INVALID_REQUEST("Account not found", null);
}
return account;
}

private static boolean checkPermissions(String authAccountId, List<Integer> folderInterests, List<Folder> folders) {
ZimbraLog.soap.trace("Checking folder permissions");
// Create a map to store folder IDs and their corresponding ACL grants
Map<Integer, List<ACLGrant>> folderAclMap = new HashMap<>();
for (Folder folder : folders) {
folderAclMap.put(folder.getId(), folder.getACLGrants());
}

// Iterate over the folder interests
for (Integer folderInterest : folderInterests) {
List<ACLGrant> aclGrants = folderAclMap.get(folderInterest);
if (aclGrants == null) {
return false; // Folder not found
}

boolean hasRequiredPermissions = false;
for (ACLGrant aclGrant : aclGrants) {
if (authAccountId.equals(aclGrant.getGranteeId())) {
String permissions = aclGrant.getPermissions();
if (permissions.matches(".*[rwiax].*")) {
hasRequiredPermissions = true;
break;
}
}
}

if (!hasRequiredPermissions) {
return false; // Required permissions not found
}
}

return true; // All folders have the required permissions
}

private static List<String> parseRemoveAccounts(ZimbraSoapContext zsc, List<Id> ids)
throws ServiceException {
List<String> remove = Lists.newArrayList();
Expand Down