Skip to content

Commit 11dc540

Browse files
fix: [CO-3221] filter distribution list rights (#932)
* chore: filter out distribution list rights not belonging user * test: rights in GetInfo API
1 parent 8b0f68b commit 11dc540

File tree

2 files changed

+103
-7
lines changed

2 files changed

+103
-7
lines changed

store/src/main/java/com/zimbra/cs/account/accesscontrol/DiscoverUserRights.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package com.zimbra.cs.account.accesscontrol;
77

8+
import java.util.List;
89
import java.util.Map;
910
import java.util.Set;
1011

@@ -66,11 +67,13 @@ Map<Right, Set<Entry>> handle() throws ServiceException {
6667

6768
Map<Right, Set<Entry>> result = Maps.newHashMap();
6869

70+
Set<String> accountDistributionLists = prov.getDistributionLists(acct);
6971
for (SearchGrants.GrantsOnTarget grants : searchResults) {
7072
Entry targetEntry = grants.getTargetEntry();
7173
ZimbraACL acl = grants.getAcl();
7274

73-
for (ZimbraACE ace : acl.getAllACEs()) {
75+
List<ZimbraACE> aces = filterAccountACEs(acl.getAllACEs(), accountDistributionLists);
76+
for (ZimbraACE ace : aces) {
7477
Right right = ace.getRight();
7578

7679
if (rights.contains(right) && !isSameEntry(targetEntry, acct)) {
@@ -83,11 +86,11 @@ Map<Right, Set<Entry>> handle() throws ServiceException {
8386
}
8487
}
8588
TargetType targetTypeForRight = right.getTargetType();
86-
TargetType taregtTypeOfEntry = TargetTypeLookup.getTargetType(targetEntry);
87-
if (targetTypeForRight.equals(taregtTypeOfEntry) ||
88-
(targetTypeForRight==TargetType.account && taregtTypeOfEntry==TargetType.calresource) ||
89-
(targetTypeForRight==TargetType.dl && taregtTypeOfEntry==TargetType.group) ||
90-
(targetTypeForRight==TargetType.group && taregtTypeOfEntry==TargetType.dl)) {
89+
TargetType targetTypeOfEntry = TargetTypeLookup.getTargetType(targetEntry);
90+
if (targetTypeForRight.equals(targetTypeOfEntry) ||
91+
(targetTypeForRight==TargetType.account && targetTypeOfEntry==TargetType.calresource) ||
92+
(targetTypeForRight==TargetType.dl && targetTypeOfEntry==TargetType.group) ||
93+
(targetTypeForRight==TargetType.group && targetTypeOfEntry==TargetType.dl)) {
9194
Set<Entry> entries = result.get(right);
9295
if (entries == null) {
9396
entries = Sets.newHashSet();
@@ -101,6 +104,13 @@ Map<Right, Set<Entry>> handle() throws ServiceException {
101104
return result;
102105
}
103106

107+
private static List<ZimbraACE> filterAccountACEs(List<ZimbraACE> aces, Set<String> accountDistributionLists) {
108+
return aces.stream().filter(ace -> {
109+
boolean isDistributionList = ace.getGranteeType().equals(GranteeType.GT_GROUP);
110+
return !isDistributionList || (accountDistributionLists.contains(ace.getGrantee()));
111+
}).toList();
112+
}
113+
104114
private boolean isSameEntry(Entry entry1, Entry entry2) throws ServiceException {
105115
if ((entry1 instanceof LdapEntry) && (entry2 instanceof LdapEntry)) {
106116
String entry1DN = ((LdapEntry) entry1).getDN();

store/src/test/java/com/zimbra/cs/service/account/GetInfoTest.java

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,24 @@
99
import com.zimbra.cs.account.Account;
1010
import com.zimbra.cs.account.AttributeInfo;
1111
import com.zimbra.cs.account.AttributeManager;
12+
import com.zimbra.cs.account.DistributionList;
1213
import com.zimbra.cs.account.Provisioning;
14+
import com.zimbra.soap.account.message.DistributionListActionRequest;
1315
import com.zimbra.soap.account.message.GetInfoRequest;
16+
17+
import java.util.HashMap;
1418
import java.util.List;
19+
20+
import com.zimbra.soap.account.type.DistributionListAction;
21+
import com.zimbra.soap.account.type.DistributionListGranteeSelector;
22+
import com.zimbra.soap.account.type.DistributionListRightSpec;
23+
import com.zimbra.soap.type.DistributionListBy;
24+
import com.zimbra.soap.type.DistributionListGranteeBy;
25+
import com.zimbra.soap.type.DistributionListSelector;
26+
import com.zimbra.soap.type.GranteeType;
1527
import org.apache.http.HttpStatus;
1628
import org.junit.jupiter.api.Assertions;
17-
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.api.BeforeEach;
1830
import org.junit.jupiter.api.Tag;
1931
import org.junit.jupiter.api.Test;
2032
import org.junit.jupiter.params.ParameterizedTest;
@@ -98,6 +110,11 @@ private SoapResponse getAttributesSection(Account account) throws Exception {
98110
return getSoapClient().executeSoap(account, request);
99111
}
100112

113+
private SoapResponse getResponseIncludingRights(Account account) throws Exception {
114+
final var request = new GetInfoRequest().setRights("sendAs","sendAsDistList","viewFreeBusy","sendOnBehalfOf","sendOnBehalfOfDistList");
115+
return getSoapClient().executeSoap(account, request);
116+
}
117+
101118
@Test
102119
void attributesSectionProvidesAccountStatusAttribute() throws Exception {
103120
final var account =
@@ -125,6 +142,75 @@ void getInfo_shouldReturnAlsoDeprecatedAttributes() throws Exception {
125142
final var body = response.body();
126143
assertTrue(body.contains("<attr name=\"zimbraFeatureMailEnabled\">FALSE</attr>"));
127144
}
145+
146+
@Test
147+
void getInfo_shouldContainRightsSection_sendAsDistList_singleAccount() throws Exception {
148+
final var admin = createAccount().asGlobalAdmin().create();
149+
final var grantee = createAccount().create();
150+
151+
var dl = getProvisioning().createDistributionList("dl@test.com", new HashMap<>());
152+
getSoapClient().executeSoap(admin, createGrantRightsDistributionListActionRequest("sendAsDistList", grantee.getName(), dl));
153+
final var response = getResponseIncludingRights(grantee);
154+
155+
assertEquals(HttpStatus.SC_OK, response.statusCode());
156+
final var body = response.body();
157+
158+
assertTrue(body.contains("""
159+
<rights><targets right="sendAsDistList"><target type="dl"><email addr="dl@test.com"/></target></targets></rights>"""));
160+
}
161+
162+
@Test
163+
void getInfo_shouldContainRightsSection_sendAsDistList_distributionList() throws Exception {
164+
final var admin = createAccount().asGlobalAdmin().create();
165+
final var member = createAccount().create();
166+
167+
var targetDl = getProvisioning().createDistributionList("target-dl@test.com", new HashMap<>());
168+
var granteeDl = getProvisioning().createDistributionList("grantee-dl@test.com", new HashMap<>());
169+
170+
getProvisioning().addGroupMembers(granteeDl, new String[] { member.getName() });
171+
getSoapClient().executeSoap(admin, createGrantRightsDistributionListActionRequest("sendAsDistList", granteeDl.getName(), targetDl));
172+
173+
final var response = getResponseIncludingRights(member);
174+
175+
assertEquals(HttpStatus.SC_OK, response.statusCode());
176+
final var body = response.body();
177+
178+
assertTrue(body.contains("""
179+
<rights><targets right="sendAsDistList"><target type="dl"><email addr="target-dl@test.com"/></target></targets></rights>"""));
180+
}
181+
182+
@Test
183+
void getInfo_shouldContainRightsSection_sendAsDistList_distributionLists() throws Exception {
184+
final var admin = createAccount().asGlobalAdmin().create();
185+
final var member = createAccount().create();
186+
187+
var targetDl = getProvisioning().createDistributionList("target-1-dl@test.com", new HashMap<>());
188+
var granteeDl = getProvisioning().createDistributionList("grantee-1-dl@test.com", new HashMap<>());
189+
var otherGranteeDl = getProvisioning().createDistributionList("other-grantee-1-dl@test.com", new HashMap<>());
190+
191+
getProvisioning().addGroupMembers(granteeDl, new String[] { member.getName() });
192+
193+
getSoapClient().executeSoap(admin, createGrantRightsDistributionListActionRequest("sendAsDistList", granteeDl.getName(), targetDl));
194+
getSoapClient().executeSoap(admin, createGrantRightsDistributionListActionRequest("sendOnBehalfOfDistList", otherGranteeDl.getName(), targetDl));
195+
196+
final var response = getResponseIncludingRights(member);
197+
198+
assertEquals(HttpStatus.SC_OK, response.statusCode());
199+
final var body = response.body();
200+
201+
assertTrue(body.contains("""
202+
<rights><targets right="sendAsDistList"><target type="dl"><email addr="target-1-dl@test.com"/></target></targets></rights>"""));
203+
}
204+
205+
private static DistributionListActionRequest createGrantRightsDistributionListActionRequest(String right, String granteeName, DistributionList targetDl) {
206+
DistributionListAction distributionListAction = new DistributionListAction(DistributionListAction.Operation.grantRights);
207+
DistributionListRightSpec distributionListRightSpec = new DistributionListRightSpec(right);
208+
distributionListRightSpec.addGrantee(new DistributionListGranteeSelector(
209+
GranteeType.email, DistributionListGranteeBy.name, granteeName
210+
));
211+
distributionListAction.setRights(List.of(distributionListRightSpec));
212+
return new DistributionListActionRequest(new DistributionListSelector(DistributionListBy.id, targetDl.getId()), distributionListAction);
213+
}
128214
}
129215

130216

0 commit comments

Comments
 (0)