Browse code

BM-14963 Chore: LDAP export tests no more a plugin fragment

Anthony Prades authored on 20/06/2019 15:45:44
Showing 42 changed files
... ...
@@ -4,14 +4,19 @@ Bundle-Name: net.bluemind.system.ldap.export.tests
4 4
 Bundle-SymbolicName: net.bluemind.system.ldap.export.tests
5 5
 Bundle-Version: 3.1.0.qualifier
6 6
 Bundle-Vendor: bluemind.net
7
-Fragment-Host: net.bluemind.system.ldap.export
8 7
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
9 8
 Require-Bundle: net.bluemind.pool,
10 9
  org.junit,
11
- net.bluemind.node.client;bundle-version="3.1.0",
10
+ net.bluemind.node.client,
12 11
  net.bluemind.core.jdbc.testshelper,
13 12
  net.bluemind.tests.defaultdata,
14 13
  net.bluemind.core.tests.testshelper,
15 14
  net.bluemind.core.container.persistance,
16 15
  net.bluemind.role.api,
17
- net.bluemind.externaluser.service;bundle-version="3.1.0"
16
+ net.bluemind.externaluser.service,
17
+ net.bluemind.system.ldap.export,
18
+ net.bluemind.lib.ldap,
19
+ net.bluemind.group.api,
20
+ net.bluemind.config,
21
+ net.bluemind.node.api,
22
+ net.bluemind.server.hook
... ...
@@ -1,4 +1,5 @@
1 1
 source.. = src/
2 2
 output.. = bin/
3 3
 bin.includes = META-INF/,\
