Browse code

FEATBL-294 Fix: ContainerManagement checks mailbox public acls

David Phan authored on 07/02/2018 14:05:37
Showing 7 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,70 @@
0
+/* BEGIN LICENSE
1
+  * Copyright © Blue Mind SAS, 2012-2018
2
+  *
3
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
4
+  * solution.
5
+  *
6
+  * This program is free software; you can redistribute it and/or modify
7
+  * it under the terms of either the GNU Affero General Public License as
8
+  * published by the Free Software Foundation (version 3 of the License).
9
+  *
10
+  * This program is distributed in the hope that it will be useful,
11
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+  *
14
+  * See LICENSE.txt
15
+  * END LICENSE
16
+  */
17
+package net.bluemind.core.container.service.internal;
18
+
19
+import static org.junit.Assert.fail;
20
+
21
+import java.sql.SQLException;
22
+import java.util.ArrayList;
23
+import java.util.UUID;
24
+
25
+import org.junit.Before;
26
+import org.junit.Test;
27
+
28
+import net.bluemind.core.api.fault.ServerFault;
29
+import net.bluemind.core.container.model.Container;
30
+import net.bluemind.core.container.model.acl.AccessControlEntry;
31
+import net.bluemind.core.container.model.acl.Verb;
32
+
33
+public class AccessControlEntryValidatorTest {
34
+
35
+	private AccessControlEntryValidator validator;
36
+
37
+	@Before
38
+	public void before() throws Exception {
39
+		validator = new AccessControlEntryValidator("bm.lan");
40
+	}
41
+
42
+	@Test
43
+	public void validate_MailboxAcl_NoPublicSharing_Ok() {
44
+		Container c = Container.create("uid", "mailboxacl", "name", "owner");
45
+
46
+		ArrayList<AccessControlEntry> accessControlEntries = new ArrayList<AccessControlEntry>();
47
+		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Write));
48
+		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Read));
49
+		try {
50
+			validator.validate(c, accessControlEntries);
51
+		} catch (ServerFault sf) {
52
+			fail();
53
+		}
54
+	}
55
+
56
+	@Test
57
+	public void validate_MailboxAcl_NoPublicSharing_Forbidden() throws SQLException {
58
+		Container c = Container.create("uid", "mailboxacl", "name", "owner");
59
+
60
+		ArrayList<AccessControlEntry> accessControlEntries = new ArrayList<AccessControlEntry>();
61
+		accessControlEntries.add(AccessControlEntry.create("bm.lan", Verb.Write));
62
+		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Read));
63
+		try {
64
+			validator.validate(c, accessControlEntries);
65
+			fail();
66
+		} catch (ServerFault sf) {
67
+		}
68
+	}
69
+}
0 70
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+/* BEGIN LICENSE
1
+  * Copyright © Blue Mind SAS, 2012-2018
2
+  *
3
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
4
+  * solution.
5
+  *
6
+  * This program is free software; you can redistribute it and/or modify
7
+  * it under the terms of either the GNU Affero General Public License as
8
+  * published by the Free Software Foundation (version 3 of the License).
9
+  *
10
+  * This program is distributed in the hope that it will be useful,
11
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+  *
14
+  * See LICENSE.txt
15
+  * END LICENSE
16
+  */
17
+package net.bluemind.core.container.service.internal;
18
+
19
+import java.util.List;
20
+
21
+import net.bluemind.core.api.fault.ErrorCode;
22
+import net.bluemind.core.api.fault.ServerFault;
23
+import net.bluemind.core.container.model.Container;
24
+import net.bluemind.core.container.model.acl.AccessControlEntry;
25
+
26
+public class AccessControlEntryValidator {
27
+	private final String domainUid;
28
+
29
+	public AccessControlEntryValidator(String domainUid) {
30
+		this.domainUid = domainUid;
31
+	}
32
+
33
+	public void validate(Container container, List<AccessControlEntry> accessControlEntries) {
34
+		if ("mailboxacl".equals(container.type)
35
+				&& accessControlEntries.stream().anyMatch(ace -> domainUid.equals(ace.subject))) {
36
+			throw new ServerFault("Public sharing for user mailbox is forbidden", ErrorCode.FORBIDDEN);
37
+		}
38
+	}
39
+
40
+}
... ...
@@ -68,8 +68,8 @@ public class ContainerManagement implements IContainerManagement {
68 68
 	private Validator validator;
69 69
 	private RBACManager rbacManager;
70 70
 	private UserSubscriptionStore userSubscriptionStore;
71
+	private AccessControlEntryValidator aceValidator;
71 72
 
72
-	@SuppressWarnings("unused")
73 73
 	private static final Logger logger = LoggerFactory.getLogger(ContainerManagement.class);
74 74
 
75 75
 	private static List<IAclHook> loadHooks() {
... ...
@@ -108,7 +108,7 @@ public class ContainerManagement implements IContainerManagement {
108 108
 		} catch (SQLException e) {
109 109
 			throw ServerFault.sqlFault(e);
110 110
 		}
111
-
111
+		aceValidator = new AccessControlEntryValidator(container.domainUid);
112 112
 	}
113 113
 
114 114
 	@Override
... ...
@@ -116,9 +116,11 @@ public class ContainerManagement implements IContainerManagement {
116 116
 
117 117
 		if (!(container.owner.equals(securityContext.getSubject()) || rbacManager.can(Verb.Manage.name()))) {
118 118
 			throw new ServerFault("container " + container.uid + " is not manageable", ErrorCode.PERMISSION_DENIED);
119
-
120 119
 		}
121 120
 
121
+		// validate mailboxacl, public sharing is forbidden
122
+		aceValidator.validate(container, entries);
123
+
122 124
 		List<AccessControlEntry> previous = aclStore.retrieveAndStore(container, entries);
123 125
 
124 126
 		ContainerDescriptor descriptor = ContainerDescriptor.create(container.uid, container.name, container.owner,
... ...
@@ -34,8 +34,6 @@ import net.bluemind.core.api.Email;
34 34
 import net.bluemind.core.api.fault.ErrorCode;
35 35
 import net.bluemind.core.api.fault.ServerFault;
36 36
 import net.bluemind.core.container.model.Item;
37
-import net.bluemind.core.container.model.acl.AccessControlEntry;
38
-import net.bluemind.core.container.model.acl.Verb;
39 37
 import net.bluemind.core.context.SecurityContext;
40 38
 import net.bluemind.core.rest.ServerSideServiceProvider;
41 39
 import net.bluemind.core.tests.BmTestContext;
... ...
@@ -428,29 +426,4 @@ public class MailboxValidatorTests extends AbstractMailboxServiceTests {
428 428
 			fail("routing external + no split is be valid");
429 429
 		}
430 430
 	}
431
-
432
-	@Test
433
-	public void validate_NoPublicSharing_Ok() {
434
-		ArrayList<AccessControlEntry> accessControlEntries = new ArrayList<AccessControlEntry>();
435
-		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Write));
436
-		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Read));
437
-		try {
438
-			validator.validateAccessControlEntity(accessControlEntries);
439
-		} catch (ServerFault sf) {
440
-			fail();
441
-		}
442
-	}
443
-
444
-	@Test
445
-	public void validate_MailboxPublicSharing_Forbidden() {
446
-		ArrayList<AccessControlEntry> accessControlEntries = new ArrayList<AccessControlEntry>();
447
-		accessControlEntries.add(AccessControlEntry.create(domainUid, Verb.Write));
448
-		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Read));
449
-		try {
450
-			validator.validateAccessControlEntity(accessControlEntries);
451
-			fail();
452
-		} catch (ServerFault sf) {
453
-		}
454
-	}
455
-
456 431
 }
