1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.ldaptive;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.LinkedHashSet;
29 import java.util.Optional;
30 import java.util.Set;
31 import java.util.UUID;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.bremersee.exception.ServiceException;
35 import org.bremersee.ldaptive.app.Group;
36 import org.bremersee.ldaptive.app.GroupMapper;
37 import org.bremersee.ldaptive.app.Person;
38 import org.bremersee.ldaptive.app.PersonMapper;
39 import org.bremersee.ldaptive.app.TestConfiguration;
40 import org.junit.jupiter.api.BeforeAll;
41 import org.junit.jupiter.api.Test;
42 import org.ldaptive.AddRequest;
43 import org.ldaptive.CompareRequest;
44 import org.ldaptive.DeleteRequest;
45 import org.ldaptive.FilterTemplate;
46 import org.ldaptive.LdapAttribute;
47 import org.ldaptive.LdapEntry;
48 import org.ldaptive.ModifyDnRequest;
49 import org.ldaptive.ModifyRequest;
50 import org.ldaptive.SearchRequest;
51 import org.ldaptive.SearchScope;
52 import org.ldaptive.SimpleBindRequest;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.beans.factory.annotation.Value;
55 import org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapProperties;
56 import org.springframework.boot.test.context.SpringBootTest;
57 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
58 import org.springframework.test.util.TestSocketUtils;
59
60
61
62
63
64
65 @SpringBootTest(
66 classes = {TestConfiguration.class},
67 webEnvironment = WebEnvironment.NONE,
68 properties = {
69 "spring.ldap.embedded.base-dn=dc=bremersee,dc=org",
70 "spring.ldap.embedded.credential.username=uid=admin",
71 "spring.ldap.embedded.credential.password=secret",
72 "spring.ldap.embedded.ldif=classpath:schema.ldif",
73 "spring.ldap.embedded.validation.enabled=false"
74 })
75 class LdaptiveTemplateTest {
76
77 EmbeddedLdapProperties k;
78
79 private static final Log log = LogFactory.getLog(LdaptiveTemplateTest.class);
80
81 @Value("${spring.ldap.embedded.base-dn}")
82 private String baseDn;
83
84 @Autowired
85 private LdaptiveTemplate ldaptiveTemplate;
86
87 @Autowired
88 private PersonMapper personMapper;
89
90 @Autowired
91 private GroupMapper groupMapper;
92
93
94
95
96 @BeforeAll
97 static void setEmbeddedLdapPort() {
98 int embeddedLdapPort = TestSocketUtils.findAvailableTcpPort();
99 System.setProperty("spring.ldap.embedded.port", String.valueOf(embeddedLdapPort));
100 }
101
102
103
104
105 @Test
106 void findExistingPersons() {
107 SearchRequest searchRequest = SearchRequest.builder()
108 .dn("ou=people," + baseDn)
109 .filter("(objectclass=inetOrgPerson)")
110 .scope(SearchScope.ONELEVEL)
111 .build();
112
113
114 Collection<LdapEntry> entries = ldaptiveTemplate.findAll(searchRequest);
115 entries.forEach(ldapEntry -> log.info(String.format("Ldap entry found with cn = %s",
116 ldapEntry.getAttribute("cn").getStringValue())));
117 assertTrue(entries.stream()
118 .anyMatch(entry -> "Anna Livia Plurabelle"
119 .equalsIgnoreCase(entry.getAttribute("cn").getStringValue())));
120 assertTrue(entries.stream()
121 .anyMatch(entry -> "Gustav Anias Horn"
122 .equalsIgnoreCase(entry.getAttribute("cn").getStringValue())));
123 assertTrue(entries.stream()
124 .anyMatch(entry -> "Hans Castorp"
125 .equalsIgnoreCase(entry.getAttribute("cn").getStringValue())));
126
127
128 assertTrue(ldaptiveTemplate.findAll(searchRequest, personMapper)
129 .anyMatch(entry -> "Anna Livia Plurabelle"
130 .equalsIgnoreCase(entry.getCn())));
131 assertTrue(ldaptiveTemplate.findAll(searchRequest, personMapper)
132 .anyMatch(entry -> "Gustav Anias Horn"
133 .equalsIgnoreCase(entry.getCn())));
134 assertTrue(ldaptiveTemplate.findAll(searchRequest, personMapper)
135 .anyMatch(entry -> "Hans Castorp"
136 .equalsIgnoreCase(entry.getCn())));
137 }
138
139
140
141
142 @Test
143 void findExistingGroups() {
144 SearchRequest searchRequest = SearchRequest.builder()
145 .dn("ou=groups," + baseDn)
146 .filter("(objectclass=groupOfUniqueNames)")
147 .scope(SearchScope.ONELEVEL)
148 .build();
149
150
151 Collection<LdapEntry> entries = ldaptiveTemplate.findAll(searchRequest);
152 entries.forEach(ldapEntry -> log.info(String.format("Ldap entry found with cn = %s",
153 ldapEntry.getAttribute("cn").getStringValue())));
154 assertTrue(entries.stream()
155 .anyMatch(entry -> "developers"
156 .equalsIgnoreCase(entry.getAttribute("cn").getStringValue())));
157 assertTrue(entries.stream()
158 .anyMatch(entry -> "managers"
159 .equalsIgnoreCase(entry.getAttribute("cn").getStringValue())));
160
161
162 assertTrue(ldaptiveTemplate.findAll(searchRequest, groupMapper)
163 .anyMatch(entry -> "developers"
164 .equalsIgnoreCase(entry.getCn())));
165 assertTrue(ldaptiveTemplate.findAll(searchRequest, groupMapper)
166 .anyMatch(entry -> "managers"
167 .equalsIgnoreCase(entry.getCn())));
168 }
169
170
171
172
173 @Test
174 void findOneAndExpectSizeLimitExceeded() {
175 SearchRequest searchRequest = SearchRequest.builder()
176 .dn("ou=people," + baseDn)
177 .filter(FilterTemplate.builder()
178 .filter("(objectclass=inetOrgPerson)")
179 .build())
180 .scope(SearchScope.ONELEVEL)
181 .sizeLimit(1)
182 .build();
183
184 assertThrows(LdaptiveException.class, () -> ldaptiveTemplate.findOne(searchRequest));
185 }
186
187
188
189
190 @Test
191 void findExistingPerson() {
192 SearchRequest searchRequest = SearchRequest.builder()
193 .dn("ou=people," + baseDn)
194 .filter(FilterTemplate.builder()
195 .filter("(&(objectclass=inetOrgPerson)(uid={0}))")
196 .parameters("anna")
197 .build())
198 .scope(SearchScope.ONELEVEL)
199 .sizeLimit(1)
200 .build();
201
202 Optional<LdapEntry> entry = ldaptiveTemplate.findOne(searchRequest);
203 assertTrue(entry.isPresent());
204 assertEquals("anna", entry.get().getAttribute("uid").getStringValue());
205
206 Optional<Person> person = ldaptiveTemplate.findOne(searchRequest, personMapper);
207 assertTrue(person.isPresent());
208 assertEquals("anna", person.get().getUid());
209 }
210
211
212
213
214 @Test
215 void findExistingPersonByDn() {
216 String dn = "uid=anna,ou=people," + baseDn;
217 Optional<LdapEntry> entry = ldaptiveTemplate
218 .findOne(SearchRequest.objectScopeSearchRequest(dn));
219 assertTrue(entry.isPresent());
220 }
221
222
223
224
225 @Test
226 void findNonExistingPerson() {
227 SearchRequest searchRequest = SearchRequest.builder()
228 .dn("ou=people," + baseDn)
229 .filter(FilterTemplate.builder()
230 .filter("(&(objectclass=inetOrgPerson)(uid={0}))")
231 .parameters(UUID.randomUUID().toString().replace("-", ""))
232 .build())
233 .scope(SearchScope.ONELEVEL)
234 .build();
235
236 Optional<LdapEntry> entry = ldaptiveTemplate.findOne(searchRequest);
237 assertFalse(entry.isPresent());
238 }
239
240
241
242
243 @Test
244 void findNonExistingPersonByDn() {
245 String uid = UUID.randomUUID().toString().replace("-", "");
246 String dn = "uid=" + uid + ",ou=people," + baseDn;
247 Optional<LdapEntry> entry = ldaptiveTemplate
248 .findOne(SearchRequest.objectScopeSearchRequest(dn));
249 assertFalse(entry.isPresent());
250 }
251
252
253
254
255 @Test
256 void generateUserPasswordAndBind() {
257 String dn = "uid=anna,ou=people," + baseDn;
258
259 String initPasswd = ldaptiveTemplate.generateUserPassword(dn);
260 assertNotNull(initPasswd);
261
262 String newPasswd = initPasswd + "Pass1234";
263 ldaptiveTemplate.modifyUserPassword(dn, initPasswd, newPasswd);
264
265 boolean success = ldaptiveTemplate.bind(SimpleBindRequest.builder()
266 .dn(dn)
267 .password(newPasswd)
268 .build());
269 assertTrue(success);
270
271 success = ldaptiveTemplate.bind(SimpleBindRequest.builder()
272 .dn(dn)
273 .password(initPasswd + "f")
274 .build());
275 assertFalse(success);
276 }
277
278
279
280
281 @Test
282 void setUserPasswordFails() {
283 String dn = "uid=hans,ou=people," + baseDn;
284
285 String initPasswd = ldaptiveTemplate.generateUserPassword(dn);
286 assertNotNull(initPasswd);
287
288 String newPasswd = initPasswd + "Pass1234";
289 assertThrows(ServiceException.class, () -> ldaptiveTemplate
290 .modifyUserPassword(dn, "wrong", newPasswd));
291 }
292
293
294
295
296 @Test
297 void existsGroup() {
298 Group group = new Group();
299 group.setCn("developers");
300 assertTrue(ldaptiveTemplate.exists(group, groupMapper));
301 group.setCn("na");
302 assertFalse(ldaptiveTemplate.exists(group, groupMapper));
303 }
304
305
306
307
308 @Test
309 void compareGroup() {
310 Group group = new Group();
311 group.setCn("developers");
312
313 assertTrue(ldaptiveTemplate.compare(CompareRequest.builder()
314 .dn(groupMapper.mapDn(group))
315 .name("ou")
316 .value("developer")
317 .build()));
318
319 assertFalse(ldaptiveTemplate.compare(CompareRequest.builder()
320 .dn(groupMapper.mapDn(group))
321 .name("ou")
322 .value("manager")
323 .build()));
324
325 assertFalse(ldaptiveTemplate.compare(CompareRequest.builder()
326 .dn(groupMapper.mapDn(group))
327 .name("notexists")
328 .value("manager")
329 .build()));
330
331 group.setCn("notexists");
332 CompareRequest cr = CompareRequest.builder()
333 .dn(groupMapper.mapDn(group))
334 .name("ou")
335 .value("developer")
336 .build();
337 assertThrows(ServiceException.class, () -> ldaptiveTemplate.compare(cr));
338 }
339
340
341
342
343 @Test
344 void addAndModifyAndDeletePerson() {
345 Person person = new Person();
346 person.setCn("A person");
347 person.setSn("Person");
348 person.setUid("person");
349
350 String dn = personMapper.mapDn(person);
351 LdapEntry destination = new LdapEntry();
352 personMapper.map(person, destination);
353 destination.setDn(dn);
354 destination.addAttributes(new LdapAttribute(
355 "objectclass",
356 personMapper.getObjectClasses()));
357 ldaptiveTemplate.add(new AddRequest(dn, destination.getAttributes()));
358 assertTrue(ldaptiveTemplate.exists(person, personMapper));
359
360 person.setSn("Surname");
361 ModifyRequest modifyRequest = personMapper
362 .mapAndComputeModifyRequest(person, destination)
363 .orElseThrow();
364 ldaptiveTemplate.modify(modifyRequest);
365
366 person = ldaptiveTemplate.findOne(SearchRequest.objectScopeSearchRequest(dn), personMapper)
367 .orElseThrow(() -> ServiceException.notFound("Person", "person"));
368 assertEquals("Surname", person.getSn());
369
370 person.setSn("");
371 modifyRequest = personMapper
372 .mapAndComputeModifyRequest(person, destination)
373 .orElseThrow();
374 ldaptiveTemplate.modify(modifyRequest);
375
376 person = ldaptiveTemplate.findOne(SearchRequest.objectScopeSearchRequest(dn), personMapper)
377 .orElseThrow(() -> ServiceException.notFound("Person", "person"));
378 assertNull(person.getSn());
379
380 ldaptiveTemplate.delete(new DeleteRequest(dn));
381 assertFalse(ldaptiveTemplate.exists(person, personMapper));
382 }
383
384
385
386
387 @Test
388 void saveAndRemoveGroup() {
389 Group group = new Group();
390 group.setCn("party");
391 group.setOu("Party Guests");
392
393 Set<String> members = new LinkedHashSet<>();
394 members.add("uid=anna,ou=people," + baseDn);
395 group.setMembers(members);
396
397 group = ldaptiveTemplate.save(group, groupMapper);
398 assertNotNull(group);
399
400 SearchRequest searchRequest = SearchRequest.builder()
401 .dn("ou=groups," + baseDn)
402 .filter(FilterTemplate.builder()
403 .filter("(&(objectclass=groupOfUniqueNames)(cn={0}))")
404 .parameters("party")
405 .build())
406 .scope(SearchScope.ONELEVEL)
407 .build();
408
409 group = ldaptiveTemplate.findOne(searchRequest, groupMapper)
410 .orElseThrow(() -> ServiceException.notFound("Group", "party"));
411 assertEquals("party", group.getCn());
412 assertEquals("Party Guests", group.getOu());
413 assertTrue(group.getMembers().contains("uid=anna,ou=people," + baseDn));
414
415 group.getMembers().add("uid=hans,ou=people," + baseDn);
416 group.getMembers().add("uid=gustav,ou=people," + baseDn);
417 group = ldaptiveTemplate.save(group, groupMapper);
418 assertNotNull(group);
419
420 group = ldaptiveTemplate.findOne(searchRequest, groupMapper)
421 .orElseThrow(() -> ServiceException.notFound("Group", "party"));
422 assertEquals("party", group.getCn());
423 assertEquals("Party Guests", group.getOu());
424 assertTrue(group.getMembers().contains("uid=anna,ou=people," + baseDn));
425 assertTrue(group.getMembers().contains("uid=hans,ou=people," + baseDn));
426 assertTrue(group.getMembers().contains("uid=gustav,ou=people," + baseDn));
427
428 group.getMembers().remove("uid=hans,ou=people," + baseDn);
429 group = ldaptiveTemplate.save(group, groupMapper);
430 assertNotNull(group);
431
432 group = ldaptiveTemplate.findOne(searchRequest, groupMapper)
433 .orElseThrow(() -> ServiceException.notFound("Group", "party"));
434 assertEquals("party", group.getCn());
435 assertEquals("Party Guests", group.getOu());
436 assertTrue(group.getMembers().contains("uid=anna,ou=people," + baseDn));
437 assertTrue(group.getMembers().contains("uid=gustav,ou=people," + baseDn));
438 assertFalse(group.getMembers().contains("uid=hans,ou=people," + baseDn));
439
440 ldaptiveTemplate.remove(group, groupMapper);
441 assertFalse(ldaptiveTemplate.exists(group, groupMapper));
442 }
443
444
445
446
447 @Test
448 void saveAndRemovePersons() {
449 Person p0 = new Person();
450 p0.setCn("Person Number 0");
451 p0.setSn("Person 0");
452 p0.setUid("person0");
453 Person p1 = new Person();
454 p1.setCn("Person Number 1");
455 p1.setSn("Person 1");
456 p1.setUid("person1");
457 Person p2 = new Person();
458 p2.setCn("Person Number 2");
459 p2.setSn("Person 2");
460 p2.setUid("person2");
461
462 ldaptiveTemplate.saveAll(Arrays.asList(p0, p1, p2), personMapper)
463 .forEach(person -> log.info(String.format("New person: %s", person)));
464 assertTrue(ldaptiveTemplate.exists(p0, personMapper));
465 assertTrue(ldaptiveTemplate.exists(p1, personMapper));
466 assertTrue(ldaptiveTemplate.exists(p2, personMapper));
467
468 ldaptiveTemplate.removeAll(Arrays.asList(p0, p1, p2), personMapper);
469 assertFalse(ldaptiveTemplate.exists(p0, personMapper));
470 assertFalse(ldaptiveTemplate.exists(p1, personMapper));
471 assertFalse(ldaptiveTemplate.exists(p2, personMapper));
472 }
473
474
475
476
477 @Test
478 void modifyDn() {
479 Person p0 = new Person();
480 p0.setCn("Gottfried");
481 p0.setSn("Benn");
482 p0.setUid("benn");
483
484 p0 = ldaptiveTemplate.save(p0, personMapper);
485 assertNotNull(p0);
486
487 ldaptiveTemplate.modifyDn(ModifyDnRequest.builder()
488 .oldDN(personMapper.mapDn(p0))
489 .newRDN("uid=gbn")
490 .delete(true)
491 .build());
492
493 Optional<Person> pr = ldaptiveTemplate.findAll(
494 SearchRequest.builder()
495 .dn("ou=people," + baseDn)
496 .filter("(sn=Benn)")
497 .build(),
498 personMapper)
499 .filter(p -> "gbn".equals(p.getUid()))
500 .findAny();
501 assertTrue(pr.isPresent());
502
503 ldaptiveTemplate.delete(DeleteRequest.builder().dn(personMapper.mapDn(pr.get())).build());
504 }
505
506
507
508
509 @Test
510 void testCopy() {
511 LdaptiveTemplate clone = ldaptiveTemplate.copy();
512 clone.setErrorHandler(new DefaultLdaptiveErrorHandler());
513 Group group = new Group();
514 group.setCn("developers");
515 assertTrue(clone.exists(group, groupMapper));
516 group.setCn("na");
517 assertFalse(clone.exists(group, groupMapper));
518 }
519
520 }