4
-               .
4
+               .,\
5
+               plugin.xml
5 6
new file mode 100644
... ...
@@ -0,0 +1,1188 @@
1
+/* BEGIN LICENSE
2
+  * Copyright © Blue Mind SAS, 2012-2017
3
+  *
4
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
5
+  * solution.
6
+  *
7
+  * This program is free software; you can redistribute it and/or modify
8
+  * it under the terms of either the GNU Affero General Public License as
9
+  * published by the Free Software Foundation (version 3 of the License).
10
+  *
11
+  * This program is distributed in the hope that it will be useful,
12
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+  *
15
+  * See LICENSE.txt
16
+  * END LICENSE
17
+  */
18
+package net.bluemind.system.ldap.export;
19
+
20
+import static org.junit.Assert.assertEquals;
21
+import static org.junit.Assert.assertFalse;
22
+import static org.junit.Assert.assertNotEquals;
23
+import static org.junit.Assert.assertNotNull;
24
+import static org.junit.Assert.assertNull;
25
+import static org.junit.Assert.assertTrue;
26
+import static org.junit.Assert.fail;
27
+
28
+import java.sql.SQLException;
29
+import java.util.ArrayList;
30
+import java.util.Arrays;
31
+import java.util.List;
32
+import java.util.UUID;
33
+
34
+import org.apache.directory.api.ldap.model.cursor.CursorException;
35
+import org.apache.directory.api.ldap.model.entry.Attribute;
36
+import org.apache.directory.api.ldap.model.entry.Entry;
37
+import org.apache.directory.api.ldap.model.exception.LdapException;
38
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
39
+import org.apache.directory.ldap.client.api.LdapConnection;
40
+import org.junit.Before;
41
+import org.junit.Test;
42
+import org.vertx.java.core.AsyncResult;
43
+import org.vertx.java.core.Handler;
44
+
45
+import com.google.common.util.concurrent.SettableFuture;
46
+
47
+import net.bluemind.config.InstallationId;
48
+import net.bluemind.config.Token;
49
+import net.bluemind.core.api.fault.ErrorCode;
50
+import net.bluemind.core.api.fault.ServerFault;
51
+import net.bluemind.core.container.model.ContainerChangeset;
52
+import net.bluemind.core.container.model.ItemValue;
53
+import net.bluemind.core.context.SecurityContext;
54
+import net.bluemind.core.jdbc.JdbcTestHelper;
55
+import net.bluemind.core.rest.ServerSideServiceProvider;
56
+import net.bluemind.core.task.api.ITask;
57
+import net.bluemind.core.task.api.TaskRef;
58
+import net.bluemind.core.task.api.TaskStatus.State;
59
+import net.bluemind.core.tests.BmTestContext;
60
+import net.bluemind.core.utils.UIDGenerator;
61
+import net.bluemind.directory.api.DirEntry;
62
+import net.bluemind.directory.api.IDirectory;
63
+import net.bluemind.domain.api.Domain;
64
+import net.bluemind.group.api.Group;
65
+import net.bluemind.group.api.IGroup;
66
+import net.bluemind.group.api.Member;
67
+import net.bluemind.lib.vertx.VertxPlatform;
68
+import net.bluemind.mailbox.api.Mailbox;
69
+import net.bluemind.node.api.INodeClient;
70
+import net.bluemind.node.api.NCUtils;
71
+import net.bluemind.node.api.NodeActivator;
72
+import net.bluemind.pool.impl.BmConfIni;
73
+import net.bluemind.server.api.IServer;
74
+import net.bluemind.server.api.Server;
75
+import net.bluemind.system.ldap.export.LdapExportService;
76
+import net.bluemind.system.ldap.export.LdapHelper;
77
+import net.bluemind.system.ldap.export.objects.DomainDirectoryGroup;
78
+import net.bluemind.system.ldap.export.objects.DomainDirectoryUser;
79
+import net.bluemind.system.ldap.export.verticle.LdapExportVerticle;
80
+import net.bluemind.tests.defaultdata.PopulateHelper;
81
+import net.bluemind.user.api.IUser;
82
+import net.bluemind.user.api.User;
83
+
84
+public class LdapExportServiceTests {
85
+	private static final String LDAPTAG = "directory/bm-master";
86
+
87
+	private ItemValue<Domain> domain;
88
+	private ItemValue<Server> ldapRoleServer;
89
+
90
+	@Before
91
+	public void before() throws Exception {
92
+		LdapExportVerticle.suspended = true;
93
+
94
+		JdbcTestHelper.getInstance().beforeTest();
95
+		JdbcTestHelper.getInstance().getDbSchemaService().initialize();
96
+
97
+		PopulateHelper.initGlobalVirt();
98
+
99
+		String domainUid = "test" + System.currentTimeMillis() + ".lan";
100
+
101
+		SecurityContext domainAdmin = BmTestContext
102
+				.contextWithSession("testUser", "test", domainUid, SecurityContext.ROLE_ADMIN).getSecurityContext();
103
+
104
+		domain = PopulateHelper.createTestDomain(domainUid);
105
+		PopulateHelper.domainAdmin(domainUid, domainAdmin.getSubject());
106
+
107
+		final SettableFuture<Void> future = SettableFuture.<Void>create();
108
+		Handler<AsyncResult<Void>> done = new Handler<AsyncResult<Void>>() {
109
+
110
+			@Override
111
+			public void handle(AsyncResult<Void> event) {
112
+				future.set(null);
113
+			}
114
+		};
115
+		VertxPlatform.spawnVerticles(done);
116
+		future.get();
117
+
118
+		initAndAssignLdapExportServer();
119
+	}
120
+
121
+	@Test
122
+	public void testExportService_builder() throws Exception {
123
+		try {
124
+			LdapExportService.build(null);
125
+			fail("Test must thrown an exception");
126
+		} catch (ServerFault sf) {
127
+			assertEquals(ErrorCode.INVALID_PARAMETER, sf.getCode());
128
+		}
129
+
130
+		try {
131
+			LdapExportService.build("");
132
+			fail("Test must thrown an exception");
133
+		} catch (ServerFault sf) {
134
+			assertEquals(ErrorCode.INVALID_PARAMETER, sf.getCode());
135
+		}
136
+
137
+		try {
138
+			LdapExportService.build("invalidUid");
139
+			fail("Test must thrown an exception");
140
+		} catch (ServerFault sf) {
141
+			assertEquals(ErrorCode.UNKNOWN, sf.getCode());
142
+		}
143
+
144
+		assertNotNull(LdapExportService.build(domain.uid));
145
+
146
+		String noLdapExportDomainUid = "test" + System.currentTimeMillis() + ".lan";
147
+		PopulateHelper.createTestDomain(noLdapExportDomainUid);
148
+		assertNull(LdapExportService.build(noLdapExportDomainUid));
149
+	}
150
+
151
+	@Test
152
+	public void testExport_syncAll() throws Exception {
153
+		checkBmVersion();
154
+
155
+		String userUid = PopulateHelper.addUser(UUID.randomUUID().toString(), domain.value.name);
156
+		String groupUid = addGroup();
157
+
158
+		LdapExportService les = LdapExportService.build(domain.uid);
159
+		les.sync();
160
+
161
+		Results results = checkSync();
162
+
163
+		assertNotEquals(0, results.userExported.size());
164
+		assertTrue(results.userExported.contains(userUid));
165
+
166
+		assertNotEquals(0, results.userNotExported.size());
167
+
168
+		assertNotEquals(0, results.groupExported.size());
169
+		assertTrue(results.groupExported.contains(groupUid));
170
+
171
+		assertNotEquals(0, results.groupNotExported.size());
172
+	}
173
+
174
+	@Test
175
+	public void testExportUser_hiddenNotExported() throws Exception {
176
+		checkBmVersion();
177
+
178
+		User user = PopulateHelper.getUser("test-" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
179
+		user.hidden = true;
180
+		PopulateHelper.addUser(domain.value.name, user);
181
+
182
+		LdapExportService les = LdapExportService.build(domain.uid);
183
+		les.sync();
184
+
185
+		checkBmVersion();
186
+
187
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
188
+		Entry ldapEntry = ldapCon.lookup("uid=" + user.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
189
+		assertNull(ldapEntry);
190
+	}
191
+
192
+	@Test
193
+	public void testExportGroup_hiddenNotExported() throws Exception {
194
+		checkBmVersion();
195
+
196
+		Group group = getGroup();
197
+		group.hidden = true;
198
+		addGroup(group);
199
+
200
+		LdapExportService les = LdapExportService.build(domain.uid);
201
+		les.sync();
202
+
203
+		checkBmVersion();
204
+
205
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
206
+		Entry ldapEntry = ldapCon.lookup("cn=" + group.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
207
+		assertNull(ldapEntry);
208
+	}
209
+
210
+	@Test
211
+	public void testExportGroup_removeFromLdapIfDeleted() throws Exception {
212
+		String groupUid = addGroup();
213
+
214
+		LdapExportService.build(domain.uid).sync();
215
+
216
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
217
+				domain.value.name);
218
+		ItemValue<Group> group = groupService.getComplete(groupUid);
219
+
220
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
221
+		Entry ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
222
+		assertNotNull(ldapGroup);
223
+
224
+		TaskRef tr = groupService.delete(group.uid);
225
+		waitFor(tr);
226
+
227
+		LdapExportService.build(domain.uid).sync();
228
+
229
+		ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
230
+		assertNull(ldapGroup);
231
+	}
232
+
233
+	@Test
234
+	public void testExportUser_systemNotExported() throws Exception {
235
+		checkBmVersion();
236
+
237
+		User user = PopulateHelper.getUser("test-" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
238
+		user.system = true;
239
+		PopulateHelper.addUser(domain.value.name, user);
240
+
241
+		LdapExportService les = LdapExportService.build(domain.uid);
242
+		les.sync();
243
+
244
+		checkBmVersion();
245
+
246
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
247
+		Entry ldapEntry = ldapCon.lookup("uid=" + user.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
248
+		assertNull(ldapEntry);
249
+	}
250
+
251
+	@Test
252
+	public void testExport_syncAllWithNoDomainRoot() throws Exception {
253
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
254
+		LdapHelper.deleteTree(ldapCon, "dc=" + domain.value.name + ",dc=local");
255
+
256
+		LdapExportService les = LdapExportService.build(domain.uid);
257
+		les.sync();
258
+
259
+		checkSync();
260
+	}
261
+
262
+	@Test
263
+	public void testExportUser_createIfAbsentOnUpdate() throws Exception {
264
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
265
+
266
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
267
+				domain.value.name);
268
+		ItemValue<User> user = userService.getComplete(userUid);
269
+
270
+		LdapExportService les = LdapExportService.build(domain.uid);
271
+		les.sync();
272
+
273
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
274
+		LdapHelper.deleteTree(ldapCon, "uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
275
+
276
+		Entry ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
277
+		assertNull(ldapUser);
278
+
279
+		userService.update(user.uid, user.value);
280
+
281
+		les = LdapExportService.build(domain.uid);
282
+		les.sync();
283
+
284
+		ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
285
+		assertNotNull(ldapUser);
286
+	}
287
+
288
+	@Test
289
+	public void testExportGroup_createIfAbsentOnUpdate() throws Exception {
290
+		String groupUid = addGroup();
291
+
292
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
293
+				domain.value.name);
294
+		ItemValue<Group> group = groupService.getComplete(groupUid);
295
+
296
+		LdapExportService.build(domain.uid).sync();
297
+
298
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
299
+		LdapHelper.deleteTree(ldapCon, "cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
300
+
301
+		Entry ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
302
+		assertNull(ldapGroup);
303
+
304
+		groupService.update(group.uid, group.value);
305
+
306
+		LdapExportService.build(domain.uid).sync();
307
+
308
+		ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
309
+		assertNotNull(ldapGroup);
310
+	}
311
+
312
+	@Test
313
+	public void testExportUser_resetLdapEntryIfMoreThanOneEntryFound() throws Exception {
314
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
315
+
316
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
317
+				domain.value.name);
318
+		ItemValue<User> user = userService.getComplete(userUid);
319
+
320
+		LdapExportService.build(domain.uid).sync();
321
+
322
+		try (LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);) {
323
+			Entry ldapUser = ldapCon
324
+					.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
325
+			ldapUser.removeAttributes("uid");
326
+			String newLogin = user.value.login + "-2";
327
+			ldapUser.add("uid", newLogin);
328
+			ldapUser.setDn("uid=" + newLogin + ",ou=users,dc=" + domain.value.name + ",dc=local");
329
+			ldapCon.add(ldapUser);
330
+		}
331
+
332
+		userService.update(user.uid, user.value);
333
+
334
+		LdapExportService.build(domain.uid).sync();
335
+
336
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
337
+
338
+		List<Entry> entries = LdapHelper.getLdapEntryFromUid(ldapCon, domain, userUid);
339
+		assertEquals(1, entries.size());
340
+		assertEquals("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local",
341
+				entries.get(0).getDn().getName());
342
+		assertEquals(userUid, entries.get(0).get("bmUid").getString());
343
+	}
344
+
345
+	@Test
346
+	public void testExportGroup_resetLdapEntryIfMoreThanOneEntryFound() throws Exception {
347
+		String groupUid = addGroup();
348
+
349
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
350
+				domain.value.name);
351
+		ItemValue<Group> group = groupService.getComplete(groupUid);
352
+
353
+		LdapExportService.build(domain.uid).sync();
354
+
355
+		try (LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);) {
356
+			Entry ldapGroup = ldapCon
357
+					.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
358
+			ldapGroup.removeAttributes("uid");
359
+			String newName = group.value.name + "-2";
360
+			ldapGroup.add("cn", newName);
361
+			ldapGroup.setDn("cn=" + newName + ",ou=groups,dc=" + domain.value.name + ",dc=local");
362
+			ldapCon.add(ldapGroup);
363
+		}
364
+
365
+		groupService.update(group.uid, group.value);
366
+
367
+		LdapExportService.build(domain.uid).sync();
368
+
369
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
370
+
371
+		List<Entry> entries = LdapHelper.getLdapEntryFromUid(ldapCon, domain, groupUid);
372
+		assertEquals(1, entries.size());
373
+		assertEquals("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local",
374
+				entries.get(0).getDn().getName());
375
+		assertEquals(groupUid, entries.get(0).get("bmUid").getString());
376
+	}
377
+
378
+	@Test
379
+	public void testExportUser_removeFromLdapIfUpdatedToHidden() throws Exception {
380
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
381
+
382
+		LdapExportService les = LdapExportService.build(domain.uid);
383
+		les.sync();
384
+
385
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
386
+				domain.value.name);
387
+		ItemValue<User> user = userService.getComplete(userUid);
388
+
389
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
390
+		Entry ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
391
+		assertNotNull(ldapUser);
392
+
393
+		user.value.hidden = true;
394
+		userService.update(user.uid, user.value);
395
+
396
+		les.sync();
397
+
398
+		ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
399
+		assertNull(ldapUser);
400
+	}
401
+
402
+	@Test
403
+	public void testExportGroup_removeFromLdapIfUpdatedToHidden() throws Exception {
404
+		String groupUid = addGroup();
405
+
406
+		LdapExportService.build(domain.uid).sync();
407
+
408
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
409
+				domain.value.name);
410
+		ItemValue<Group> group = groupService.getComplete(groupUid);
411
+
412
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
413
+		Entry ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
414
+		assertNotNull(ldapGroup);
415
+
416
+		group.value.hidden = true;
417
+		groupService.update(group.uid, group.value);
418
+
419
+		LdapExportService.build(domain.uid).sync();
420
+
421
+		ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
422
+		assertNull(ldapGroup);
423
+	}
424
+
425
+	@Test
426
+	public void testExportUser_removeFromLdapIfUpdatedToSystem() throws Exception {
427
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
428
+
429
+		LdapExportService les = LdapExportService.build(domain.uid);
430
+		les.sync();
431
+
432
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
433
+				domain.value.name);
434
+		ItemValue<User> user = userService.getComplete(userUid);
435
+
436
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
437
+		Entry ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
438
+		assertNotNull(ldapUser);
439
+
440
+		user.value.system = true;
441
+		userService.update(user.uid, user.value);
442
+
443
+		les.sync();
444
+
445
+		ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
446
+		assertNull(ldapUser);
447
+	}
448
+
449
+	@Test
450
+	public void testExportUser_removeFromLdapIfDeleted() throws Exception {
451
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
452
+
453
+		LdapExportService les = LdapExportService.build(domain.uid);
454
+		les.sync();
455
+
456
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
457
+				domain.value.name);
458
+		ItemValue<User> user = userService.getComplete(userUid);
459
+
460
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
461
+		Entry ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
462
+		assertNotNull(ldapUser);
463
+
464
+		TaskRef tr = userService.delete(user.uid);
465
+		waitFor(tr);
466
+
467
+		les.sync();
468
+
469
+		ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
470
+		assertNull(ldapUser);
471
+	}
472
+
473
+	@Test
474
+	public void testExportUser_updated() throws Exception {
475
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
476
+
477
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
478
+				domain.value.name);
479
+		ItemValue<User> user = userService.getComplete(userUid);
480
+		user.value.contactInfos.explanatory.note = "description";
481
+		userService.update(user.uid, user.value);
482
+
483
+		LdapExportService les = LdapExportService.build(domain.uid);
484
+		les.sync();
485
+
486
+		user.value.contactInfos.explanatory.note = "updated description";
487
+		userService.update(user.uid, user.value);
488
+
489
+		les.sync();
490
+
491
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
492
+		Entry ldapUser = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
493
+		assertNotNull(ldapUser);
494
+		assertEquals(userUid, ldapUser.get("bmUid").getString());
495
+		assertEquals("updated description", ldapUser.get("description").getString());
496
+	}
497
+
498
+	@Test
499
+	public void testExportGroup_updated() throws Exception {
500
+		String groupUid = addGroup();
501
+
502
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
503
+				domain.value.name);
504
+		ItemValue<Group> group = groupService.getComplete(groupUid);
505
+		group.value.description = "description";
506
+		groupService.update(group.uid, group.value);
507
+
508
+		LdapExportService.build(domain.uid).sync();
509
+
510
+		group.value.description = "updated description";
511
+		groupService.update(group.uid, group.value);
512
+
513
+		LdapExportService.build(domain.uid).sync();
514
+
515
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
516
+		Entry ldapGroup = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
517
+		assertNotNull(ldapGroup);
518
+		assertEquals(groupUid, ldapGroup.get("bmUid").getString());
519
+		assertEquals("updated description", ldapGroup.get("description").getString());
520
+	}
521
+
522
+	@Test
523
+	public void testExportUser_renamed() throws Exception {
524
+		String userUid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
525
+
526
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
527
+				domain.value.name);
528
+		ItemValue<User> user = userService.getComplete(userUid);
529
+
530
+		LdapExportService.build(domain.uid).sync();
531
+
532
+		String oldLogin = user.value.login;
533
+		user.value.login = "newlogin";
534
+		userService.update(user.uid, user.value);
535
+
536
+		LdapExportService.build(domain.uid).sync();
537
+
538
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
539
+		Entry ldapUser = ldapCon.lookup("uid=newlogin,ou=users,dc=" + domain.value.name + ",dc=local");
540
+		assertNotNull(ldapUser);
541
+		assertEquals(userUid, ldapUser.get("bmUid").getString());
542
+
543
+		ldapUser = ldapCon.lookup("uid=" + oldLogin + ",ou=users,dc=" + domain.value.name + ",dc=local");
544
+		assertNull(ldapUser);
545
+	}
546
+
547
+	@Test
548
+	public void testExportGroup_renamed() throws Exception {
549
+		String groupUid = addGroup();
550
+
551
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
552
+				domain.value.name);
553
+		ItemValue<Group> group = groupService.getComplete(groupUid);
554
+
555
+		LdapExportService.build(domain.uid).sync();
556
+
557
+		String oldName = group.value.name;
558
+		group.value.name = "newlogin";
559
+		groupService.update(group.uid, group.value);
560
+
561
+		LdapExportService.build(domain.uid).sync();
562
+
563
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
564
+		Entry ldapUser = ldapCon.lookup("cn=newlogin,ou=groups,dc=" + domain.value.name + ",dc=local");
565
+		assertNotNull(ldapUser);
566
+		assertEquals(groupUid, ldapUser.get("bmUid").getString());
567
+
568
+		ldapUser = ldapCon.lookup("cn=" + oldName + ",ou=groups,dc=" + domain.value.name + ",dc=local");
569
+		assertNull(ldapUser);
570
+	}
571
+
572
+	@Test
573
+	public void testExportGroupMember_membersOnCreate() throws Exception {
574
+		String userLogin = "test" + System.nanoTime();
575
+		String userUid = PopulateHelper.addUser(userLogin, domain.value.name, Mailbox.Routing.none);
576
+		String groupUid = addGroup();
577
+
578
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
579
+				domain.value.name);
580
+		groupService.add(groupUid, Arrays.asList(Member.user(userUid)));
581
+
582
+		LdapExportService.build(domain.uid).sync();
583
+
584
+		checkUserIsMemberOfGroup(groupUid, userUid, userLogin);
585
+	}
586
+
587
+	@Test
588
+	public void testExportGroupMember_addMember() throws Exception {
589
+		String userLogin = "test" + System.nanoTime();
590
+		String userUid = PopulateHelper.addUser(userLogin, domain.value.name, Mailbox.Routing.none);
591
+		String groupUid = addGroup();
592
+
593
+		LdapExportService.build(domain.uid).sync();
594
+
595
+		try (LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer)) {
596
+			List<Entry> ldapGroup = LdapHelper.getLdapEntryFromUid(ldapCon, domain, groupUid);
597
+			assertEquals(1, ldapGroup.size());
598
+
599
+			Attribute memberAttribute = ldapGroup.get(0).get("member");
600
+			assertNull(memberAttribute);
601
+
602
+			Attribute memberUidAttribute = ldapGroup.get(0).get("memberUid");
603
+			assertNull(memberUidAttribute);
604
+		}
605
+
606
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
607
+				domain.value.name);
608
+		groupService.add(groupUid, Arrays.asList(Member.user(userUid)));
609
+
610
+		LdapExportService.build(domain.uid).sync();
611
+
612
+		checkUserIsMemberOfGroup(groupUid, userUid, userLogin);
613
+	}
614
+
615
+	@Test
616
+	public void testExportGroupMember_removeMember() throws Exception {
617
+		String userLogin = "test" + System.nanoTime();
618
+		String userUid = PopulateHelper.addUser(userLogin, domain.value.name, Mailbox.Routing.none);
619
+		String groupUid = addGroup();
620
+
621
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
622
+				domain.value.name);
623
+		groupService.add(groupUid, Arrays.asList(Member.user(userUid)));
624
+
625
+		LdapExportService.build(domain.uid).sync();
626
+
627
+		checkUserIsMemberOfGroup(groupUid, userUid, userLogin);
628
+
629
+		groupService.remove(groupUid, Arrays.asList(Member.user(userUid)));
630
+
631
+		LdapExportService.build(domain.uid).sync();
632
+
633
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
634
+		List<Entry> ldapGroup = LdapHelper.getLdapEntryFromUid(ldapCon, domain, groupUid);
635
+		assertEquals(1, ldapGroup.size());
636
+
637
+		Attribute memberAttribute = ldapGroup.get(0).get("member");
638
+		assertNull(memberAttribute);
639
+
640
+		Attribute memberUidAttribute = ldapGroup.get(0).get("memberUid");
641
+		assertNull(memberUidAttribute);
642
+	}
643
+
644
+	@Test
645
+	public void testExportGroupMember_createGroupHierarchy() throws Exception {
646
+		String user1Login = "test" + System.nanoTime();
647
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
648
+		String user2Login = "test" + System.nanoTime();
649
+		String user2Uid = PopulateHelper.addUser(user2Login, domain.value.name, Mailbox.Routing.none);
650
+		String group1Uid = addGroup();
651
+		String group2Uid = addGroup();
652
+
653
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
654
+				domain.value.name);
655
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
656
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
657
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
658
+
659
+		LdapExportService.build(domain.uid).sync();
660
+
661
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2Login, user2Uid);
662
+	}
663
+
664
+	@Test
665
+	public void testExportGroupMember_removeUserFromGroupChild() throws Exception {
666
+		Group group1 = getGroup();
667
+		String group1Uid = addGroup(group1);
668
+		Group group2 = getGroup();
669
+		String group2Uid = addGroup(group2);
670
+		Group group3 = getGroup();
671
+		String group3Uid = addGroup(group3);
672
+		String user1Uid = PopulateHelper.addUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
673
+		User user2 = PopulateHelper.getUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
674
+		String user2Uid = PopulateHelper.addUser(domain.value.name, user2);
675
+
676
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
677
+				domain.value.name);
678
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
679
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
680
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
681
+		groupService.add(group3Uid, Arrays.asList(Member.user(user2Uid)));
682
+
683
+		LdapExportService.build(domain.uid).sync();
684
+
685
+		groupService.remove(group2Uid, Arrays.asList(Member.user(user2Uid)));
686
+
687
+		LdapExportService.build(domain.uid).sync();
688
+
689
+		checkUserIsMemberOfGroup(group3Uid, user2Uid, user2.login);
690
+
691
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
692
+		String user2Dn = new DomainDirectoryUser(domain, ItemValue.create(user2Uid, user2), null).getDn();
693
+
694
+		Entry entry = ldapCon.lookup(new DomainDirectoryGroup(domain, ItemValue.create(group1Uid, group1)).getDn());
695
+		Attribute attrs = entry.get("member");
696
+		assertFalse(attrs.contains(user2Dn));
697
+		attrs = entry.get("memberUid");
698
+		assertFalse(attrs.contains(user2.login));
699
+
700
+		entry = ldapCon.lookup(new DomainDirectoryGroup(domain, ItemValue.create(group2Uid, group2)).getDn());
701
+		assertNull(entry.get("member"));
702
+		assertNull(entry.get("memberUid"));
703
+	}
704
+
705
+	@Test
706
+	public void testExportGroupMember_addUserToGroupChild() throws Exception {
707
+		Group group1 = getGroup();
708
+		String group1Uid = addGroup(group1);
709
+		Group group2 = getGroup();
710
+		String group2Uid = addGroup(group2);
711
+		User user1 = PopulateHelper.getUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
712
+		String user1Uid = PopulateHelper.addUser(domain.value.name, user1);
713
+		User user2 = PopulateHelper.getUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
714
+		String user2Uid = PopulateHelper.addUser(domain.value.name, user2);
715
+
716
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
717
+				domain.value.name);
718
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
719
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
720
+
721
+		LdapExportService.build(domain.uid).sync();
722
+
723
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
724
+
725
+		LdapExportService.build(domain.uid).sync();
726
+
727
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1.login, group2Uid, user2.login, user2Uid);
728
+	}
729
+
730
+	@Test
731
+	public void testExportGroupWithExternalUserNotTaken() throws Exception {
732
+		// create a user
733
+		String user1Login = "test" + System.nanoTime();
734
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
735
+
736
+		// create a group
737
+		String groupUid = addGroup();
738
+
739
+		// create an external user
740
+		String externalUser1Uid = PopulateHelper.addExternalUser(domain.value.name, "external@user.com", "displayName");
741
+
742
+		// add all members to group
743
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
744
+				domain.value.name);
745
+		groupService.add(groupUid, Arrays.asList(Member.user(user1Uid), Member.externalUser(externalUser1Uid)));
746
+
747
+		LdapExportService.build(domain.uid).sync();
748
+
749
+		checkUidIsNotMemberOfGroup(groupUid, externalUser1Uid);
750
+		checkUserIsMemberOfGroup(groupUid, user1Uid, user1Login);
751
+	}
752
+
753
+	@Test
754
+	public void testExportGroupMember_addGroupMember() throws Exception {
755
+		String user1Login = "test" + System.nanoTime();
756
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
757
+		String user2Login = "test" + System.nanoTime();
758
+		String user2Uid = PopulateHelper.addUser(user2Login, domain.value.name, Mailbox.Routing.none);
759
+		String group1Uid = addGroup();
760
+		String group2Uid = addGroup();
761
+
762
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
763
+				domain.value.name);
764
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
765
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
766
+
767
+		LdapExportService.build(domain.uid).sync();
768
+
769
+		checkUserIsMemberOfGroup(group1Uid, user1Uid, user1Login);
770
+		checkUserIsMemberOfGroup(group2Uid, user2Uid, user2Login);
771
+
772
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
773
+
774
+		LdapExportService.build(domain.uid).sync();
775
+
776
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2Login, user2Uid);
777
+	}
778
+
779
+	@Test
780
+	public void testExportGroupMember_removeGroupMember() throws Exception {
781
+		String user1Login = "test" + System.nanoTime();
782
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
783
+		String user2Login = "test" + System.nanoTime();
784
+		String user2Uid = PopulateHelper.addUser(user2Login, domain.value.name, Mailbox.Routing.none);
785
+		String group1Uid = addGroup();
786
+		String group2Uid = addGroup();
787
+
788
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
789
+				domain.value.name);
790
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
791
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
792
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
793
+
794
+		LdapExportService.build(domain.uid).sync();
795
+
796
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2Login, user2Uid);
797
+
798
+		groupService.remove(group1Uid, Arrays.asList(Member.group(group2Uid)));
799
+
800
+		LdapExportService.build(domain.uid).sync();
801
+
802
+		checkUserIsMemberOfGroup(group1Uid, user1Uid, user1Login);
803
+		checkUserIsMemberOfGroup(group2Uid, user2Uid, user2Login);
804
+	}
805
+
806
+	@Test
807
+	public void testExportGroupMember_renameGroupMember() throws Exception {
808
+		String group1Uid = addGroup();
809
+		Group group2 = getGroup();
810
+		String group2Uid = addGroup(group2);
811
+		String user1Login = "test" + System.nanoTime();
812
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
813
+		String user2Login = "test" + System.nanoTime();
814
+		String user2Uid = PopulateHelper.addUser(user2Login, domain.value.name, Mailbox.Routing.none);
815
+
816
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
817
+				domain.value.name);
818
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
819
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
820
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
821
+
822
+		LdapExportService.build(domain.uid).sync();
823
+
824
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2Login, user2Uid);
825
+
826
+		group2.name = group2.name + "-new";
827
+		groupService.update(group2Uid, group2);
828
+
829
+		LdapExportService.build(domain.uid).sync();
830
+
831
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2Login, user2Uid);
832
+	}
833
+
834
+	@Test
835
+	public void testExportGroupMember_renameUserMember() throws Exception {
836
+		String group1Uid = addGroup();
837
+		Group group2 = getGroup();
838
+		String group2Uid = addGroup(group2);
839
+		String user1Login = "test" + System.nanoTime();
840
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
841
+		User user2 = PopulateHelper.getUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
842
+		String user2Uid = PopulateHelper.addUser(domain.value.name, user2);
843
+
844
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
845
+				domain.value.name);
846
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
847
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
848
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
849
+
850
+		LdapExportService.build(domain.uid).sync();
851
+
852
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2.login, user2Uid);
853
+
854
+		user2.login = user2.login + "-new";
855
+		ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class, domain.value.name)
856
+				.update(user2Uid, user2);
857
+
858
+		LdapExportService.build(domain.uid).sync();
859
+
860
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2.login, user2Uid);
861
+	}
862
+
863
+	@Test
864
+	public void testExportGroupMember_deleteUserMemberFromChild() throws Exception {
865
+		Group group1 = getGroup();
866
+		String group1Uid = addGroup(group1);
867
+		Group group2 = getGroup();
868
+		String group2Uid = addGroup(group2);
869
+		String user1Login = "test" + System.nanoTime();
870
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
871
+		User user2 = PopulateHelper.getUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
872
+		String user2Uid = PopulateHelper.addUser(domain.value.name, user2);
873
+
874
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
875
+				domain.value.name);
876
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
877
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
878
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
879
+
880
+		LdapExportService.build(domain.uid).sync();
881
+
882
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2.login, user2Uid);
883
+
884
+		TaskRef tr = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
885
+				.instance(IUser.class, domain.value.name).delete(user2Uid);
886
+		waitFor(tr);
887
+
888
+		LdapExportService.build(domain.uid).sync();
889
+
890
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
891
+		String user2Dn = new DomainDirectoryUser(domain, ItemValue.create(user2Uid, user2), null).getDn();
892
+
893
+		Entry entry = ldapCon.lookup(new DomainDirectoryGroup(domain, ItemValue.create(group1Uid, group1)).getDn());
894
+		Attribute attrs = entry.get("member");
895
+		assertFalse(attrs.contains(user2Dn));
896
+		attrs = entry.get("memberUid");
897
+		assertFalse(attrs.contains(user2.login));
898
+
899
+		entry = ldapCon.lookup(new DomainDirectoryGroup(domain, ItemValue.create(group2Uid, group2)).getDn());
900
+		assertNull(entry.get("member"));
901
+		assertNull(entry.get("memberUid"));
902
+	}
903
+
904
+	@Test
905
+	public void testExportGroupMember_deleteGroupMemberFromChild() throws Exception {
906
+		Group group1 = getGroup();
907
+		String group1Uid = addGroup(group1);
908
+		Group group2 = getGroup();
909
+		String group2Uid = addGroup(group2);
910
+		String user1Login = "test" + System.nanoTime();
911
+		String user1Uid = PopulateHelper.addUser(user1Login, domain.value.name, Mailbox.Routing.none);
912
+		User user2 = PopulateHelper.getUser("test" + System.nanoTime(), domain.value.name, Mailbox.Routing.none);
913
+		String user2Uid = PopulateHelper.addUser(domain.value.name, user2);
914
+
915
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
916
+				domain.value.name);
917
+		groupService.add(group1Uid, Arrays.asList(Member.user(user1Uid)));
918
+		groupService.add(group2Uid, Arrays.asList(Member.user(user2Uid)));
919
+		groupService.add(group1Uid, Arrays.asList(Member.group(group2Uid)));
920
+
921
+		LdapExportService.build(domain.uid).sync();
922
+
923
+		checkGroupHierarchyMembers(group1Uid, user1Uid, user1Login, group2Uid, user2.login, user2Uid);
924
+
925
+		TaskRef tr = groupService.delete(group2Uid);
926
+		waitFor(tr);
927
+
928
+		LdapExportService.build(domain.uid).sync();
929
+
930
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
931
+		String user2Dn = new DomainDirectoryUser(domain, ItemValue.create(user2Uid, user2), null).getDn();
932
+		String group2Dn = new DomainDirectoryGroup(domain, ItemValue.create(group2Uid, group2)).getDn();
933
+
934
+		Entry entry = ldapCon.lookup(group2Dn);
935
+		assertNull(entry);
936
+
937
+		entry = ldapCon.lookup(new DomainDirectoryGroup(domain, ItemValue.create(group1Uid, group1)).getDn());
938
+		Attribute attrs = entry.get("member");
939
+		assertFalse(attrs.contains(user2Dn));
940
+		assertFalse(attrs.contains(group2Dn));
941
+		attrs = entry.get("memberUid");
942
+		assertFalse(attrs.contains(user2.login));
943
+	}
944
+
945
+	/**
946
+	 * Check:
947
+	 * <ul>
948
+	 * <li>user (<i>groupUserUid</i>, <i>groupUserLogin</i>) member of group
949
+	 * (<i>groupUid</i>)</li>
950
+	 * <li>user (<i>childGroupUserLogin</i>, <i>childGroupUserUid</i>) member of
951
+	 * group (<i>childGroupUid</i>)</li>
952
+	 * <li>group (<i>childGroupUid</i>) member of group (<i>groupUid</i>)</li>
953
+	 * </ul>
954
+	 * 
955
+	 * @param groupUid
956
+	 * @param groupUserUid
957
+	 * @param groupUserLogin
958
+	 * @param childGroupUid
959
+	 * @param childGroupUserLogin
960
+	 * @param childGroupUserUid
961
+	 * @throws LdapException
962
+	 * @throws CursorException
963
+	 * @throws LdapInvalidAttributeValueException
964
+	 */
965
+	private void checkGroupHierarchyMembers(String groupUid, String groupUserUid, String groupUserLogin,
966
+			String childGroupUid, String childGroupUserLogin, String childGroupUserUid)
967
+			throws LdapException, CursorException, LdapInvalidAttributeValueException {
968
+		checkUserIsMemberOfGroup(childGroupUid, childGroupUserUid, childGroupUserLogin);
969
+
970
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
971
+
972
+		List<Entry> ldapUser1 = LdapHelper.getLdapEntryFromUid(ldapCon, domain, groupUserUid, "memberOf");
973
+		assertEquals(1, ldapUser1.size());
974
+
975
+		List<Entry> ldapGroup1 = LdapHelper.getLdapEntryFromUid(ldapCon, domain, groupUid, "member", "memberuid",
976
+				"memberOf");
977
+		assertEquals(1, ldapGroup1.size());
978
+
979
+		List<Entry> ldapGroup2 = LdapHelper.getLdapEntryFromUid(ldapCon, domain, childGroupUid, "member", "memberuid",
980
+				"memberOf");
981
+		assertEquals(1, ldapGroup2.size());
982
+
983
+		// Check group1 member and memberUid attributes
984
+		Attribute memberAttribute = ldapGroup1.get(0).get("member");
985
+		assertNotNull(memberAttribute);
986
+		assertEquals(2, memberAttribute.size());
987
+		assertTrue(memberAttribute.contains(ldapUser1.get(0).getDn().getName()));
988
+		assertTrue(memberAttribute.contains(ldapGroup2.get(0).getDn().getName()));
989
+
990
+		Attribute memberUidAttribute = ldapGroup1.get(0).get("memberUid");
991
+		assertNotNull(memberUidAttribute);
992
+		assertEquals(2, memberUidAttribute.size());
993
+		assertTrue(memberUidAttribute.contains(groupUserLogin));
994
+		assertTrue(memberUidAttribute.contains(childGroupUserLogin));
995
+
996
+		// Check user1 memberOf attributes
997
+		Attribute memberOfAttribute = ldapUser1.get(0).get("memberof");
998
+		assertNotNull(memberOfAttribute);
999
+		assertEquals(1, memberOfAttribute.size());
1000
+		assertEquals(ldapGroup1.get(0).getDn().getName(), memberOfAttribute.getString());
1001
+
1002
+		// Check group2 memberOf attributes
1003
+		memberOfAttribute = ldapGroup2.get(0).get("memberof");
1004
+		assertNotNull(memberOfAttribute);
1005
+		assertEquals(1, memberOfAttribute.size());
1006
+		assertEquals(ldapGroup1.get(0).getDn().getName(), memberOfAttribute.getString());
1007
+	}
1008
+
1009
+	/**
1010
+	 * Check user (<i>userUid</i>, <i>userLogin</i>) is member of group
1011
+	 * (<i>groupUid</i>).
1012
+	 * 
1013
+	 * @param groupUid
1014
+	 * @param userUid
1015
+	 * @param userLogin
1016
+	 * 
1017
+	 * @throws LdapException
1018
+	 * @throws CursorException
1019
+	 * @throws LdapInvalidAttributeValueException
1020
+	 */
1021
+	private void checkUserIsMemberOfGroup(String groupUid, String userUid, String userLogin)
1022
+			throws LdapException, CursorException, LdapInvalidAttributeValueException {
1023
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
1024
+
1025
+		List<Entry> ldapUser = LdapHelper.getLdapEntryFromUid(ldapCon, domain, userUid, "memberOf");
1026
+		assertEquals(1, ldapUser.size());
1027
+
1028
+		List<Entry> ldapGroup = LdapHelper.getLdapEntryFromUid(ldapCon, domain, groupUid);
1029
+		assertEquals(1, ldapGroup.size());
1030
+
1031
+		Attribute memberAttribute = ldapGroup.get(0).get("member");
1032
+		assertNotNull(memberAttribute);
1033
+		assertEquals(1, memberAttribute.size());
1034
+		assertEquals(ldapUser.get(0).getDn().getName(), memberAttribute.getString());
1035
+
1036
+		Attribute memberUidAttribute = ldapGroup.get(0).get("memberUid");
1037
+		assertNotNull(memberUidAttribute);
1038
+		assertEquals(1, memberUidAttribute.size());
1039
+		assertEquals(userLogin, memberUidAttribute.getString());
1040
+
1041
+		Attribute memberOfAttribute = ldapUser.get(0).get("memberof");
1042
+		assertNotNull(memberOfAttribute);
1043
+		assertEquals(1, memberOfAttribute.size());
1044
+		assertEquals(ldapGroup.get(0).getDn().getName(), memberOfAttribute.getString());
1045
+	}
1046
+
1047
+	private void checkUidIsNotMemberOfGroup(String groupUid, String memberUid) throws LdapException, CursorException {
1048
+		assertEquals(0,
1049
+				LdapHelper
1050
+						.getLdapEntryFromUid(LdapHelper.connectDirectory(ldapRoleServer), domain, memberUid, "memberOf")
1051
+						.size());
1052
+	}
1053
+
1054
+	private void initAndAssignLdapExportServer() throws ServerFault, SQLException, InterruptedException {
1055
+		IServer serverService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IServer.class,
1056
+				InstallationId.getIdentifier());
1057
+
1058
+		String ldapRoleServerUid = UUID.randomUUID().toString();
1059
+		Server ldapRoleServer = new Server();
1060
+		ldapRoleServer.name = "LDAP export server";
1061
+		ldapRoleServer.ip = new BmConfIni().get("bluemind/ldap");
1062
+		waitFor(serverService.create(ldapRoleServerUid, ldapRoleServer));
1063
+
1064
+		this.ldapRoleServer = serverService.getComplete(ldapRoleServerUid);
1065
+
1066
+		INodeClient nodeClient = NodeActivator.get(ldapRoleServer.ip);
1067
+		updateUserPassword(nodeClient, "admin0@global.virt", Token.admin0());
1068
+
1069
+		waitFor(serverService.setTags(ldapRoleServerUid, Arrays.asList(LDAPTAG)));
1070
+
1071
+		serverService.assign(ldapRoleServerUid, domain.uid, LDAPTAG);
1072
+		// Wait for domain assign ending
1073
+		Thread.sleep(1000);
1074
+	}
1075
+
1076
+	private void waitFor(TaskRef taskRef) {
1077
+		ITask task = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(ITask.class, taskRef.id);
1078
+		while (!task.status().state.ended) {
1079
+			try {
1080
+				Thread.sleep(100);
1081
+			} catch (InterruptedException e) {
1082
+				e.printStackTrace();
1083
+			}
1084
+		}
1085
+		assertEquals(State.Success, task.status().state);
1086
+	}
1087
+
1088
+	private void updateUserPassword(INodeClient nodeClient, String login, String passwd) {
1089
+		NCUtils.exec(nodeClient, "/usr/local/sbin/updateUserPassword.sh " + login + " " + passwd);
1090
+	}
1091
+
1092
+	private class Results {
1093
+		List<String> userNotExported = new ArrayList<>();
1094
+		List<String> userExported = new ArrayList<>();
1095
+		List<String> groupNotExported = new ArrayList<>();
1096
+		List<String> groupExported = new ArrayList<>();
1097
+	}
1098
+
1099
+	private String addGroup() {
1100
+		Group group = getGroup();
1101
+		return addGroup(group);
1102
+	}
1103
+
1104
+	private String addGroup(Group group) {
1105
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
1106
+				domain.value.name);
1107
+		String uid = UIDGenerator.uid();
1108
+		groupService.create(uid, group);
1109
+		return uid;
1110
+	}
1111
+
1112
+	private Group getGroup() {
1113
+		Group group = new Group();
1114
+		group.name = UUID.randomUUID().toString();
1115
+
1116
+		return group;
1117
+	}
1118
+
1119
+	private Results checkSync() throws LdapException {
1120
+		IDirectory directoryService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
1121
+				.instance(IDirectory.class, domain.uid);
1122
+		ContainerChangeset<String> changeSet = directoryService.changeset(0l);
1123
+		assertNotEquals(0, changeSet.version);
1124
+		checkBmVersion(changeSet.version);
1125
+
1126
+		Results results = new Results();
1127
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
1128
+		for (String uid : changeSet.created) {
1129
+			DirEntry dirEntry = directoryService.findByEntryUid(uid);
1130
+			assertNotNull(dirEntry);
1131
+
1132
+			switch (dirEntry.kind) {
1133
+			case USER:
1134
+				checkUser(ldapCon, dirEntry, results);
1135
+				break;
1136
+			case GROUP:
1137
+				checkGroup(ldapCon, dirEntry, results);
1138
+				break;
1139
+			default:
1140
+				break;
1141
+			}
1142
+		}
1143
+		return results;
1144
+	}
1145
+
1146
+	private void checkGroup(LdapConnection ldapCon, DirEntry dirEntry, Results results) throws LdapException {
1147
+		IGroup groupService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IGroup.class,
1148
+				domain.uid);
1149
+		ItemValue<Group> group = groupService.getComplete(dirEntry.entryUid);
1150
+
1151
+		Entry ldapEntry = ldapCon.lookup("cn=" + group.value.name + ",ou=groups,dc=" + domain.value.name + ",dc=local");
1152
+
1153
+		if (dirEntry.hidden || dirEntry.system) {
1154
+			assertNull(ldapEntry);
1155
+			results.groupNotExported.add(dirEntry.entryUid);
1156
+		} else {
1157
+			assertNotNull(ldapEntry);
1158
+			results.groupExported.add(dirEntry.entryUid);
1159
+		}
1160
+	}
1161
+
1162
+	private void checkUser(LdapConnection ldapCon, DirEntry dirEntry, Results results) throws LdapException {
1163
+		IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
1164
+				domain.uid);
1165
+		ItemValue<User> user = userService.getComplete(dirEntry.entryUid);
1166
+
1167
+		Entry ldapEntry = ldapCon.lookup("uid=" + user.value.login + ",ou=users,dc=" + domain.value.name + ",dc=local");
1168
+
1169
+		if (dirEntry.hidden || dirEntry.system) {
1170
+			assertNull(ldapEntry);
1171
+			results.userNotExported.add(dirEntry.entryUid);
1172
+		} else {
1173
+			assertNotNull(ldapEntry);
1174
+			results.userExported.add(dirEntry.entryUid);
1175
+		}
1176
+	}
1177
+
1178
+	private void checkBmVersion() throws ServerFault, LdapException {
1179
+		checkBmVersion(ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
1180
+				.instance(IDirectory.class, domain.uid).changeset(0l).version);
1181
+	}
1182
+
1183
+	private void checkBmVersion(long i) throws LdapException {
1184
+		LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer);
1185
+		Entry entry = ldapCon.lookup("dc=" + domain.value.name + ",dc=local", "bmVersion");
1186
+		assertEquals(i, Long.parseLong(entry.get("bmVersion").getString()));
1187
+	}
1188
+}
0 1189
new file mode 100644
... ...
@@ -0,0 +1,131 @@
1
+/* BEGIN LICENSE
2
+  * Copyright © Blue Mind SAS, 2012-2017
3
+  *
4
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
5
+  * solution.
6
+  *
7
+  * This program is free software; you can redistribute it and/or modify
8
+  * it under the terms of either the GNU Affero General Public License as
9
+  * published by the Free Software Foundation (version 3 of the License).
10
+  *
11
+  * This program is distributed in the hope that it will be useful,
12
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+  *
15
+  * See LICENSE.txt
16
+  * END LICENSE
17
+  */
18
+package net.bluemind.system.ldap.export.conf;
19
+
20
+import static org.junit.Assert.assertEquals;
21
+import static org.junit.Assert.assertNotNull;
22
+import static org.junit.Assert.assertTrue;
23
+
24
+import java.io.IOException;
25
+import java.util.Collections;
26
+import java.util.UUID;
27
+
28
+import org.apache.directory.api.ldap.codec.api.ConfigurableBinaryAttributeDetector;
29
+import org.apache.directory.api.ldap.codec.api.DefaultConfigurableBinaryAttributeDetector;
30
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
31
+import org.apache.directory.api.ldap.model.exception.LdapException;
32
+import org.apache.directory.api.ldap.model.message.BindRequest;
33
+import org.apache.directory.api.ldap.model.message.BindRequestImpl;
34
+import org.apache.directory.api.ldap.model.message.BindResponse;
35
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
36
+import org.apache.directory.ldap.client.api.LdapConnection;
37
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
38
+import org.apache.directory.ldap.client.api.NoVerificationTrustManager;
39
+import org.junit.Before;
40
+import org.junit.Test;
41
+
42
+import net.bluemind.config.Token;
43
+import net.bluemind.core.api.fault.ServerFault;
44
+import net.bluemind.core.container.model.Item;
45
+import net.bluemind.core.container.model.ItemValue;
46
+import net.bluemind.lib.ldap.LdapConProxy;
47
+import net.bluemind.node.api.INodeClient;
48
+import net.bluemind.node.api.NCUtils;
49
+import net.bluemind.node.api.NodeActivator;
50
+import net.bluemind.pool.impl.BmConfIni;
51
+import net.bluemind.server.api.Server;
52
+import net.bluemind.system.ldap.export.LdapHelper;
53
+import net.bluemind.system.ldap.export.conf.DebSlapdConfig;
54
+
55
+public class DebSlapdConfigTests {
56
+	private String ldapRoleServerIp = new BmConfIni().get("bluemind/ldap");
57
+	private ItemValue<Server> ldapRoleServer;
58
+
59
+	@Before
60
+	public void before() throws Exception {
61
+		getLdapRoleServer();
62
+		updateUserPassword("admin0@global.virt", Token.admin0());
63
+	}
64
+
65
+	@Test
66
+	public void testSlapdConfig_initHost() throws ServerFault, IOException {
67
+		new DebSlapdConfig(ldapRoleServer).init();
68
+
69
+		try (LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer)) {
70
+			assertNotNull(ldapCon);
71
+			assertTrue(ldapCon.isConnected());
72
+			assertTrue(ldapCon.isAuthenticated());
73
+		}
74
+	}
75
+
76
+	@Test
77
+	public void testSlapdConfig_checkSaslAuth() throws ServerFault, IOException, LdapException {
78
+		updateUserPassword("test@domain.tld", "testpassword");
79
+
80
+		new DebSlapdConfig(ldapRoleServer).init();
81
+
82
+		try (LdapConnection ldapCon = LdapHelper.connectDirectory(ldapRoleServer)) {
83
+			ldapCon.add(new DefaultEntry("dc=local", "objectClass: organization", "objectClass: dcObject",
84
+					"o: BlueMind", "description: BlueMind LDAP directory"));
85
+
86
+			ldapCon.add(new DefaultEntry("uid=test,dc=local", "objectclass: inetOrgPerson", "sn: test", "cn: test",
87
+					"userPassword: {SASL}test@domain.tld"));
88
+		}
89
+
90
+		LdapConnectionConfig config = new LdapConnectionConfig();
91
+		config.setLdapHost(ldapRoleServer.value.address());
92
+		config.setLdapPort(389);
93
+		config.setUseTls(true);
94
+		config.setUseSsl(false);
95
+		config.setTrustManagers(new NoVerificationTrustManager());
96
+
97
+		config.setTimeout(10000);
98
+
99
+		ConfigurableBinaryAttributeDetector detector = new DefaultConfigurableBinaryAttributeDetector();
100
+		config.setBinaryAttributeDetector(detector);
101
+
102
+		try (LdapConnection ldapCon = new LdapConProxy(config)) {
103
+			assertNotNull(ldapCon);
104
+
105
+			BindRequest bindRequest = new BindRequestImpl();
106
+			bindRequest.setSimple(true);
107
+			bindRequest.setName("uid=test,dc=local");
108
+			bindRequest.setCredentials("testpassword");
109
+
110
+			BindResponse response = ldapCon.bind(bindRequest);
111
+			assertEquals(ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode());
112
+			assertTrue(ldapCon.isConnected());
113
+			assertTrue(ldapCon.isAuthenticated());
114
+		}
115
+	}
116
+
117
+	private void updateUserPassword(String login, String passwd) {
118
+		INodeClient nodeClient = NodeActivator.get(ldapRoleServerIp);
119
+		NCUtils.exec(nodeClient, "/usr/local/sbin/updateUserPassword.sh " + login + " " + passwd);
120
+	}
121
+
122
+	private void getLdapRoleServer() {
123
+		String uid = UUID.randomUUID().toString();
124
+
125
+		Server lrs = new Server();
126
+		lrs.ip = ldapRoleServerIp;
127
+		lrs.tags = Collections.emptyList();
128
+
129
+		ldapRoleServer = ItemValue.create(Item.create(uid, null), lrs);
130
+	}
131
+}
... ...
@@ -64,7 +64,7 @@ import net.bluemind.node.api.NCUtils;
64 64
 import net.bluemind.node.api.NodeActivator;
65 65
 import net.bluemind.pool.impl.BmConfIni;
66 66
 import net.bluemind.server.api.Server;
67
-import net.bluemind.system.ldap.export.internal.LdapHelper;
67
+import net.bluemind.system.ldap.export.LdapHelper;
68 68
 import net.bluemind.tests.defaultdata.PopulateHelper;
69 69
 
70 70
 public class LdapServerHookTests {
71 71
deleted file mode 100644
... ...
@@ -1,1186 +0,0 @@
1
-/* BEGIN LICENSE
2
-  * Copyright © Blue Mind SAS, 2012-2017
3
-  *
4
-  * This file is part of BlueMind. BlueMind is a messaging and collaborative
5
-  * solution.
6
-  *
7
-  * This program is free software; you can redistribute it and/or modify
8
-  * it under the terms of either the GNU Affero General Public License as
9
-  * published by the Free Software Foundation (version 3 of the License).
10
-  *
11
-  * This program is distributed in the hope that it will be useful,
12
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14