... ...
@@ -836,4 +836,23 @@ public class MailboxesServiceTests extends AbstractMailboxServiceTests {
836 836
 		mailConfig = getService(userSecurityContext).getMailboxConfig(userSecurityContext.getSubject());
837 837
 		assertEquals(Integer.valueOf(1000), mailConfig.messageMaxSize);
838 838
 	}
839
+
840
+	@Test
841
+	public void test_MailboxPublicAcl_Forbidden() throws ServerFault {
842
+		String uid = UUID.randomUUID().toString();
843
+		Mailbox mailshare = defaultMailshare("public-mailshare");
844
+		new BmTestContext(SecurityContext.SYSTEM).provider().instance(IMailshare.class, domainUid).create(uid,
845
+				Mailshare.fromMailbox(mailshare));
846
+
847
+		ArrayList<AccessControlEntry> accessControlEntries = new ArrayList<AccessControlEntry>();
848
+		accessControlEntries.add(AccessControlEntry.create(domainUid, Verb.Write));
849
+		accessControlEntries.add(AccessControlEntry.create(UUID.randomUUID().toString(), Verb.Read));
850
+
851
+		try {
852
+			getService(defaultSecurityContext).setMailboxAccessControlList(uid, accessControlEntries);
853
+			fail("Public ACL is forbidden");
854
+		} catch (ServerFault e) {
855
+			assertEquals(ErrorCode.FORBIDDEN, e.getCode());
856
+		}
857
+	}
839 858
 }
... ...
@@ -32,7 +32,6 @@ import net.bluemind.core.api.fault.ErrorCode;
32 32
 import net.bluemind.core.api.fault.ServerFault;
33 33
 import net.bluemind.core.container.model.Item;
34 34
 import net.bluemind.core.container.model.ItemValue;
35
-import net.bluemind.core.container.model.acl.AccessControlEntry;
36 35
 import net.bluemind.core.container.persistance.ItemStore;
37 36
 import net.bluemind.core.rest.BmContext;
38 37
 import net.bluemind.domain.api.DomainSettingsKeys;
... ...
@@ -132,13 +131,6 @@ public class MailboxValidator {
132 132
 
133 133
 	}
134 134
 
135
-	public void validateAccessControlEntity(List<AccessControlEntry> accessControlEntries) {
136
-		if (accessControlEntries.stream().anyMatch(ace -> domainUid.equals(ace.subject))) {
137
-			// no public sharing mailbox
138
-			throw new ServerFault("Public sharing for user mailbox is forbidden", ErrorCode.FORBIDDEN);
139
-		}
140
-	}
141
-
142 135
 	private void validateRouting(Mailbox mailbox) {
143 136
 		if (mailbox.routing == Routing.external) {
144 137
 			IDomainSettings domSettingsService = context.provider().instance(IDomainSettings.class, domainUid);
... ...
@@ -401,8 +401,6 @@ public class MailboxesService implements IMailboxes, IInCoreMailboxes {
401 401
 			throws ServerFault {
402 402
 		rbacManager.forContainer(MailboxAclContainerType.uidForMailbox(mailboxUid)).check(Verb.Manage.name());
403 403
 
404
-		validator.validateAccessControlEntity(accessControlEntries);
405
-
406 404
 		IContainerManagement cmgmt = context.provider().instance(IContainerManagement.class,
407 405
 				MailboxAclContainerType.uidForMailbox(mailboxUid));
408 406