1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.fit.core;
20
21 import static org.awaitility.Awaitility.await;
22 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
23 import static org.junit.jupiter.api.Assertions.assertEquals;
24 import static org.junit.jupiter.api.Assertions.assertFalse;
25 import static org.junit.jupiter.api.Assertions.assertNotEquals;
26 import static org.junit.jupiter.api.Assertions.assertNotNull;
27 import static org.junit.jupiter.api.Assertions.assertNull;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.junit.jupiter.api.Assertions.fail;
30 import static org.junit.jupiter.api.Assumptions.assumeFalse;
31
32 import java.io.IOException;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import java.util.UUID;
37 import java.util.concurrent.TimeUnit;
38 import java.util.concurrent.atomic.AtomicReference;
39 import javax.naming.NamingEnumeration;
40 import javax.naming.NamingException;
41 import javax.naming.directory.DirContext;
42 import javax.naming.directory.SearchControls;
43 import javax.naming.directory.SearchResult;
44 import javax.ws.rs.ForbiddenException;
45 import javax.ws.rs.core.GenericType;
46 import javax.ws.rs.core.Response;
47 import org.apache.commons.lang3.SerializationUtils;
48 import org.apache.syncope.client.lib.SyncopeClient;
49 import org.apache.syncope.common.lib.AnyOperations;
50 import org.apache.syncope.common.lib.Attr;
51 import org.apache.syncope.common.lib.EntityTOUtils;
52 import org.apache.syncope.common.lib.SyncopeClientException;
53 import org.apache.syncope.common.lib.SyncopeConstants;
54 import org.apache.syncope.common.lib.request.AnyObjectCR;
55 import org.apache.syncope.common.lib.request.AnyObjectUR;
56 import org.apache.syncope.common.lib.request.AttrPatch;
57 import org.apache.syncope.common.lib.request.GroupCR;
58 import org.apache.syncope.common.lib.request.GroupUR;
59 import org.apache.syncope.common.lib.request.ResourceAR;
60 import org.apache.syncope.common.lib.request.ResourceDR;
61 import org.apache.syncope.common.lib.request.StringPatchItem;
62 import org.apache.syncope.common.lib.request.StringReplacePatchItem;
63 import org.apache.syncope.common.lib.request.UserCR;
64 import org.apache.syncope.common.lib.to.AnyObjectTO;
65 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
66 import org.apache.syncope.common.lib.to.AnyTypeTO;
67 import org.apache.syncope.common.lib.to.ConnInstanceTO;
68 import org.apache.syncope.common.lib.to.ConnObject;
69 import org.apache.syncope.common.lib.to.DerSchemaTO;
70 import org.apache.syncope.common.lib.to.ExecTO;
71 import org.apache.syncope.common.lib.to.GroupTO;
72 import org.apache.syncope.common.lib.to.Item;
73 import org.apache.syncope.common.lib.to.Mapping;
74 import org.apache.syncope.common.lib.to.MembershipTO;
75 import org.apache.syncope.common.lib.to.PagedResult;
76 import org.apache.syncope.common.lib.to.PlainSchemaTO;
77 import org.apache.syncope.common.lib.to.PropagationStatus;
78 import org.apache.syncope.common.lib.to.Provision;
79 import org.apache.syncope.common.lib.to.ProvisioningResult;
80 import org.apache.syncope.common.lib.to.ResourceTO;
81 import org.apache.syncope.common.lib.to.TypeExtensionTO;
82 import org.apache.syncope.common.lib.to.UserTO;
83 import org.apache.syncope.common.lib.types.AnyTypeKind;
84 import org.apache.syncope.common.lib.types.AttrSchemaType;
85 import org.apache.syncope.common.lib.types.CipherAlgorithm;
86 import org.apache.syncope.common.lib.types.ClientExceptionType;
87 import org.apache.syncope.common.lib.types.ConnectorCapability;
88 import org.apache.syncope.common.lib.types.ExecStatus;
89 import org.apache.syncope.common.lib.types.MappingPurpose;
90 import org.apache.syncope.common.lib.types.PatchOperation;
91 import org.apache.syncope.common.lib.types.ProvisionAction;
92 import org.apache.syncope.common.lib.types.ResourceAssociationAction;
93 import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
94 import org.apache.syncope.common.lib.types.SchemaType;
95 import org.apache.syncope.common.lib.types.TaskType;
96 import org.apache.syncope.common.rest.api.beans.AnyQuery;
97 import org.apache.syncope.common.rest.api.service.GroupService;
98 import org.apache.syncope.common.rest.api.service.SyncopeService;
99 import org.apache.syncope.core.provisioning.java.job.TaskJob;
100 import org.apache.syncope.core.spring.security.Encryptor;
101 import org.apache.syncope.fit.AbstractITCase;
102 import org.junit.jupiter.api.Assertions;
103 import org.junit.jupiter.api.Test;
104
105 public class GroupITCase extends AbstractITCase {
106
107 public static GroupCR getBasicSample(final String name) {
108 return new GroupCR.Builder(SyncopeConstants.ROOT_REALM, name + getUUIDString()).build();
109 }
110
111 public static GroupCR getSample(final String name) {
112 GroupCR groupCR = getBasicSample(name);
113
114 groupCR.getPlainAttrs().add(attr("icon", "anIcon"));
115
116 groupCR.getResources().add(RESOURCE_NAME_LDAP);
117 return groupCR;
118 }
119
120 @Test
121 public void create() {
122 GroupCR groupCR = getSample("lastGroup");
123 groupCR.getVirAttrs().add(attr("rvirtualdata", "rvirtualvalue"));
124 groupCR.setGroupOwner("f779c0d4-633b-4be5-8f57-32eb478a3ca5");
125
126 GroupTO groupTO = createGroup(groupCR).getEntity();
127 assertNotNull(groupTO);
128
129 assertNotNull(groupTO.getVirAttr("rvirtualdata").get().getValues());
130 assertFalse(groupTO.getVirAttr("rvirtualdata").get().getValues().isEmpty());
131 assertEquals("rvirtualvalue", groupTO.getVirAttr("rvirtualdata").get().getValues().get(0));
132
133 assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP));
134
135 ConnObject connObjectTO =
136 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
137 assertNotNull(connObjectTO);
138 assertNotNull(connObjectTO.getAttr("owner"));
139
140
141 GroupUR groupUR = new GroupUR();
142 groupUR.setKey(groupTO.getKey());
143 groupUR.setGroupOwner(new StringReplacePatchItem());
144
145 assertNull(updateGroup(groupUR).getEntity().getGroupOwner());
146 }
147
148 @Test
149 public void createWithInternationalCharacters() {
150 GroupCR groupCR = getSample("räksmörgås");
151
152 GroupTO groupTO = createGroup(groupCR).getEntity();
153 assertNotNull(groupTO);
154 }
155
156 @Test
157 public void delete() {
158 try {
159 GROUP_SERVICE.delete(UUID.randomUUID().toString());
160 } catch (SyncopeClientException e) {
161 assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
162 }
163
164 GroupCR groupCR = new GroupCR();
165 groupCR.setName("toBeDeleted" + getUUIDString());
166 groupCR.setRealm("/even");
167
168 groupCR.getResources().add(RESOURCE_NAME_LDAP);
169
170 GroupTO groupTO = createGroup(groupCR).getEntity();
171 assertNotNull(groupTO);
172
173 GroupTO deletedGroup = deleteGroup(groupTO.getKey()).getEntity();
174 assertNotNull(deletedGroup);
175
176 try {
177 GROUP_SERVICE.read(deletedGroup.getKey());
178 } catch (SyncopeClientException e) {
179 assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
180 }
181 }
182
183 @Test
184 public void list() {
185 PagedResult<GroupTO> groupTOs =
186 GROUP_SERVICE.search(new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
187 assertNotNull(groupTOs);
188 assertTrue(groupTOs.getResult().size() >= 8);
189 groupTOs.getResult().forEach(Assertions::assertNotNull);
190 }
191
192 @Test
193 public void read() {
194 GroupTO groupTO = GROUP_SERVICE.read("37d15e4c-cdc1-460b-a591-8505c8133806");
195
196 assertNotNull(groupTO);
197 assertNotNull(groupTO.getPlainAttrs());
198 assertFalse(groupTO.getPlainAttrs().isEmpty());
199 assertEquals(2, groupTO.getStaticUserMembershipCount());
200 }
201
202 @Test
203 public void selfRead() {
204 UserTO userTO = USER_SERVICE.read("1417acbe-cbf6-4277-9372-e75e04f97000");
205 assertNotNull(userTO);
206
207 assertTrue(userTO.getMembership("37d15e4c-cdc1-460b-a591-8505c8133806").isPresent());
208 assertFalse(userTO.getMembership("29f96485-729e-4d31-88a1-6fc60e4677f3").isPresent());
209
210 GroupService groupService2 = CLIENT_FACTORY.create("rossini", ADMIN_PWD).getService(GroupService.class);
211
212 try {
213 groupService2.read("29f96485-729e-4d31-88a1-6fc60e4677f3");
214 fail("This should not happen");
215 } catch (SyncopeClientException e) {
216 assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
217 }
218
219 List<GroupTO> groups = groupService2.own();
220 assertNotNull(groups);
221 assertTrue(groups.stream().anyMatch(group -> "37d15e4c-cdc1-460b-a591-8505c8133806".equals(group.getKey())));
222 }
223
224 @Test
225 public void update() {
226 GroupCR groupCR = getSample("latestGroup" + getUUIDString());
227 GroupTO groupTO = createGroup(groupCR).getEntity();
228
229 assertEquals(1, groupTO.getPlainAttrs().size());
230
231 GroupUR groupUR = new GroupUR();
232 groupUR.setKey(groupTO.getKey());
233 String modName = "finalGroup" + getUUIDString();
234 groupUR.setName(new StringReplacePatchItem.Builder().value(modName).build());
235 groupUR.getPlainAttrs().add(attrAddReplacePatch("show", "FALSE"));
236
237 groupTO = updateGroup(groupUR).getEntity();
238
239 assertEquals(modName, groupTO.getName());
240 assertEquals(2, groupTO.getPlainAttrs().size());
241
242 groupTO.getPlainAttr("show").get().getValues().clear();
243
244 groupUR = new GroupUR.Builder(groupTO.getKey()).
245 plainAttr(new AttrPatch.Builder(new Attr.Builder("show").build()).
246 operation(PatchOperation.DELETE).build()).build();
247
248 groupTO = updateGroup(groupUR).getEntity();
249
250 assertFalse(groupTO.getPlainAttr("show").isPresent());
251 }
252
253 @Test
254 public void patch() {
255 GroupCR createReq = getBasicSample("patch");
256 createReq.setUDynMembershipCond(
257 "(($groups==ebf97068-aa4b-4a85-9f01-680e8c4cf227;$resources!=ws-target-resource-1);aLong==1)");
258 createReq.getADynMembershipConds().put(
259 PRINTER,
260 "(($groups==ece66293-8f31-4a84-8e8d-23da36e70846;cool==ss);$resources==ws-target-resource-2);"
261 + "$type==PRINTER");
262
263 GroupTO created = createGroup(createReq).getEntity();
264
265 created.getPlainAttrs().add(new Attr.Builder("icon").build());
266 created.getPlainAttrs().add(new Attr.Builder("show").build());
267 created.getPlainAttrs().add(new Attr.Builder("rderived_sx").value("sx").build());
268 created.getPlainAttrs().add(new Attr.Builder("rderived_dx").value("dx").build());
269 created.getPlainAttrs().add(new Attr.Builder("title").value("mr").build());
270
271 GroupTO original = GROUP_SERVICE.read(created.getKey());
272
273 GroupUR groupUR = AnyOperations.diff(created, original, true);
274 GroupTO updated = updateGroup(groupUR).getEntity();
275
276 Map<String, Attr> attrs = EntityTOUtils.buildAttrMap(updated.getPlainAttrs());
277 assertFalse(attrs.containsKey("icon"));
278 assertFalse(attrs.containsKey("show"));
279 assertEquals(List.of("sx"), attrs.get("rderived_sx").getValues());
280 assertEquals(List.of("dx"), attrs.get("rderived_dx").getValues());
281 assertEquals(List.of("mr"), attrs.get("title").getValues());
282 }
283
284 @Test
285 public void updateAsGroupOwner() {
286
287 GroupTO groupTO = GROUP_SERVICE.read("ebf97068-aa4b-4a85-9f01-680e8c4cf227");
288
289
290 assertNotNull(groupTO.getCreationDate());
291 assertNotNull(groupTO.getLastChangeDate());
292 assertEquals("admin", groupTO.getCreator());
293 assertEquals("admin", groupTO.getLastModifier());
294
295
296 GroupUR groupUR = new GroupUR();
297 groupUR.setKey(groupTO.getKey());
298 groupUR.setName(new StringReplacePatchItem.Builder().value("Director").build());
299
300
301 GroupService groupService2 = CLIENT_FACTORY.create("verdi", ADMIN_PWD).getService(GroupService.class);
302
303 try {
304 groupService2.update(groupUR);
305 fail("This should not happen");
306 } catch (Exception e) {
307 assertNotNull(e);
308 }
309
310
311 GroupService groupService3 = CLIENT_FACTORY.create("puccini", ADMIN_PWD).getService(GroupService.class);
312
313 groupTO = groupService3.update(groupUR).readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
314 }).getEntity();
315 assertEquals("Director", groupTO.getName());
316
317
318 assertNotNull(groupTO.getCreationDate());
319 assertNotNull(groupTO.getLastChangeDate());
320 assertEquals("admin", groupTO.getCreator());
321 assertEquals("puccini", groupTO.getLastModifier());
322 assertTrue(groupTO.getCreationDate().isBefore(groupTO.getLastChangeDate()));
323 }
324
325 @Test
326 public void unlink() throws IOException {
327 GroupTO actual = createGroup(getSample("unlink")).getEntity();
328 assertNotNull(actual);
329
330 assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
331
332 ResourceDR resourceDR = new ResourceDR.Builder().key(actual.getKey()).
333 action(ResourceDeassociationAction.UNLINK).resource(RESOURCE_NAME_LDAP).build();
334
335 assertNotNull(parseBatchResponse(GROUP_SERVICE.deassociate(resourceDR)));
336
337 actual = GROUP_SERVICE.read(actual.getKey());
338 assertNotNull(actual);
339 assertTrue(actual.getResources().isEmpty());
340
341 assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
342 }
343
344 @Test
345 public void link() throws IOException {
346 GroupCR groupCR = getSample("link");
347 groupCR.getResources().clear();
348
349 GroupTO actual = createGroup(groupCR).getEntity();
350 assertNotNull(actual);
351
352 try {
353 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
354 fail("This should not happen");
355 } catch (Exception e) {
356 assertNotNull(e);
357 }
358
359 ResourceAR resourceAR = new ResourceAR.Builder().key(actual.getKey()).
360 action(ResourceAssociationAction.LINK).resource(RESOURCE_NAME_LDAP).build();
361
362 assertNotNull(parseBatchResponse(GROUP_SERVICE.associate(resourceAR)));
363
364 actual = GROUP_SERVICE.read(actual.getKey());
365 assertFalse(actual.getResources().isEmpty());
366
367 try {
368 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
369 fail("This should not happen");
370 } catch (Exception e) {
371 assertNotNull(e);
372 }
373 }
374
375 @Test
376 public void unassign() throws IOException {
377 GroupTO groupTO = null;
378
379 try {
380 groupTO = createGroup(getSample("unassign")).getEntity();
381 assertNotNull(groupTO);
382
383 assertNotNull(RESOURCE_SERVICE.readConnObject(
384 RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey()));
385
386 ResourceDR resourceDR = new ResourceDR();
387 resourceDR.setKey(groupTO.getKey());
388 resourceDR.setAction(ResourceDeassociationAction.UNASSIGN);
389 resourceDR.getResources().add(RESOURCE_NAME_LDAP);
390
391 assertNotNull(parseBatchResponse(GROUP_SERVICE.deassociate(resourceDR)));
392
393 groupTO = GROUP_SERVICE.read(groupTO.getKey());
394 assertNotNull(groupTO);
395 assertTrue(groupTO.getResources().isEmpty());
396
397 try {
398 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
399 fail("This should not happen");
400 } catch (Exception e) {
401 assertNotNull(e);
402 }
403 } finally {
404 if (groupTO != null) {
405 GROUP_SERVICE.delete(groupTO.getKey());
406 }
407 }
408 }
409
410 @Test
411 public void assign() throws IOException {
412 GroupCR groupCR = getSample("assign");
413 groupCR.getResources().clear();
414
415 GroupTO groupTO = null;
416 try {
417 groupTO = createGroup(groupCR).getEntity();
418 assertNotNull(groupTO);
419
420 try {
421 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
422 fail("This should not happen");
423 } catch (Exception e) {
424 assertNotNull(e);
425 }
426
427 ResourceAR resourceAR = new ResourceAR.Builder().key(groupTO.getKey()).
428 action(ResourceAssociationAction.ASSIGN).resource(RESOURCE_NAME_LDAP).build();
429
430 assertNotNull(parseBatchResponse(GROUP_SERVICE.associate(resourceAR)));
431
432 groupTO = GROUP_SERVICE.read(groupTO.getKey());
433 assertFalse(groupTO.getResources().isEmpty());
434 assertNotNull(RESOURCE_SERVICE.readConnObject(
435 RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey()));
436 } finally {
437 if (groupTO != null) {
438 GROUP_SERVICE.delete(groupTO.getKey());
439 }
440 }
441 }
442
443 @Test
444 public void deprovision() throws IOException {
445 GroupTO groupTO = null;
446
447 try {
448 groupTO = createGroup(getSample("deprovision")).getEntity();
449 assertNotNull(groupTO);
450 assertNotNull(groupTO.getKey());
451
452 assertNotNull(
453 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey()));
454
455 ResourceDR resourceDR = new ResourceDR.Builder().key(groupTO.getKey()).
456 action(ResourceDeassociationAction.DEPROVISION).resource(RESOURCE_NAME_LDAP).build();
457
458 assertNotNull(parseBatchResponse(GROUP_SERVICE.deassociate(resourceDR)));
459
460 groupTO = GROUP_SERVICE.read(groupTO.getKey());
461 assertNotNull(groupTO);
462 assertFalse(groupTO.getResources().isEmpty());
463
464 try {
465 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
466 fail("This should not happen");
467 } catch (Exception e) {
468 assertNotNull(e);
469 }
470 } finally {
471 if (groupTO != null) {
472 GROUP_SERVICE.delete(groupTO.getKey());
473 }
474 }
475 }
476
477 @Test
478 public void provision() throws IOException {
479 GroupCR groupCR = getSample("provision");
480 groupCR.getResources().clear();
481
482 GroupTO groupTO = null;
483 try {
484 groupTO = createGroup(groupCR).getEntity();
485 assertNotNull(groupTO);
486
487 try {
488 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
489 fail("This should not happen");
490 } catch (Exception e) {
491 assertNotNull(e);
492 }
493
494 ResourceAR resourceAR = new ResourceAR.Builder().key(groupTO.getKey()).
495 action(ResourceAssociationAction.PROVISION).resource(RESOURCE_NAME_LDAP).build();
496
497 assertNotNull(parseBatchResponse(GROUP_SERVICE.associate(resourceAR)));
498
499 groupTO = GROUP_SERVICE.read(groupTO.getKey());
500 assertTrue(groupTO.getResources().isEmpty());
501
502 assertNotNull(RESOURCE_SERVICE.readConnObject(
503 RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey()));
504 } finally {
505 if (groupTO != null) {
506 GROUP_SERVICE.delete(groupTO.getKey());
507 }
508 }
509 }
510
511 @Test
512 public void deprovisionUnlinked() throws IOException {
513 GroupCR groupCR = getSample("deprovision");
514 groupCR.getResources().clear();
515
516 GroupTO groupTO = null;
517 try {
518 groupTO = createGroup(groupCR).getEntity();
519 assertNotNull(groupTO);
520
521 try {
522 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
523 fail("This should not happen");
524 } catch (Exception e) {
525 assertNotNull(e);
526 }
527
528 ResourceAR resourceAR = new ResourceAR.Builder().key(groupTO.getKey()).
529 action(ResourceAssociationAction.PROVISION).resource(RESOURCE_NAME_LDAP).build();
530
531 assertNotNull(parseBatchResponse(GROUP_SERVICE.associate(resourceAR)));
532
533 groupTO = GROUP_SERVICE.read(groupTO.getKey());
534 assertTrue(groupTO.getResources().isEmpty());
535
536 assertNotNull(RESOURCE_SERVICE.readConnObject(
537 RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey()));
538
539 ResourceDR resourceDR = new ResourceDR.Builder().key(groupTO.getKey()).
540 action(ResourceDeassociationAction.DEPROVISION).resource(RESOURCE_NAME_LDAP).build();
541
542 assertNotNull(parseBatchResponse(GROUP_SERVICE.deassociate(resourceDR)));
543
544 groupTO = GROUP_SERVICE.read(groupTO.getKey());
545 assertNotNull(groupTO);
546 assertTrue(groupTO.getResources().isEmpty());
547
548 try {
549 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
550 fail("This should not happen");
551 } catch (Exception e) {
552 assertNotNull(e);
553 }
554 } finally {
555 if (groupTO != null) {
556 GROUP_SERVICE.delete(groupTO.getKey());
557 }
558 }
559 }
560
561 @Test
562 public void createWithMandatorySchema() {
563
564 PlainSchemaTO badge = new PlainSchemaTO();
565 badge.setKey("badge" + getUUIDString());
566 badge.setMandatoryCondition("true");
567 SCHEMA_SERVICE.create(SchemaType.PLAIN, badge);
568
569
570 GroupCR groupCR = getSample("lastGroup");
571 GroupTO groupTO = createGroup(groupCR).getEntity();
572 assertNotNull(groupTO);
573 assertFalse(groupTO.getPlainAttr(badge.getKey()).isPresent());
574
575
576 AnyTypeTO type = ANY_TYPE_SERVICE.read(AnyTypeKind.GROUP.name());
577 String typeClassName = type.getClasses().get(0);
578 AnyTypeClassTO typeClass = ANY_TYPE_CLASS_SERVICE.read(typeClassName);
579 typeClass.getPlainSchemas().add(badge.getKey());
580 ANY_TYPE_CLASS_SERVICE.update(typeClass);
581 typeClass = ANY_TYPE_CLASS_SERVICE.read(typeClassName);
582 assertTrue(typeClass.getPlainSchemas().contains(badge.getKey()));
583
584 try {
585
586 GroupUR groupUR = new GroupUR();
587 groupUR.setKey(groupTO.getKey());
588
589 try {
590 updateGroup(groupUR);
591 fail("This should not happen");
592 } catch (SyncopeClientException e) {
593 assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
594 }
595
596
597 groupUR.getPlainAttrs().add(attrAddReplacePatch(badge.getKey(), "xxxxxxxxxx"));
598
599 groupTO = updateGroup(groupUR).getEntity();
600 assertNotNull(groupTO);
601 assertNotNull(groupTO.getPlainAttr(badge.getKey()));
602 } finally {
603
604 typeClass.getPlainSchemas().remove(badge.getKey());
605 ANY_TYPE_CLASS_SERVICE.update(typeClass);
606 typeClass = ANY_TYPE_CLASS_SERVICE.read(typeClassName);
607 assertFalse(typeClass.getPlainSchemas().contains(badge.getKey()));
608 }
609 }
610
611 @Test
612 public void encrypted() throws Exception {
613
614 PlainSchemaTO encrypted = new PlainSchemaTO();
615 encrypted.setKey("encrypted" + getUUIDString());
616 encrypted.setType(AttrSchemaType.Encrypted);
617 encrypted.setCipherAlgorithm(CipherAlgorithm.SHA512);
618 encrypted.setSecretKey("${obscureSecretKey}");
619 SCHEMA_SERVICE.create(SchemaType.PLAIN, encrypted);
620
621
622 AnyTypeTO type = ANY_TYPE_SERVICE.read(AnyTypeKind.GROUP.name());
623 String typeClassName = type.getClasses().get(0);
624 AnyTypeClassTO typeClass = ANY_TYPE_CLASS_SERVICE.read(typeClassName);
625 typeClass.getPlainSchemas().add(encrypted.getKey());
626 ANY_TYPE_CLASS_SERVICE.update(typeClass);
627 typeClass = ANY_TYPE_CLASS_SERVICE.read(typeClassName);
628 assertTrue(typeClass.getPlainSchemas().contains(encrypted.getKey()));
629
630
631 GroupCR groupCR = getSample("encrypted");
632 groupCR.getPlainAttrs().add(new Attr.Builder(encrypted.getKey()).value("testvalue").build());
633 GroupTO group = createGroup(groupCR).getEntity();
634
635 assertEquals(Encryptor.getInstance(System.getProperty("obscureSecretKey")).
636 encode("testvalue", encrypted.getCipherAlgorithm()),
637 group.getPlainAttr(encrypted.getKey()).get().getValues().get(0));
638
639
640 encrypted.setAnyTypeClass(typeClassName);
641 encrypted.setCipherAlgorithm(CipherAlgorithm.AES);
642 encrypted.setConversionPattern(SyncopeConstants.ENCRYPTED_DECODE_CONVERSION_PATTERN);
643 SCHEMA_SERVICE.update(SchemaType.PLAIN, encrypted);
644
645
646 GroupUR groupUR = new GroupUR();
647 groupUR.setKey(group.getKey());
648 groupUR.getPlainAttrs().add(new AttrPatch.Builder(
649 new Attr.Builder(encrypted.getKey()).value("testvalue").build()).build());
650 group = updateGroup(groupUR).getEntity();
651
652 assertEquals("testvalue", group.getPlainAttr(encrypted.getKey()).get().getValues().get(0));
653
654
655 encrypted.setConversionPattern(null);
656 SCHEMA_SERVICE.update(SchemaType.PLAIN, encrypted);
657
658 group = GROUP_SERVICE.read(group.getKey());
659 assertNotEquals("testvalue", group.getPlainAttr(encrypted.getKey()).get().getValues().get(0));
660 }
661
662 @Test
663 public void anonymous() {
664 try {
665 ANONYMOUS_CLIENT.getService(GroupService.class).
666 search(new AnyQuery.Builder().realm("/even").build());
667 fail("This should not happen");
668 } catch (ForbiddenException e) {
669 assertNotNull(e);
670 }
671
672 assertFalse(ANONYMOUS_CLIENT.getService(SyncopeService.class).
673 searchAssignableGroups("/even", null, 1, 100).getResult().isEmpty());
674 }
675
676 @Test
677 public void uDynMembership() {
678 assertTrue(USER_SERVICE.read("c9b2dec2-00a7-4855-97c0-d854842b4b24").getDynMemberships().isEmpty());
679
680 GroupCR groupCR = getBasicSample("uDynMembership");
681 groupCR.setUDynMembershipCond("cool==true");
682 GroupTO group = null;
683 try {
684 group = createGroup(groupCR).getEntity();
685 assertNotNull(group);
686 String groupKey = group.getKey();
687
688 List<MembershipTO> memberships =
689 USER_SERVICE.read("c9b2dec2-00a7-4855-97c0-d854842b4b24").getDynMemberships();
690 assertTrue(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
691 assertEquals(1, GROUP_SERVICE.read(group.getKey()).getDynamicUserMembershipCount());
692
693 GROUP_SERVICE.update(new GroupUR.Builder(group.getKey()).udynMembershipCond("cool==false").build());
694
695 assertTrue(USER_SERVICE.read("c9b2dec2-00a7-4855-97c0-d854842b4b24").getDynMemberships().isEmpty());
696 assertEquals(0, GROUP_SERVICE.read(group.getKey()).getDynamicUserMembershipCount());
697 } finally {
698 if (group != null) {
699 GROUP_SERVICE.delete(group.getKey());
700 }
701 }
702 }
703
704 @Test
705 public void aDynMembership() {
706 String fiql = SyncopeClient.getAnyObjectSearchConditionBuilder(PRINTER).is("location").notNullValue().query();
707
708
709 GroupCR groupCR = getBasicSample("aDynMembership");
710 groupCR.getADynMembershipConds().put(PRINTER, fiql);
711 GroupTO group = createGroup(groupCR).getEntity();
712 assertEquals(fiql, group.getADynMembershipConds().get(PRINTER));
713
714 if (IS_EXT_SEARCH_ENABLED) {
715 try {
716 Thread.sleep(2000);
717 } catch (InterruptedException ex) {
718
719 }
720 }
721
722 group = GROUP_SERVICE.read(group.getKey());
723 String groupKey = group.getKey();
724 assertEquals(fiql, group.getADynMembershipConds().get(PRINTER));
725
726
727 AnyObjectCR newAnyCR = AnyObjectITCase.getSample("aDynMembership");
728 newAnyCR.getResources().clear();
729 AnyObjectTO newAny = createAnyObject(newAnyCR).getEntity();
730 assertNotNull(newAny.getPlainAttr("location"));
731 List<MembershipTO> memberships = ANY_OBJECT_SERVICE.read(
732 "fc6dbc3a-6c07-4965-8781-921e7401a4a5").getDynMemberships();
733 assertTrue(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
734
735 memberships = ANY_OBJECT_SERVICE.read(
736 "8559d14d-58c2-46eb-a2d4-a7d35161e8f8").getDynMemberships();
737 assertTrue(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
738
739 memberships = ANY_OBJECT_SERVICE.read(newAny.getKey()).getDynMemberships();
740 assertTrue(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
741
742
743 fiql = SyncopeClient.getAnyObjectSearchConditionBuilder(PRINTER).is("location").nullValue().query();
744
745 GroupUR groupUR = new GroupUR();
746 groupUR.setKey(group.getKey());
747 groupUR.getADynMembershipConds().put(PRINTER, fiql);
748
749 group = updateGroup(groupUR).getEntity();
750 assertEquals(fiql, group.getADynMembershipConds().get(PRINTER));
751
752 group = GROUP_SERVICE.read(group.getKey());
753 assertEquals(fiql, group.getADynMembershipConds().get(PRINTER));
754
755
756 AnyObjectUR anyObjectUR = new AnyObjectUR();
757 anyObjectUR.setKey(newAny.getKey());
758 anyObjectUR.getPlainAttrs().add(new AttrPatch.Builder(new Attr.Builder("location").build()).
759 operation(PatchOperation.DELETE).
760 build());
761 newAny = updateAnyObject(anyObjectUR).getEntity();
762 assertFalse(newAny.getPlainAttr("location").isPresent());
763
764 memberships = ANY_OBJECT_SERVICE.read(
765 "fc6dbc3a-6c07-4965-8781-921e7401a4a5").getDynMemberships();
766 assertFalse(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
767 memberships = ANY_OBJECT_SERVICE.read(
768 "8559d14d-58c2-46eb-a2d4-a7d35161e8f8").getDynMemberships();
769 assertFalse(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
770 memberships = ANY_OBJECT_SERVICE.read(newAny.getKey()).getDynMemberships();
771 assertTrue(memberships.stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
772 }
773
774 @Test
775 public void aDynMembershipCount() {
776
777 GroupCR groupCR = getBasicSample("aDynamicMembership");
778 String fiql = SyncopeClient.getAnyObjectSearchConditionBuilder(PRINTER).is("location").equalTo("home").query();
779 groupCR.getADynMembershipConds().put(PRINTER, fiql);
780 GroupTO group = createGroup(groupCR).getEntity();
781
782 AnyObjectCR printerCR = new AnyObjectCR();
783 printerCR.setRealm(SyncopeConstants.ROOT_REALM);
784 printerCR.setName("Printer_" + getUUIDString());
785 printerCR.setType(PRINTER);
786 printerCR.getPlainAttrs().add(new Attr.Builder("location").value("home").build());
787 AnyObjectTO printer = createAnyObject(printerCR).getEntity();
788
789 group = GROUP_SERVICE.read(group.getKey());
790 assertEquals(0, group.getStaticAnyObjectMembershipCount());
791 assertEquals(1, group.getDynamicAnyObjectMembershipCount());
792
793 ANY_OBJECT_SERVICE.delete(printer.getKey());
794 GROUP_SERVICE.delete(group.getKey());
795 }
796
797 @Test
798 public void aStaticMembershipCount() {
799
800 GroupCR groupCR = getBasicSample("aStaticMembership");
801 GroupTO group = createGroup(groupCR).getEntity();
802
803 AnyObjectCR printerCR = new AnyObjectCR();
804 printerCR.setRealm(SyncopeConstants.ROOT_REALM);
805 printerCR.setName("Printer_" + getUUIDString());
806 printerCR.setType(PRINTER);
807 printerCR.getMemberships().add(new MembershipTO.Builder(group.getKey()).build());
808 AnyObjectTO printer = createAnyObject(printerCR).getEntity();
809
810 group = GROUP_SERVICE.read(group.getKey());
811 assertEquals(0, group.getDynamicAnyObjectMembershipCount());
812 assertEquals(1, group.getStaticAnyObjectMembershipCount());
813
814 ANY_OBJECT_SERVICE.delete(printer.getKey());
815 GROUP_SERVICE.delete(group.getKey());
816 }
817
818 @Test
819 public void capabilitiesOverride() {
820
821 ResourceTO ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
822 assertNotNull(ldap);
823 assertFalse(ldap.isOverrideCapabilities());
824 assertTrue(ldap.getCapabilitiesOverride().isEmpty());
825
826
827 ConnInstanceTO conn = CONNECTOR_SERVICE.read(ldap.getConnector(), null);
828 assertNotNull(conn);
829 assertTrue(conn.getCapabilities().contains(ConnectorCapability.CREATE));
830 assertTrue(conn.getCapabilities().contains(ConnectorCapability.UPDATE));
831
832 try {
833
834 GroupCR groupCR = getSample("syncope714");
835 groupCR.getPlainAttrs().add(attr("title", "first"));
836 groupCR.getResources().add(RESOURCE_NAME_LDAP);
837
838 ProvisioningResult<GroupTO> result = createGroup(groupCR);
839 assertNotNull(result);
840 assertEquals(1, result.getPropagationStatuses().size());
841 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
842 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
843 GroupTO group = result.getEntity();
844
845
846 GroupUR groupUR = new GroupUR();
847 groupUR.setKey(group.getKey());
848 groupUR.getPlainAttrs().add(new AttrPatch.Builder(attr("title", "second")).
849 operation(PatchOperation.ADD_REPLACE).build());
850
851 result = updateGroup(groupUR);
852 assertNotNull(result);
853 assertEquals(1, result.getPropagationStatuses().size());
854 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
855 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
856 group = result.getEntity();
857
858
859 ldap.getCapabilitiesOverride().add(ConnectorCapability.SEARCH);
860 RESOURCE_SERVICE.update(ldap);
861 ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
862 assertNotNull(ldap);
863 assertFalse(ldap.isOverrideCapabilities());
864 assertEquals(1, ldap.getCapabilitiesOverride().size());
865 assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
866
867
868 groupUR = new GroupUR();
869 groupUR.setKey(group.getKey());
870 groupUR.getPlainAttrs().add(new AttrPatch.Builder(attr("title", "third")).
871 operation(PatchOperation.ADD_REPLACE).build());
872
873 result = updateGroup(groupUR);
874 assertNotNull(result);
875 assertEquals(1, result.getPropagationStatuses().size());
876 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
877 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
878 group = result.getEntity();
879
880
881 ldap.setOverrideCapabilities(true);
882 RESOURCE_SERVICE.update(ldap);
883 ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
884 assertNotNull(ldap);
885 assertTrue(ldap.isOverrideCapabilities());
886 assertEquals(1, ldap.getCapabilitiesOverride().size());
887 assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
888
889
890 groupUR = new GroupUR();
891 groupUR.setKey(group.getKey());
892 groupUR.getPlainAttrs().add(new AttrPatch.Builder(attr("title", "fourth")).
893 operation(PatchOperation.ADD_REPLACE).build());
894
895 result = updateGroup(groupUR);
896 assertNotNull(result);
897 assertEquals(1, result.getPropagationStatuses().size());
898 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
899 assertEquals(ExecStatus.NOT_ATTEMPTED, result.getPropagationStatuses().get(0).getStatus());
900 } finally {
901 ldap.getCapabilitiesOverride().clear();
902 ldap.setOverrideCapabilities(false);
903 RESOURCE_SERVICE.update(ldap);
904 }
905 }
906
907 @Test
908 public void typeExtensions() {
909 TypeExtensionTO typeExtension = new TypeExtensionTO();
910 typeExtension.setAnyType(AnyTypeKind.USER.name());
911 typeExtension.getAuxClasses().add("csv");
912
913 GroupCR groupCR = getBasicSample("typeExtensions");
914 groupCR.getTypeExtensions().add(typeExtension);
915
916 GroupTO groupTO = createGroup(groupCR).getEntity();
917 assertNotNull(groupTO);
918 assertEquals(1, groupTO.getTypeExtensions().size());
919 assertEquals(1, groupTO.getTypeExtension(AnyTypeKind.USER.name()).get().getAuxClasses().size());
920 assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).get().getAuxClasses().contains("csv"));
921
922 typeExtension = new TypeExtensionTO();
923 typeExtension.setAnyType(AnyTypeKind.USER.name());
924 typeExtension.getAuxClasses().add("csv");
925 typeExtension.getAuxClasses().add("other");
926
927 GroupUR groupUR = new GroupUR();
928 groupUR.setKey(groupTO.getKey());
929 groupUR.getTypeExtensions().add(typeExtension);
930
931 groupTO = updateGroup(groupUR).getEntity();
932 assertNotNull(groupTO);
933 assertEquals(1, groupTO.getTypeExtensions().size());
934 assertEquals(2, groupTO.getTypeExtension(AnyTypeKind.USER.name()).get().getAuxClasses().size());
935 assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).get().getAuxClasses().contains("csv"));
936 assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).get().getAuxClasses().contains("other"));
937 }
938
939 @Test
940 public void provisionMembers() throws InterruptedException {
941 assumeFalse(IS_EXT_SEARCH_ENABLED);
942
943
944 GroupCR groupCR = getBasicSample("forProvision");
945 GroupTO groupTO = createGroup(groupCR).getEntity();
946
947
948 UserCR userCR = UserITCase.getUniqueSample("forProvision@syncope.apache.org");
949 userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build());
950 UserTO userTO = createUser(userCR).getEntity();
951
952
953 GroupUR groupUR = new GroupUR();
954 groupUR.setKey(groupTO.getKey());
955 groupUR.getResources().add(new StringPatchItem.Builder().value(RESOURCE_NAME_LDAP).build());
956 ProvisioningResult<GroupTO> groupUpdateResult = updateGroup(groupUR);
957
958 PropagationStatus propStatus = groupUpdateResult.getPropagationStatuses().get(0);
959 assertEquals(RESOURCE_NAME_LDAP, propStatus.getResource());
960 assertEquals(ExecStatus.SUCCESS, propStatus.getStatus());
961
962
963 try {
964 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
965 fail("This should not happen");
966 } catch (SyncopeClientException e) {
967 assertEquals(ClientExceptionType.NotFound, e.getType());
968 }
969
970 try {
971
972 ExecTO exec = GROUP_SERVICE.provisionMembers(groupTO.getKey(), ProvisionAction.PROVISION);
973 assertNotNull(exec.getRefKey());
974
975 AtomicReference<List<ExecTO>> execs = new AtomicReference<>();
976 await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
977 try {
978 execs.set(TASK_SERVICE.read(TaskType.SCHEDULED, exec.getRefKey(), true).getExecutions());
979 return !execs.get().isEmpty();
980 } catch (Exception e) {
981 return false;
982 }
983 });
984 assertEquals(TaskJob.Status.SUCCESS.name(), execs.get().get(0).getStatus());
985
986
987 ConnObject userOnLdap =
988 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
989 assertNotNull(userOnLdap);
990
991
992 assertDoesNotThrow(() -> GROUP_SERVICE.provisionMembers(groupTO.getKey(), ProvisionAction.PROVISION));
993 } finally {
994 GROUP_SERVICE.delete(groupTO.getKey());
995 USER_SERVICE.delete(userTO.getKey());
996 }
997 }
998
999 @Test
1000 public void unlimitedMembership() {
1001 GroupCR groupCR = new GroupCR();
1002 groupCR.setName("unlimited" + getUUIDString());
1003 groupCR.setRealm("/even/two");
1004 GroupTO groupTO = createGroup(groupCR).getEntity();
1005
1006 UserCR userCR = UserITCase.getUniqueSample("unlimited@syncope.apache.org");
1007 userCR.setRealm(SyncopeConstants.ROOT_REALM);
1008 userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build());
1009 UserTO userTO = createUser(userCR).getEntity();
1010
1011 assertFalse(userTO.getMemberships().isEmpty());
1012 assertEquals(groupTO.getKey(), userTO.getMemberships().get(0).getGroupKey());
1013 }
1014
1015 @Test
1016 public void issue178() {
1017 GroupCR groupCR = new GroupCR();
1018 groupCR.setName("torename" + getUUIDString());
1019 groupCR.setRealm(SyncopeConstants.ROOT_REALM);
1020
1021 GroupTO actual = createGroup(groupCR).getEntity();
1022
1023 assertNotNull(actual);
1024 assertEquals(groupCR.getName(), actual.getName());
1025
1026 GroupUR groupUR = new GroupUR();
1027 groupUR.setKey(actual.getKey());
1028 groupUR.setName(new StringReplacePatchItem.Builder().value("renamed" + getUUIDString()).build());
1029
1030 actual = updateGroup(groupUR).getEntity();
1031 assertNotNull(actual);
1032 assertEquals(groupUR.getName().getValue(), actual.getName());
1033 }
1034
1035 @Test
1036 public void issueSYNCOPE632() {
1037 DerSchemaTO orig = SCHEMA_SERVICE.read(SchemaType.DERIVED, "displayProperty");
1038 DerSchemaTO modified = SerializationUtils.clone(orig);
1039 modified.setExpression("icon + '_' + show");
1040
1041 GroupCR groupCR = GroupITCase.getSample("lastGroup");
1042 GroupTO groupTO = null;
1043 try {
1044 SCHEMA_SERVICE.update(SchemaType.DERIVED, modified);
1045
1046
1047 groupCR.getPlainAttrs().add(attr("icon", "anIcon"));
1048 groupCR.getPlainAttrs().add(attr("show", "true"));
1049 groupCR.getResources().clear();
1050
1051 groupTO = createGroup(groupCR).getEntity();
1052 assertNotNull(groupTO);
1053
1054
1055 ResourceTO newLDAP = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
1056 newLDAP.setKey("new-ldap");
1057 newLDAP.setPropagationPriority(0);
1058
1059 for (Provision provision : newLDAP.getProvisions()) {
1060 provision.getVirSchemas().clear();
1061 }
1062
1063 Mapping mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).get().getMapping();
1064
1065 Item connObjectKey = mapping.getConnObjectKeyItem().get();
1066 connObjectKey.setIntAttrName("displayProperty");
1067 connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
1068 mapping.setConnObjectKeyItem(connObjectKey);
1069 mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
1070
1071 Item description = new Item();
1072 description.setIntAttrName("key");
1073 description.setExtAttrName("description");
1074 description.setPurpose(MappingPurpose.PROPAGATION);
1075 mapping.add(description);
1076
1077 newLDAP = createResource(newLDAP);
1078 assertNotNull(newLDAP);
1079
1080
1081 GroupUR groupUR = new GroupUR();
1082 groupUR.setKey(groupTO.getKey());
1083 groupUR.getResources().add(new StringPatchItem.Builder().
1084 operation(PatchOperation.ADD_REPLACE).
1085 value("new-ldap").build());
1086
1087 groupTO = updateGroup(groupUR).getEntity();
1088 assertNotNull(groupTO);
1089
1090
1091 groupUR = new GroupUR();
1092 groupUR.setKey(groupTO.getKey());
1093 groupUR.getPlainAttrs().add(attrAddReplacePatch("icon", "anotherIcon"));
1094
1095 groupTO = updateGroup(groupUR).getEntity();
1096 assertNotNull(groupTO);
1097
1098
1099 int entries = 0;
1100 DirContext ctx = null;
1101 try {
1102 ctx = getLdapResourceDirContext(null, null);
1103
1104 SearchControls ctls = new SearchControls();
1105 ctls.setReturningAttributes(new String[] { "*", "+" });
1106 ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
1107
1108 NamingEnumeration<SearchResult> result =
1109 ctx.search("ou=groups,o=isp", "(description=" + groupTO.getKey() + ')', ctls);
1110 while (result.hasMore()) {
1111 result.next();
1112 entries++;
1113 }
1114 } catch (Exception e) {
1115
1116 } finally {
1117 if (ctx != null) {
1118 try {
1119 ctx.close();
1120 } catch (NamingException e) {
1121
1122 }
1123 }
1124 }
1125
1126 assertEquals(1, entries);
1127 } finally {
1128 SCHEMA_SERVICE.update(SchemaType.DERIVED, orig);
1129 Optional.ofNullable(groupTO).ifPresent(g -> GROUP_SERVICE.delete(g.getKey()));
1130 RESOURCE_SERVICE.delete("new-ldap");
1131 }
1132 }
1133
1134 @Test
1135 public void issueSYNCOPE717() {
1136 String doubleSchemaName = "double" + getUUIDString();
1137
1138
1139 PlainSchemaTO schema = new PlainSchemaTO();
1140 schema.setKey(doubleSchemaName);
1141 schema.setType(AttrSchemaType.Double);
1142
1143 schema = createSchema(SchemaType.PLAIN, schema);
1144 assertNotNull(schema);
1145 assertNull(schema.getConversionPattern());
1146
1147 AnyTypeClassTO minimalGroup = ANY_TYPE_CLASS_SERVICE.read("minimal group");
1148 assertNotNull(minimalGroup);
1149 minimalGroup.getPlainSchemas().add(doubleSchemaName);
1150 ANY_TYPE_CLASS_SERVICE.update(minimalGroup);
1151
1152
1153 GroupCR groupCR = GroupITCase.getBasicSample("syncope717");
1154 groupCR.getPlainAttrs().add(attr(doubleSchemaName, "11.23"));
1155
1156 GroupTO groupTO = createGroup(groupCR).getEntity();
1157 assertNotNull(groupTO);
1158 assertEquals("11.23", groupTO.getPlainAttr(doubleSchemaName).get().getValues().get(0));
1159
1160
1161 schema = SCHEMA_SERVICE.read(SchemaType.PLAIN, schema.getKey());
1162 schema.setConversionPattern("0.000");
1163 SCHEMA_SERVICE.update(SchemaType.PLAIN, schema);
1164
1165
1166 groupTO = GROUP_SERVICE.read(groupTO.getKey());
1167 assertNotNull(groupTO);
1168 assertEquals("11.230", groupTO.getPlainAttr(doubleSchemaName).get().getValues().get(0));
1169
1170
1171 GroupUR groupUR = new GroupUR();
1172 groupUR.setKey(groupTO.getKey());
1173 groupUR.getPlainAttrs().add(new AttrPatch.Builder(attr(doubleSchemaName, "11.257")).build());
1174
1175 groupTO = updateGroup(groupUR).getEntity();
1176 assertNotNull(groupTO);
1177 assertEquals("11.257", groupTO.getPlainAttr(doubleSchemaName).get().getValues().get(0));
1178
1179
1180 schema.setConversionPattern(null);
1181 SCHEMA_SERVICE.update(SchemaType.PLAIN, schema);
1182
1183
1184 groupUR = new GroupUR();
1185 groupUR.setKey(groupTO.getKey());
1186 groupUR.getPlainAttrs().add(new AttrPatch.Builder(attr(doubleSchemaName, "11.23")).build());
1187
1188 groupTO = updateGroup(groupUR).getEntity();
1189 assertNotNull(groupTO);
1190 assertEquals("11.23", groupTO.getPlainAttr(doubleSchemaName).get().getValues().get(0));
1191 }
1192
1193 @Test
1194 public void issueSYNCOPE1467() {
1195 GroupTO groupTO = null;
1196 try {
1197 GroupCR groupCR = new GroupCR();
1198 groupCR.setRealm(SyncopeConstants.ROOT_REALM);
1199 groupCR.setName("issueSYNCOPE1467");
1200 groupCR.getResources().add(RESOURCE_NAME_LDAP);
1201
1202 groupTO = createGroup(groupCR).getEntity();
1203 assertNotNull(groupTO);
1204 assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP));
1205
1206 ConnObject connObjectTO =
1207 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
1208 assertNotNull(connObjectTO);
1209 assertEquals("issueSYNCOPE1467", connObjectTO.getAttr("cn").get().getValues().get(0));
1210
1211 GroupUR groupUR = new GroupUR();
1212 groupUR.setKey(groupTO.getKey());
1213 groupUR.setName(new StringReplacePatchItem.Builder().value("fixedSYNCOPE1467").build());
1214
1215 ProvisioningResult<GroupTO> result = updateGroup(groupUR);
1216 assertEquals(1, result.getPropagationStatuses().size());
1217 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
1218 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
1219
1220 connObjectTO = RESOURCE_SERVICE.readConnObject(
1221 RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
1222 assertNotNull(connObjectTO);
1223 assertEquals("fixedSYNCOPE1467", connObjectTO.getAttr("cn").get().getValues().get(0));
1224 } finally {
1225 Optional.ofNullable(groupTO).ifPresent(g -> GROUP_SERVICE.delete(g.getKey()));
1226 }
1227 }
1228
1229 @Test
1230 public void issueSYNCOPE1472() {
1231
1232 GroupUR groupUR = new GroupUR();
1233 groupUR.setKey("ece66293-8f31-4a84-8e8d-23da36e70846");
1234 groupUR.getResources().add(new StringPatchItem.Builder()
1235 .value(RESOURCE_NAME_TESTDB)
1236 .operation(PatchOperation.ADD_REPLACE)
1237 .build());
1238 groupUR.getAuxClasses().add(new StringPatchItem.Builder()
1239 .operation(PatchOperation.ADD_REPLACE)
1240 .value("csv")
1241 .build());
1242 for (int i = 0; i < 2; i++) {
1243 updateGroup(groupUR);
1244 }
1245
1246
1247 groupUR.getResources().clear();
1248 groupUR.getResources().add(new StringPatchItem.Builder()
1249 .value(RESOURCE_NAME_TESTDB)
1250 .operation(PatchOperation.DELETE)
1251 .build());
1252 groupUR.getAuxClasses().clear();
1253 groupUR.getAuxClasses().add(new StringPatchItem.Builder()
1254 .value("csv")
1255 .operation(PatchOperation.DELETE)
1256 .build());
1257
1258 updateGroup(groupUR);
1259
1260 GroupTO groupTO = GROUP_SERVICE.read("ece66293-8f31-4a84-8e8d-23da36e70846");
1261 assertFalse(groupTO.getResources().contains(RESOURCE_NAME_TESTDB), "Should not contain removed resources");
1262 assertFalse(groupTO.getAuxClasses().contains("csv"), "Should not contain removed auxiliary classes");
1263 }
1264 }