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.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotEquals;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import static org.junit.jupiter.api.Assertions.fail;
28 import static org.junit.jupiter.api.Assumptions.assumeFalse;
29
30 import java.io.IOException;
31 import java.nio.charset.StandardCharsets;
32 import java.util.Base64;
33 import java.util.Collection;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Optional;
37 import java.util.Set;
38 import java.util.UUID;
39 import javax.naming.NamingException;
40 import javax.ws.rs.HttpMethod;
41 import javax.ws.rs.core.GenericType;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.Response;
44 import org.apache.commons.lang3.tuple.Triple;
45 import org.apache.cxf.helpers.IOUtils;
46 import org.apache.cxf.jaxrs.client.WebClient;
47 import org.apache.syncope.client.lib.SyncopeClient;
48 import org.apache.syncope.common.lib.Attr;
49 import org.apache.syncope.common.lib.SyncopeClientException;
50 import org.apache.syncope.common.lib.SyncopeConstants;
51 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
52 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
53 import org.apache.syncope.common.lib.request.AttrPatch;
54 import org.apache.syncope.common.lib.request.GroupCR;
55 import org.apache.syncope.common.lib.request.MembershipUR;
56 import org.apache.syncope.common.lib.request.PasswordPatch;
57 import org.apache.syncope.common.lib.request.ResourceAR;
58 import org.apache.syncope.common.lib.request.ResourceDR;
59 import org.apache.syncope.common.lib.request.StatusR;
60 import org.apache.syncope.common.lib.request.StringPatchItem;
61 import org.apache.syncope.common.lib.request.StringReplacePatchItem;
62 import org.apache.syncope.common.lib.request.UserCR;
63 import org.apache.syncope.common.lib.request.UserUR;
64 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
65 import org.apache.syncope.common.lib.to.ConnObject;
66 import org.apache.syncope.common.lib.to.ExecTO;
67 import org.apache.syncope.common.lib.to.GroupTO;
68 import org.apache.syncope.common.lib.to.ImplementationTO;
69 import org.apache.syncope.common.lib.to.Item;
70 import org.apache.syncope.common.lib.to.Mapping;
71 import org.apache.syncope.common.lib.to.MembershipTO;
72 import org.apache.syncope.common.lib.to.PlainSchemaTO;
73 import org.apache.syncope.common.lib.to.PropagationStatus;
74 import org.apache.syncope.common.lib.to.ProvisioningResult;
75 import org.apache.syncope.common.lib.to.PushTaskTO;
76 import org.apache.syncope.common.lib.to.RealmTO;
77 import org.apache.syncope.common.lib.to.ReconStatus;
78 import org.apache.syncope.common.lib.to.ResourceTO;
79 import org.apache.syncope.common.lib.to.RoleTO;
80 import org.apache.syncope.common.lib.to.UserTO;
81 import org.apache.syncope.common.lib.types.AnyTypeKind;
82 import org.apache.syncope.common.lib.types.AttrSchemaType;
83 import org.apache.syncope.common.lib.types.CipherAlgorithm;
84 import org.apache.syncope.common.lib.types.ClientExceptionType;
85 import org.apache.syncope.common.lib.types.ExecStatus;
86 import org.apache.syncope.common.lib.types.IdMImplementationType;
87 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
88 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
89 import org.apache.syncope.common.lib.types.ImplementationEngine;
90 import org.apache.syncope.common.lib.types.MappingPurpose;
91 import org.apache.syncope.common.lib.types.MatchingRule;
92 import org.apache.syncope.common.lib.types.PatchOperation;
93 import org.apache.syncope.common.lib.types.PolicyType;
94 import org.apache.syncope.common.lib.types.ResourceAssociationAction;
95 import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
96 import org.apache.syncope.common.lib.types.SchemaType;
97 import org.apache.syncope.common.lib.types.StatusRType;
98 import org.apache.syncope.common.lib.types.TaskType;
99 import org.apache.syncope.common.lib.types.UnmatchingRule;
100 import org.apache.syncope.common.rest.api.RESTHeaders;
101 import org.apache.syncope.common.rest.api.beans.RealmQuery;
102 import org.apache.syncope.common.rest.api.beans.ReconQuery;
103 import org.apache.syncope.common.rest.api.service.UserService;
104 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
105 import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
106 import org.apache.syncope.core.provisioning.java.propagation.GenerateRandomPasswordPropagationActions;
107 import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
108 import org.apache.syncope.core.spring.security.Encryptor;
109 import org.apache.syncope.fit.AbstractITCase;
110 import org.identityconnectors.framework.common.objects.Name;
111 import org.identityconnectors.framework.common.objects.OperationalAttributes;
112 import org.junit.jupiter.api.BeforeAll;
113 import org.junit.jupiter.api.Test;
114 import org.springframework.dao.EmptyResultDataAccessException;
115 import org.springframework.jdbc.core.JdbcTemplate;
116
117 public class UserIssuesITCase extends AbstractITCase {
118
119 @BeforeAll
120 public static void testPropagationActionsSetup() {
121 ImplementationTO propagationActions = null;
122 try {
123 propagationActions = IMPLEMENTATION_SERVICE.read(
124 IdMImplementationType.PROPAGATION_ACTIONS, LDAPPasswordPropagationActions.class.getSimpleName());
125 } catch (SyncopeClientException e) {
126 if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) {
127 propagationActions = new ImplementationTO();
128 propagationActions.setKey(LDAPPasswordPropagationActions.class.getSimpleName());
129 propagationActions.setEngine(ImplementationEngine.JAVA);
130 propagationActions.setType(IdMImplementationType.PROPAGATION_ACTIONS);
131 propagationActions.setBody(LDAPPasswordPropagationActions.class.getName());
132 Response response = IMPLEMENTATION_SERVICE.create(propagationActions);
133 propagationActions = IMPLEMENTATION_SERVICE.read(
134 propagationActions.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
135 }
136 }
137 assertNotNull(propagationActions);
138 }
139
140 @Test
141 public void issue186() {
142
143 UserCR userCR = new UserCR();
144 userCR.setRealm(SyncopeConstants.ROOT_REALM);
145 String userId = getUUIDString() + "issue186@syncope.apache.org";
146 userCR.setUsername(userId);
147 userCR.setPassword("password123");
148
149 userCR.getPlainAttrs().add(attr("userId", userId));
150 userCR.getPlainAttrs().add(attr("fullname", userId));
151 userCR.getPlainAttrs().add(attr("surname", userId));
152
153 UserTO userTO = createUser(userCR).getEntity();
154 assertNotNull(userTO);
155 assertTrue(userTO.getResources().isEmpty());
156
157
158 UserUR userUR = new UserUR.Builder(userTO.getKey()).
159 password(new PasswordPatch.Builder().value("newPassword123").build()).
160 resource(new StringPatchItem.Builder().
161 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build()).
162 build();
163
164 try {
165 userTO = updateUser(userUR).getEntity();
166 fail("This should not happen");
167 } catch (SyncopeClientException e) {
168 assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
169 }
170
171
172
173 userUR = new UserUR();
174 userUR.setKey(userTO.getKey());
175 userUR.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
176 userUR.getResources().add(new StringPatchItem.Builder().
177 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
178
179 ProvisioningResult<UserTO> result = updateUser(userUR);
180 assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
181 userTO = result.getEntity();
182
183
184
185 userUR = new UserUR();
186 userUR.setKey(userTO.getKey());
187 userUR.setPassword(new PasswordPatch.Builder().value("newPassword123456").build());
188 userUR.getResources().add(new StringPatchItem.Builder().
189 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_CSV).build());
190
191 updateUser(userUR);
192 }
193
194 @Test
195 public void issue213() {
196 UserCR userCR = UserITCase.getUniqueSample("issue213@syncope.apache.org");
197 userCR.getResources().add(RESOURCE_NAME_TESTDB);
198
199 UserTO userTO = createUser(userCR).getEntity();
200 assertNotNull(userTO);
201 assertEquals(1, userTO.getResources().size());
202
203 JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
204 String username = queryForObject(
205 jdbcTemplate, MAX_WAIT_SECONDS, "SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
206 assertEquals(userTO.getUsername(), username);
207
208 UserUR userUR = new UserUR();
209 userUR.setKey(userTO.getKey());
210 userUR.getResources().add(
211 new StringPatchItem.Builder().operation(PatchOperation.DELETE).value(RESOURCE_NAME_TESTDB).build());
212
213 userTO = updateUser(userUR).getEntity();
214 assertTrue(userTO.getResources().isEmpty());
215
216 Exception exception = null;
217 try {
218 jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
219 } catch (EmptyResultDataAccessException e) {
220 exception = e;
221 }
222 assertNotNull(exception);
223 }
224
225 @Test
226 public void issue234() {
227 UserCR inUserTO = UserITCase.getUniqueSample("issue234@syncope.apache.org");
228 inUserTO.getResources().add(RESOURCE_NAME_LDAP);
229
230 UserTO userTO = createUser(inUserTO).getEntity();
231 assertNotNull(userTO);
232
233 UserUR userUR = new UserUR();
234
235 userUR.setKey(userTO.getKey());
236 userUR.setUsername(new StringReplacePatchItem.Builder().value('1' + userTO.getUsername()).build());
237
238 userTO = updateUser(userUR).getEntity();
239 assertNotNull(userTO);
240 assertEquals('1' + inUserTO.getUsername(), userTO.getUsername());
241 }
242
243 @Test
244 public void issue280() {
245 UserCR userCR = UserITCase.getUniqueSample("issue280@syncope.apache.org");
246 userCR.getResources().clear();
247 userCR.getMemberships().clear();
248
249 UserTO userTO = createUser(userCR).getEntity();
250 assertNotNull(userTO);
251
252 UserUR userUR = new UserUR();
253 userUR.setKey(userTO.getKey());
254 userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).
255 resource(RESOURCE_NAME_TESTDB).value("123password").build());
256 userUR.getResources().add(new StringPatchItem.Builder().
257 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
258
259 ProvisioningResult<UserTO> result = updateUser(userUR);
260 assertNotNull(result);
261
262 List<PropagationStatus> propagations = result.getPropagationStatuses();
263 assertNotNull(propagations);
264 assertEquals(1, propagations.size());
265
266 assertEquals(ExecStatus.SUCCESS, propagations.get(0).getStatus());
267
268 String resource = propagations.get(0).getResource();
269 assertEquals(RESOURCE_NAME_TESTDB, resource);
270 }
271
272 @Test
273 public void issue281() {
274 UserCR userCR = UserITCase.getUniqueSample("issue281@syncope.apache.org");
275 userCR.getResources().clear();
276 userCR.getMemberships().clear();
277 userCR.getResources().add(RESOURCE_NAME_CSV);
278
279 ProvisioningResult<UserTO> result = createUser(userCR);
280 assertNotNull(result);
281
282 List<PropagationStatus> propagations = result.getPropagationStatuses();
283 assertNotNull(propagations);
284 assertEquals(1, propagations.size());
285 assertNotEquals(ExecStatus.SUCCESS, propagations.get(0).getStatus());
286
287 String resource = propagations.get(0).getResource();
288 assertEquals(RESOURCE_NAME_CSV, resource);
289 }
290
291 @Test
292 public void issue288() {
293 UserCR userTO = UserITCase.getSample("issue288@syncope.apache.org");
294 userTO.getPlainAttrs().add(attr("aLong", "STRING"));
295
296 try {
297 createUser(userTO);
298 fail("This should not happen");
299 } catch (SyncopeClientException e) {
300 assertEquals(ClientExceptionType.InvalidValues, e.getType());
301 }
302 }
303
304 @Test
305 public void issueSYNCOPE108() {
306 UserCR userCR = UserITCase.getUniqueSample("syncope108@syncope.apache.org");
307 userCR.getResources().clear();
308 userCR.getMemberships().clear();
309 userCR.getVirAttrs().clear();
310 userCR.getAuxClasses().add("csv");
311
312 userCR.getMemberships().add(new MembershipTO.Builder("0626100b-a4ba-4e00-9971-86fad52a6216").build());
313 userCR.getMemberships().add(new MembershipTO.Builder("ba9ed509-b1f5-48ab-a334-c8530a6422dc").build());
314
315 userCR.getResources().add(RESOURCE_NAME_CSV);
316
317 UserTO userTO = createUser(userCR).getEntity();
318 assertNotNull(userTO);
319 assertEquals(2, userTO.getMemberships().size());
320 assertEquals(1, userTO.getResources().size());
321
322 ConnObject connObjectTO =
323 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
324 assertNotNull(connObjectTO);
325
326
327
328
329 UserUR userUR = new UserUR.Builder(userTO.getKey()).
330 membership(new MembershipUR.Builder(userTO.getMemberships().get(0).getGroupKey()).
331 operation(PatchOperation.DELETE).build()).
332 build();
333
334 userTO = updateUser(userUR).getEntity();
335 assertNotNull(userTO);
336 assertEquals(1, userTO.getMemberships().size());
337
338 connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
339 assertNotNull(connObjectTO);
340
341
342
343
344
345 userUR = new UserUR();
346 userUR.setKey(userTO.getKey());
347
348 userUR.getResources().add(new StringPatchItem.Builder().operation(PatchOperation.DELETE).
349 value(userTO.getResources().iterator().next()).build());
350
351 userTO = updateUser(userUR).getEntity();
352 assertNotNull(userTO);
353 assertEquals(1, userTO.getMemberships().size());
354 assertFalse(userTO.getResources().isEmpty());
355
356 connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
357 assertNotNull(connObjectTO);
358
359
360
361
362
363 userUR = new UserUR.Builder(userTO.getKey()).
364 membership(new MembershipUR.Builder(userTO.getMemberships().get(0).getGroupKey()).
365 operation(PatchOperation.DELETE).build()).
366 build();
367
368 userTO = updateUser(userUR).getEntity();
369 assertNotNull(userTO);
370 assertTrue(userTO.getMemberships().isEmpty());
371 assertTrue(userTO.getResources().isEmpty());
372
373 try {
374 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
375 fail("Read should not succeeed");
376 } catch (SyncopeClientException e) {
377 assertEquals(ClientExceptionType.NotFound, e.getType());
378 }
379 }
380
381 @Test
382 public void issueSYNCOPE185() {
383
384 UserCR userCR = UserITCase.getSample("syncope185@syncope.apache.org");
385 userCR.getVirAttrs().clear();
386 userCR.getResources().add(RESOURCE_NAME_LDAP);
387
388 ProvisioningResult<UserTO> result = createUser(userCR);
389 assertNotNull(result);
390 assertFalse(result.getPropagationStatuses().isEmpty());
391 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
392 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
393 UserTO userTO = result.getEntity();
394
395
396 USER_SERVICE.delete(userTO.getKey());
397
398
399 try {
400 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
401 fail("This entry should not be present on this resource");
402 } catch (SyncopeClientException e) {
403 assertEquals(ClientExceptionType.NotFound, e.getType());
404 }
405 }
406
407 @Test()
408 public void issueSYNCOPE51() {
409 String originalCA = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
410 "password.cipher.algorithm", null, String.class);
411 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "MD5");
412
413 UserCR userCR = UserITCase.getSample("syncope51@syncope.apache.org");
414 userCR.setPassword("password");
415
416 try {
417 createUser(userCR);
418 fail("Create user should not succeed");
419 } catch (SyncopeClientException e) {
420 assertEquals(ClientExceptionType.NotFound, e.getType());
421 assertTrue(e.getElements().iterator().next().contains("MD5"));
422 } finally {
423 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", originalCA);
424 }
425 }
426
427 @Test
428 public void issueSYNCOPE267() {
429
430
431
432 UserCR userCR = UserITCase.getUniqueSample("syncope267@apache.org");
433 userCR.getVirAttrs().add(attr("virtualdata", "virtualvalue"));
434 userCR.getResources().clear();
435 userCR.getResources().add(RESOURCE_NAME_DBVIRATTR);
436
437 ProvisioningResult<UserTO> result = createUser(userCR);
438 assertNotNull(result);
439 assertFalse(result.getPropagationStatuses().isEmpty());
440 assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(0).getResource());
441 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
442 UserTO userTO = result.getEntity();
443
444 ConnObject connObjectTO =
445 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
446 assertNotNull(connObjectTO);
447 assertEquals("virtualvalue", connObjectTO.getAttr("USERNAME").get().getValues().get(0));
448
449
450 userTO = USER_SERVICE.read(userTO.getKey());
451
452 assertNotNull(userTO);
453 assertEquals(1, userTO.getVirAttrs().size());
454 assertEquals("virtualvalue", userTO.getVirAttrs().iterator().next().getValues().get(0));
455 }
456
457 @Test
458 public void issueSYNCOPE266() {
459 UserCR userCR = UserITCase.getUniqueSample("syncope266@apache.org");
460 userCR.getResources().clear();
461
462 UserTO userTO = createUser(userCR).getEntity();
463 assertNotNull(userTO);
464
465 UserUR userUR = new UserUR();
466 userUR.setKey(userTO.getKey());
467
468
469 userUR.getResources().add(new StringPatchItem.Builder().
470 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_UPDATE).build());
471
472 userTO = updateUser(userUR).getEntity();
473 assertNotNull(userTO);
474 }
475
476 @Test
477 public void issueSYNCOPE279() {
478 UserCR userCR = UserITCase.getUniqueSample("syncope279@apache.org");
479 userCR.getResources().clear();
480 userCR.getResources().add(RESOURCE_NAME_TIMEOUT);
481 ProvisioningResult<UserTO> result = createUser(userCR);
482 assertEquals(RESOURCE_NAME_TIMEOUT, result.getPropagationStatuses().get(0).getResource());
483 assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
484 assertEquals(ExecStatus.FAILURE, result.getPropagationStatuses().get(0).getStatus());
485 }
486
487 @Test
488 public void issueSYNCOPE122() {
489
490 UserCR userCR = UserITCase.getUniqueSample("syncope122@apache.org");
491 userCR.getResources().clear();
492
493 userCR.getResources().add(RESOURCE_NAME_TESTDB);
494 userCR.getResources().add(RESOURCE_NAME_TESTDB2);
495
496 UserTO userTO = createUser(userCR).getEntity();
497 assertNotNull(userTO);
498 assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
499 assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB2));
500
501 String pwdOnSyncope = userTO.getPassword();
502
503 ConnObject userOnDb = RESOURCE_SERVICE.readConnObject(
504 RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
505 Attr pwdOnTestDbAttr = userOnDb.getAttr(OperationalAttributes.PASSWORD_NAME).get();
506 assertNotNull(pwdOnTestDbAttr);
507 assertNotNull(pwdOnTestDbAttr.getValues());
508 assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
509 String pwdOnTestDb = pwdOnTestDbAttr.getValues().get(0);
510
511 ConnObject userOnDb2 = RESOURCE_SERVICE.readConnObject(
512 RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
513 Attr pwdOnTestDb2Attr = userOnDb2.getAttr(OperationalAttributes.PASSWORD_NAME).get();
514 assertNotNull(pwdOnTestDb2Attr);
515 assertNotNull(pwdOnTestDb2Attr.getValues());
516 assertFalse(pwdOnTestDb2Attr.getValues().isEmpty());
517 String pwdOnTestDb2 = pwdOnTestDb2Attr.getValues().get(0);
518
519
520 UserUR userUR = new UserUR();
521 userUR.setKey(userTO.getKey());
522 userUR.setPassword(new PasswordPatch.Builder().value(UUID.randomUUID().toString()).onSyncope(false).
523 resource(RESOURCE_NAME_TESTDB).build());
524
525 ProvisioningResult<UserTO> result = updateUser(userUR);
526 userTO = result.getEntity();
527
528
529 assertNotNull(result.getPropagationStatuses());
530 assertEquals(1, result.getPropagationStatuses().size());
531 assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().get(0).getResource());
532
533
534 assertEquals(pwdOnSyncope, userTO.getPassword());
535
536
537 userOnDb = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
538 Attr pwdOnTestDbAttrAfter = userOnDb.getAttr(OperationalAttributes.PASSWORD_NAME).get();
539 assertNotNull(pwdOnTestDbAttrAfter);
540 assertNotNull(pwdOnTestDbAttrAfter.getValues());
541 assertFalse(pwdOnTestDbAttrAfter.getValues().isEmpty());
542 assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().get(0));
543
544
545 userOnDb2 = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
546 Attr pwdOnTestDb2AttrAfter = userOnDb2.getAttr(OperationalAttributes.PASSWORD_NAME).get();
547 assertNotNull(pwdOnTestDb2AttrAfter);
548 assertNotNull(pwdOnTestDb2AttrAfter.getValues());
549 assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
550 assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().get(0));
551 }
552
553 @Test
554 public void issueSYNCOPE136AES() {
555
556 String origpwdCipherAlgo = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
557 "password.cipher.algorithm", null, String.class);
558
559
560 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "AES");
561
562 UserTO userTO = null;
563 try {
564
565 UserCR userCR = UserITCase.getUniqueSample("syncope136_AES@apache.org");
566 userCR.getResources().clear();
567
568 userTO = createUser(userCR).getEntity();
569 assertNotNull(userTO);
570
571
572 UserUR userUR = new UserUR();
573 userUR.setKey(userTO.getKey());
574 userUR.getResources().add(new StringPatchItem.Builder().
575 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
576 userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
577
578 ProvisioningResult<UserTO> result = updateUser(userUR);
579 assertNotNull(result);
580 userTO = result.getEntity();
581 assertNotNull(userTO);
582
583
584 List<PropagationStatus> props = result.getPropagationStatuses();
585 assertNotNull(props);
586 assertEquals(1, props.size());
587 PropagationStatus prop = props.get(0);
588 assertNotNull(prop);
589 assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
590 assertEquals(ExecStatus.SUCCESS, prop.getStatus());
591 } finally {
592
593 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", origpwdCipherAlgo);
594
595 if (userTO != null) {
596 deleteUser(userTO.getKey());
597 }
598 }
599 }
600
601 @Test
602 public void issueSYNCOPE136Random() {
603
604 UserCR userCR = UserITCase.getUniqueSample("syncope136_Random@apache.org");
605 userCR.getResources().clear();
606 UserTO userTO = createUser(userCR).getEntity();
607 assertNotNull(userTO);
608
609
610 UserUR userUR = new UserUR();
611 userUR.setKey(userTO.getKey());
612 userUR.getResources().add(new StringPatchItem.Builder().
613 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
614 userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
615
616 ProvisioningResult<UserTO> result = updateUser(userUR);
617 assertNotNull(result);
618
619
620 List<PropagationStatus> props = result.getPropagationStatuses();
621 assertNotNull(props);
622 assertEquals(1, props.size());
623 PropagationStatus prop = props.get(0);
624 assertNotNull(prop);
625 assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
626 assertEquals(ExecStatus.SUCCESS, prop.getStatus());
627 }
628
629 @Test
630 public void issueSYNCOPE265() {
631 String[] userKeys = new String[] {
632 "1417acbe-cbf6-4277-9372-e75e04f97000",
633 "74cd8ece-715a-44a4-a736-e17b46c4e7e6",
634 "b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee",
635 "c9b2dec2-00a7-4855-97c0-d854842b4b24",
636 "823074dc-d280-436d-a7dd-07399fae48ec" };
637
638 for (String userKey : userKeys) {
639 UserUR userUR = new UserUR();
640 userUR.setKey(userKey);
641 userUR.getPlainAttrs().add(attrAddReplacePatch("ctype", "a type"));
642 UserTO userTO = updateUser(userUR).getEntity();
643 assertEquals("a type", userTO.getPlainAttr("ctype").get().getValues().get(0));
644 }
645 }
646
647 @Test
648 public void issueSYNCOPE354() {
649
650 ResourceTO ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
651 ldap.getProvision(AnyTypeKind.GROUP.name()).get().getMapping().getItems().stream().
652 filter(item -> ("description".equals(item.getExtAttrName()))).
653 forEach(item -> item.setExtAttrName("uniqueMember"));
654 RESOURCE_SERVICE.update(ldap);
655
656
657 GroupCR groupCR = new GroupCR();
658 groupCR.setName("SYNCOPE354-" + getUUIDString());
659 groupCR.setRealm("/");
660 groupCR.getResources().add(RESOURCE_NAME_LDAP);
661
662 GroupTO groupTO = createGroup(groupCR).getEntity();
663 assertNotNull(groupTO);
664
665
666 UserCR userCR = UserITCase.getUniqueSample("syncope354@syncope.apache.org");
667 userCR.getResources().add(RESOURCE_NAME_LDAP);
668 userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build());
669
670 UserTO userTO = createUser(userCR).getEntity();
671 assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
672 assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey()));
673
674
675 ConnObject connObj = RESOURCE_SERVICE.readConnObject(
676 RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
677 assertNotNull(connObj);
678 assertTrue(connObj.getAttr("uniqueMember").get().getValues().
679 contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
680
681
682 UserUR userUR = new UserUR();
683 userUR.setKey(userTO.getKey());
684 userUR.getMemberships().add(new MembershipUR.Builder(userTO.getMemberships().get(0).getGroupKey()).
685 operation(PatchOperation.DELETE).build());
686
687 userTO = updateUser(userUR).getEntity();
688 assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
689
690
691 connObj = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
692 assertNotNull(connObj);
693 assertFalse(connObj.getAttr("uniqueMember").get().getValues().
694 contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
695
696
697 userTO = USER_SERVICE.read(userTO.getKey());
698 assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
699 assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey()));
700
701
702 ldap.getProvision(AnyTypeKind.GROUP.name()).get().getMapping().getItems().stream().
703 filter(item -> "uniqueMember".equals(item.getExtAttrName())).
704 forEach(item -> item.setExtAttrName("description"));
705 RESOURCE_SERVICE.update(ldap);
706 }
707
708 @Test
709 public void issueSYNCOPE357() throws IOException {
710
711 GroupCR groupCR = new GroupCR();
712 groupCR.setName("SYNCOPE357-" + getUUIDString());
713 groupCR.setRealm("/");
714 groupCR.getResources().add(RESOURCE_NAME_LDAP);
715
716 GroupTO groupTO = createGroup(groupCR).getEntity();
717 assertNotNull(groupTO);
718
719
720 UserCR userCR = UserITCase.getUniqueSample("syncope357@syncope.apache.org");
721 userCR.getPlainAttrs().add(attr("obscure", "valueToBeObscured"));
722 userCR.getPlainAttrs().add(attr("photo", Base64.getEncoder().encodeToString(
723 IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
724 userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build());
725
726 UserTO userTO = createUser(userCR).getEntity();
727 assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
728 assertNotNull(userTO.getPlainAttr("obscure"));
729 assertNotNull(userTO.getPlainAttr("photo"));
730
731
732 ConnObject connObj = RESOURCE_SERVICE.readConnObject(
733 RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
734 assertNotNull(connObj);
735 Attr registeredAddress = connObj.getAttr("registeredAddress").get();
736 assertNotNull(registeredAddress);
737 assertEquals(userTO.getPlainAttr("obscure").get().getValues(), registeredAddress.getValues());
738 Optional<Attr> jpegPhoto = connObj.getAttr("jpegPhoto");
739 assertTrue(jpegPhoto.isPresent());
740 assertEquals(userTO.getPlainAttr("photo").get().getValues().get(0), jpegPhoto.get().getValues().get(0));
741
742
743 GROUP_SERVICE.delete(groupTO.getKey());
744
745
746 try {
747 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
748 fail("This should not happen");
749 } catch (SyncopeClientException e) {
750 assertEquals(ClientExceptionType.NotFound, e.getType());
751 }
752 }
753
754 @Test
755 public void issueSYNCOPE383() {
756
757 UserCR userCR = UserITCase.getUniqueSample("syncope383@apache.org");
758 userCR.getResources().clear();
759 UserTO userTO = createUser(userCR).getEntity();
760 assertNotNull(userTO);
761
762
763 UserUR userUR = new UserUR();
764 userUR.setKey(userTO.getKey());
765 userUR.getResources().add(new StringPatchItem.Builder().
766 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
767
768 ProvisioningResult<UserTO> result = updateUser(userUR);
769 assertNotNull(result);
770 userTO = result.getEntity();
771 assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
772 assertNotEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
773 assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
774 userTO = result.getEntity();
775
776
777 userUR = new UserUR();
778 userUR.setKey(userTO.getKey());
779 userUR.setPassword(
780 new PasswordPatch.Builder().value(getUUIDString() + "abbcbcbddd123").resource(RESOURCE_NAME_TESTDB).
781 build());
782
783 result = updateUser(userUR);
784 assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
785 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
786 }
787
788 @Test
789 public void issueSYNCOPE402() {
790
791 UserCR userCR = new UserCR();
792 userCR.setRealm(SyncopeConstants.ROOT_REALM);
793 String userId = getUUIDString() + "syncope402@syncope.apache.org";
794 userCR.setUsername(userId);
795 userCR.setPassword("password123");
796
797 userCR.getPlainAttrs().add(attr("userId", userId));
798 userCR.getPlainAttrs().add(attr("fullname", userId));
799 userCR.getPlainAttrs().add(attr("surname", userId));
800
801 UserTO userTO = createUser(userCR).getEntity();
802 assertNotNull(userTO);
803 assertTrue(userTO.getResources().isEmpty());
804
805
806
807 UserUR userUR = new UserUR();
808 userUR.setKey(userTO.getKey());
809 userUR.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
810 userUR.getResources().add(new StringPatchItem.Builder().
811 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
812 userUR.getResources().add(new StringPatchItem.Builder().
813 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
814 ProvisioningResult<UserTO> result = updateUser(userUR);
815
816 PropagationStatus ws1PropagationStatus = result.getPropagationStatuses().stream().
817 filter(propStatus -> RESOURCE_NAME_WS1.equals(propStatus.getResource())).
818 findFirst().orElse(null);
819 assertNotNull(ws1PropagationStatus);
820 assertEquals(RESOURCE_NAME_WS1, ws1PropagationStatus.getResource());
821 assertNotNull(ws1PropagationStatus.getFailureReason());
822 assertEquals(ExecStatus.FAILURE, ws1PropagationStatus.getStatus());
823 }
824
825 @Test
826 public void issueSYNCOPE420() throws IOException {
827 ImplementationTO logicActions;
828 try {
829 logicActions = IMPLEMENTATION_SERVICE.read(
830 IdRepoImplementationType.LOGIC_ACTIONS, "DoubleValueLogicActions");
831 } catch (SyncopeClientException e) {
832 logicActions = new ImplementationTO();
833 logicActions.setKey("DoubleValueLogicActions");
834 logicActions.setEngine(ImplementationEngine.GROOVY);
835 logicActions.setType(IdRepoImplementationType.LOGIC_ACTIONS);
836 logicActions.setBody(org.apache.commons.io.IOUtils.toString(
837 getClass().getResourceAsStream("/DoubleValueLogicActions.groovy"), StandardCharsets.UTF_8));
838 Response response = IMPLEMENTATION_SERVICE.create(logicActions);
839 logicActions = IMPLEMENTATION_SERVICE.read(
840 logicActions.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
841 }
842 assertNotNull(logicActions);
843
844 RealmTO realm = REALM_SERVICE.search(new RealmQuery.Builder().keyword("two").build()).getResult().get(0);
845 assertNotNull(realm);
846 realm.getActions().add(logicActions.getKey());
847 REALM_SERVICE.update(realm);
848
849 UserCR userCR = UserITCase.getUniqueSample("syncope420@syncope.apache.org");
850 userCR.setRealm(realm.getFullPath());
851 userCR.getPlainAttrs().add(attr("makeItDouble", "3"));
852
853 UserTO userTO = createUser(userCR).getEntity();
854 assertEquals("6", userTO.getPlainAttr("makeItDouble").get().getValues().get(0));
855
856 UserUR userUR = new UserUR();
857 userUR.setKey(userTO.getKey());
858 userUR.getPlainAttrs().add(attrAddReplacePatch("makeItDouble", "7"));
859
860 userTO = updateUser(userUR).getEntity();
861 assertEquals("14", userTO.getPlainAttr("makeItDouble").get().getValues().get(0));
862 }
863
864 @Test
865 public void issueSYNCOPE426() {
866 UserCR userCR = UserITCase.getUniqueSample("syncope426@syncope.apache.org");
867 UserTO userTO = createUser(userCR).getEntity();
868 assertNotNull(userTO);
869
870 UserUR userUR = new UserUR();
871 userUR.setKey(userTO.getKey());
872 userUR.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
873 userTO = USER_SERVICE.update(userUR).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
874 }).getEntity();
875 assertNotNull(userTO);
876 }
877
878 @Test
879 public void issueSYNCOPE435() {
880
881 UserCR userCR = UserITCase.getUniqueSample("syncope435@syncope.apache.org");
882 userCR.setPassword(null);
883 userCR.setStorePassword(false);
884 UserTO userTO = createUser(userCR).getEntity();
885 assertNotNull(userTO);
886
887
888 UserUR userUR = new UserUR();
889 userUR.setKey(userTO.getKey());
890 userUR.getResources().add(new StringPatchItem.Builder().
891 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
892
893 ProvisioningResult<UserTO> result = updateUser(userUR);
894 assertNotNull(result);
895 userTO = result.getEntity();
896 assertEquals(Set.of(RESOURCE_NAME_WS1), userTO.getResources());
897 assertNotEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
898 assertTrue(result.getPropagationStatuses().get(0).getFailureReason().
899 startsWith("Not attempted because there are mandatory attributes without value(s): [__PASSWORD__]"));
900 }
901
902 @Test
903 public void issueSYNCOPE454() throws NamingException {
904
905 UserCR userCR = UserITCase.getUniqueSample("syncope454@syncope.apache.org");
906 userCR.getResources().add(RESOURCE_NAME_LDAP);
907 UserTO userTO = createUser(userCR).getEntity();
908 assertNotNull(userTO);
909
910
911 ConnObject connObject =
912 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
913
914
915 assertNotNull(getLdapRemoteObject(
916 connObject.getAttr(Name.NAME).get().getValues().get(0),
917 "password123",
918 connObject.getAttr(Name.NAME).get().getValues().get(0)));
919
920
921 UserUR userUR = new UserUR();
922 userUR.setKey(userTO.getKey());
923 userUR.setPassword(new PasswordPatch());
924 userUR.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));
925
926 USER_SERVICE.update(userUR);
927
928
929 assertNotNull(getLdapRemoteObject(
930 connObject.getAttr(Name.NAME).get().getValues().get(0),
931 "password123",
932 connObject.getAttr(Name.NAME).get().getValues().get(0)));
933 }
934
935 @Test
936 public void issueSYNCOPE493() {
937
938 UserCR userCR = UserITCase.getUniqueSample("493@test.org");
939 userCR.getResources().add(RESOURCE_NAME_WS1);
940 ProvisioningResult<UserTO> result = createUser(userCR);
941 assertNotNull(result);
942 assertEquals(1, result.getPropagationStatuses().size());
943 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
944 UserTO userTO = result.getEntity();
945
946 ConnObject actual =
947 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
948 assertNotNull(actual);
949
950 assertFalse(actual.getAttr("NAME").isPresent());
951
952
953 ResourceTO ws1 = RESOURCE_SERVICE.read(RESOURCE_NAME_WS1);
954 assertNotNull(ws1);
955
956 Mapping ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).get().getMapping();
957
958 ws1NewUMapping.getItems().stream().
959 filter(itemTO -> "firstname".equals(itemTO.getIntAttrName())).
960 forEach(itemTO -> itemTO.setPurpose(MappingPurpose.BOTH));
961
962 ws1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping);
963
964 RESOURCE_SERVICE.update(ws1);
965 ResourceTO newWs1 = RESOURCE_SERVICE.read(ws1.getKey());
966 assertNotNull(newWs1);
967
968
969 Collection<Item> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems();
970 assertNotNull(mapItems);
971 assertEquals(7, mapItems.size());
972
973
974 UserUR userUR = new UserUR();
975 userUR.setKey(userTO.getKey());
976 userUR.setPassword(new PasswordPatch());
977 userUR.getPlainAttrs().add(attrAddReplacePatch("firstname", "firstnameNew"));
978
979 result = updateUser(userUR);
980 assertNotNull(userTO);
981 assertEquals(1, result.getPropagationStatuses().size());
982 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
983 userTO = result.getEntity();
984
985 ConnObject newUser =
986 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
987
988 assertNotNull(newUser.getAttr("NAME"));
989 assertEquals("firstnameNew", newUser.getAttr("NAME").get().getValues().get(0));
990
991
992 ws1NewUMapping = newWs1.getProvision(AnyTypeKind.USER.name()).get().getMapping();
993
994 for (Item itemTO : ws1NewUMapping.getItems()) {
995 if ("firstname".equals(itemTO.getIntAttrName())) {
996 itemTO.setPurpose(MappingPurpose.NONE);
997 }
998 }
999
1000 newWs1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping);
1001
1002 RESOURCE_SERVICE.update(newWs1);
1003 }
1004
1005 @Test
1006 public void issueSYNCOPE505DB() throws Exception {
1007
1008 UserCR userCR = UserITCase.getUniqueSample("syncope505-db@syncope.apache.org");
1009 userCR.setPassword("security123");
1010 UserTO user = createUser(userCR).getEntity();
1011 assertNotNull(user);
1012 assertTrue(user.getResources().isEmpty());
1013
1014
1015 ImplementationTO propagationActions = new ImplementationTO();
1016 propagationActions.setKey(DBPasswordPropagationActions.class.getSimpleName());
1017 propagationActions.setEngine(ImplementationEngine.JAVA);
1018 propagationActions.setType(IdMImplementationType.PROPAGATION_ACTIONS);
1019 propagationActions.setBody(DBPasswordPropagationActions.class.getName());
1020 Response response = IMPLEMENTATION_SERVICE.create(propagationActions);
1021 propagationActions = IMPLEMENTATION_SERVICE.read(
1022 propagationActions.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
1023 assertNotNull(propagationActions);
1024
1025 ResourceTO resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_TESTDB);
1026 assertNotNull(resourceTO);
1027 resourceTO.getPropagationActions().add(propagationActions.getKey());
1028 RESOURCE_SERVICE.update(resourceTO);
1029
1030
1031 UserUR userUR = new UserUR();
1032 userUR.setKey(user.getKey());
1033 userUR.getResources().add(new StringPatchItem.Builder().
1034 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
1035
1036 userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_TESTDB).build());
1037
1038 user = updateUser(userUR).getEntity();
1039 assertNotNull(user);
1040 assertEquals(1, user.getResources().size());
1041
1042
1043 JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
1044 String value = jdbcTemplate.queryForObject(
1045 "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
1046 assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());
1047
1048
1049 resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_TESTDB);
1050 assertNotNull(resourceTO);
1051 resourceTO.getPropagationActions().remove(propagationActions.getKey());
1052 RESOURCE_SERVICE.update(resourceTO);
1053 }
1054
1055 @Test
1056 public void issueSYNCOPE505LDAP() throws Exception {
1057
1058 UserCR userCR = UserITCase.getUniqueSample("syncope505-ldap@syncope.apache.org");
1059 userCR.setPassword("security123");
1060 UserTO user = createUser(userCR).getEntity();
1061 assertNotNull(user);
1062 assertTrue(user.getResources().isEmpty());
1063
1064
1065 ResourceTO resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
1066 assertNotNull(resourceTO);
1067 resourceTO.getPropagationActions().add(LDAPPasswordPropagationActions.class.getSimpleName());
1068 resourceTO.getPropagationActions().remove(GenerateRandomPasswordPropagationActions.class.getSimpleName());
1069 RESOURCE_SERVICE.update(resourceTO);
1070
1071
1072 UserUR userUR = new UserUR();
1073 userUR.setKey(user.getKey());
1074 userUR.getResources().add(new StringPatchItem.Builder().
1075 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
1076
1077 userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
1078
1079 user = updateUser(userUR).getEntity();
1080 assertNotNull(user);
1081 assertEquals(1, user.getResources().size());
1082
1083
1084 ConnObject connObject =
1085 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
1086
1087 assertNotNull(getLdapRemoteObject(
1088 connObject.getAttr(Name.NAME).get().getValues().get(0),
1089 "security123",
1090 connObject.getAttr(Name.NAME).get().getValues().get(0)));
1091
1092
1093 resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
1094 assertNotNull(resourceTO);
1095 resourceTO.getPropagationActions().remove(LDAPPasswordPropagationActions.class.getSimpleName());
1096 resourceTO.getPropagationActions().add(0, GenerateRandomPasswordPropagationActions.class.getSimpleName());
1097 RESOURCE_SERVICE.update(resourceTO);
1098 }
1099
1100 @Test
1101 public void issueSYNCOPE391() {
1102 assumeFalse(IS_EXT_SEARCH_ENABLED);
1103
1104
1105 UserCR userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
1106 userCR.setPassword(null);
1107 userCR.setStorePassword(false);
1108
1109 UserTO userTO = createUser(userCR).getEntity();
1110 assertNotNull(userTO);
1111 assertNull(userTO.getPassword());
1112
1113
1114
1115 userCR = new UserCR();
1116 userCR.setRealm(SyncopeConstants.ROOT_REALM);
1117 userCR.setPassword(null);
1118 userCR.setStorePassword(false);
1119 userCR.setUsername("syncope391@syncope.apache.org");
1120 userCR.getPlainAttrs().add(attr("fullname", "fullname"));
1121 userCR.getPlainAttrs().add(attr("firstname", "nome0"));
1122 userCR.getPlainAttrs().add(attr("surname", "cognome0"));
1123 userCR.getPlainAttrs().add(attr("userId", "syncope391@syncope.apache.org"));
1124 userCR.getPlainAttrs().add(attr("email", "syncope391@syncope.apache.org"));
1125 userCR.getAuxClasses().add("csv");
1126 userCR.getResources().add(RESOURCE_NAME_CSV);
1127
1128 userTO = createUser(userCR).getEntity();
1129 assertNotNull(userTO);
1130
1131 ConnObject connObjectTO =
1132 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
1133 assertNotNull(connObjectTO);
1134
1135
1136 assertEquals("password0", connObjectTO.getAttr(OperationalAttributes.PASSWORD_NAME).get().getValues().get(0));
1137 assertNull(userTO.getPassword());
1138
1139
1140
1141 userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
1142 userCR.setPassword("passwordTESTNULL1");
1143 userCR.setStorePassword(false);
1144 userCR.getVirAttrs().clear();
1145 userCR.getAuxClasses().add("csv");
1146 userCR.getResources().add(RESOURCE_NAME_CSV);
1147
1148 userTO = createUser(userCR).getEntity();
1149 assertNotNull(userTO);
1150
1151 connObjectTO =
1152 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
1153 assertNotNull(connObjectTO);
1154
1155
1156 assertEquals(
1157 "passwordTESTNULL1",
1158 connObjectTO.getAttr(OperationalAttributes.PASSWORD_NAME).get().getValues().get(0));
1159 assertNull(userTO.getPassword());
1160
1161
1162 userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
1163 userCR.setPassword("passwordTESTNULL1");
1164 userCR.getVirAttrs().clear();
1165 userCR.getAuxClasses().add("csv");
1166 userCR.getResources().add(RESOURCE_NAME_CSV);
1167
1168
1169 userTO = createUser(userCR).getEntity();
1170 assertNotNull(userTO);
1171
1172 connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
1173 assertNotNull(connObjectTO);
1174
1175
1176 assertEquals(
1177 "passwordTESTNULL1",
1178 connObjectTO.getAttr(OperationalAttributes.PASSWORD_NAME).get().getValues().get(0));
1179 Triple<Map<String, Set<String>>, List<String>, UserTO> self =
1180 CLIENT_FACTORY.create(userTO.getUsername(), "passwordTESTNULL1").self();
1181 assertNotNull(self);
1182
1183
1184 ResourceTO csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV);
1185 assertNotNull(csv);
1186 try {
1187 csv.setPasswordPolicy("55e5de0b-c79c-4e66-adda-251b6fb8579a");
1188 RESOURCE_SERVICE.update(csv);
1189 csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV);
1190 assertEquals("55e5de0b-c79c-4e66-adda-251b6fb8579a", csv.getPasswordPolicy());
1191
1192 userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
1193 userCR.setPassword(null);
1194 userCR.setStorePassword(false);
1195 userCR.getVirAttrs().clear();
1196 userCR.getAuxClasses().add("csv");
1197 userCR.getResources().add(RESOURCE_NAME_CSV);
1198
1199 createUser(userCR);
1200 fail("This should not happen");
1201 } catch (SyncopeClientException e) {
1202 assertEquals(ClientExceptionType.InvalidUser, e.getType());
1203 assertTrue(e.getMessage().contains("Password mandatory"));
1204 } finally {
1205
1206 csv.setPasswordPolicy(null);
1207 RESOURCE_SERVICE.update(csv);
1208 }
1209 }
1210
1211 @Test
1212 public void issueSYNCOPE647() {
1213 UserCR userCR = UserITCase.getUniqueSample("syncope647@syncope.apache.org");
1214 userCR.getResources().clear();
1215 userCR.getMemberships().clear();
1216 userCR.getVirAttrs().clear();
1217 userCR.getAuxClasses().add("csv");
1218
1219 userCR.getAuxClasses().add("generic membership");
1220 userCR.getPlainAttrs().add(attr("postalAddress", "postalAddress"));
1221
1222 userCR.getResources().add(RESOURCE_NAME_LDAP);
1223
1224 UserTO actual = createUser(userCR).getEntity();
1225 assertNotNull(actual);
1226 assertNotNull(actual.getDerAttr("csvuserid"));
1227
1228 ConnObject connObjectTO =
1229 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
1230 assertNotNull(connObjectTO);
1231 assertEquals("postalAddress", connObjectTO.getAttr("postalAddress").get().getValues().get(0));
1232
1233 UserUR userUR = new UserUR();
1234 userUR.setKey(actual.getKey());
1235 userUR.getPlainAttrs().add(attrAddReplacePatch("postalAddress", "newPostalAddress"));
1236
1237 actual = updateUser(userUR).getEntity();
1238
1239 connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
1240 assertNotNull(connObjectTO);
1241 assertEquals("newPostalAddress", connObjectTO.getAttr("postalAddress").get().getValues().get(0));
1242 }
1243
1244 @Test
1245 public void issueSYNCOPE626() {
1246 DefaultPasswordRuleConf ruleConf = new DefaultPasswordRuleConf();
1247 ruleConf.setUsernameAllowed(false);
1248
1249 ImplementationTO rule = new ImplementationTO();
1250 rule.setKey("DefaultPasswordRuleConf" + getUUIDString());
1251 rule.setEngine(ImplementationEngine.JAVA);
1252 rule.setType(IdRepoImplementationType.PASSWORD_RULE);
1253 rule.setBody(POJOHelper.serialize(ruleConf));
1254 Response response = IMPLEMENTATION_SERVICE.create(rule);
1255 rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));
1256
1257 PasswordPolicyTO passwordPolicy = new PasswordPolicyTO();
1258 passwordPolicy.setName("Password Policy for SYNCOPE-626");
1259 passwordPolicy.getRules().add(rule.getKey());
1260
1261 passwordPolicy = createPolicy(PolicyType.PASSWORD, passwordPolicy);
1262 assertNotNull(passwordPolicy);
1263
1264 RealmTO realm = REALM_SERVICE.search(new RealmQuery.Builder().keyword("two").build()).getResult().get(0);
1265 String oldPasswordPolicy = realm.getPasswordPolicy();
1266 realm.setPasswordPolicy(passwordPolicy.getKey());
1267 REALM_SERVICE.update(realm);
1268
1269 try {
1270 UserCR userCR = UserITCase.getUniqueSample("syncope626@syncope.apache.org");
1271 userCR.setRealm(realm.getFullPath());
1272 userCR.setPassword(userCR.getUsername());
1273 try {
1274 createUser(userCR);
1275 fail("This should not happen");
1276 } catch (SyncopeClientException e) {
1277 assertEquals(ClientExceptionType.InvalidUser, e.getType());
1278 assertTrue(e.getElements().iterator().next().startsWith("InvalidPassword"));
1279 }
1280
1281 userCR.setPassword("password123");
1282 UserTO user = createUser(userCR).getEntity();
1283 assertNotNull(user);
1284 } finally {
1285 realm.setPasswordPolicy(oldPasswordPolicy);
1286 REALM_SERVICE.update(realm);
1287
1288 POLICY_SERVICE.delete(PolicyType.PASSWORD, passwordPolicy.getKey());
1289 }
1290
1291 }
1292
1293 @Test
1294 public void issueSYNCOPE686() {
1295
1296 String origpwdCipherAlgo = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
1297 "password.cipher.algorithm", null, String.class);
1298
1299
1300 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "AES");
1301
1302 try {
1303
1304 GroupCR groupCR = GroupITCase.getBasicSample("syncope686");
1305 groupCR.getResources().add(RESOURCE_NAME_LDAP);
1306 GroupTO group = createGroup(groupCR).getEntity();
1307 assertNotNull(group);
1308
1309
1310 UserCR userCR = UserITCase.getUniqueSample("syncope686@apache.org");
1311 userCR.getResources().clear();
1312
1313 UserTO userTO = createUser(userCR).getEntity();
1314 assertNotNull(userTO);
1315
1316
1317 UserUR userUR = new UserUR();
1318 userUR.setKey(userTO.getKey());
1319 userUR.getMemberships().add(new MembershipUR.Builder(group.getKey()).
1320 operation(PatchOperation.ADD_REPLACE).build());
1321
1322 ProvisioningResult<UserTO> result = updateUser(userUR);
1323 assertNotNull(result);
1324
1325
1326 List<PropagationStatus> props = result.getPropagationStatuses();
1327 assertNotNull(props);
1328 assertEquals(1, props.size());
1329 PropagationStatus prop = props.get(0);
1330 assertNotNull(prop);
1331 assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
1332 assertEquals(ExecStatus.SUCCESS, prop.getStatus());
1333 } finally {
1334
1335 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", origpwdCipherAlgo);
1336 }
1337 }
1338
1339 @Test
1340 public void issueSYNCOPE710() {
1341
1342 GroupCR ldapGroupCR = GroupITCase.getBasicSample("syncope710.ldap");
1343 ldapGroupCR.getResources().add(RESOURCE_NAME_LDAP);
1344 GroupTO ldapGroup = createGroup(ldapGroupCR).getEntity();
1345
1346 GroupCR dbGroupCR = GroupITCase.getBasicSample("syncope710.db");
1347 dbGroupCR.getResources().add(RESOURCE_NAME_TESTDB);
1348 GroupTO dbGroup = createGroup(dbGroupCR).getEntity();
1349
1350
1351 UserCR userCR = UserITCase.getUniqueSample("syncope710@syncope.apache.org");
1352 userCR.getResources().clear();
1353 userCR.getMemberships().clear();
1354 userCR.getMemberships().add(new MembershipTO.Builder(ldapGroup.getKey()).build());
1355 userCR.getMemberships().add(new MembershipTO.Builder(dbGroup.getKey()).build());
1356
1357 ProvisioningResult<UserTO> result = createUser(userCR);
1358 assertEquals(2, result.getPropagationStatuses().size());
1359 UserTO userTO = result.getEntity();
1360
1361
1362 UserUR userUR = new UserUR();
1363 userUR.setKey(userTO.getKey());
1364 userUR.setPassword(new PasswordPatch.Builder().
1365 onSyncope(false).resource(RESOURCE_NAME_TESTDB).value("newpassword123").build());
1366
1367 result = updateUser(userUR);
1368 assertEquals(1, result.getPropagationStatuses().size());
1369 assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().get(0).getResource());
1370 }
1371
1372 @Test
1373 public void issueSYNCOPE881() {
1374
1375 GroupCR groupCR = GroupITCase.getSample("syncope881G");
1376 groupCR.getVirAttrs().add(attr("rvirtualdata", "rvirtualvalue"));
1377
1378 GroupTO group = createGroup(groupCR).getEntity();
1379 assertNotNull(group);
1380 assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), group.getKey()));
1381
1382
1383 UserCR userCR = UserITCase.getUniqueSample("syncope881U@apache.org");
1384 userCR.getMemberships().clear();
1385 userCR.getMemberships().add(new MembershipTO.Builder(group.getKey()).build());
1386
1387 UserTO user = createUser(userCR).getEntity();
1388 assertNotNull(user);
1389
1390
1391 ConnObject connObject =
1392 RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
1393 assertNotNull(connObject);
1394 Attr userDn = connObject.getAttr(Name.NAME).get();
1395 assertNotNull(userDn);
1396 assertEquals(1, userDn.getValues().size());
1397 assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, userDn.getValues().get(0)));
1398
1399
1400 USER_SERVICE.delete(user.getKey());
1401
1402
1403 assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, userDn.getValues().get(0)));
1404 }
1405
1406 @Test
1407 public void issueSYNCOPE1099() {
1408
1409 GroupCR groupCR = GroupITCase.getSample("syncope1099G");
1410 groupCR.getResources().clear();
1411 groupCR.getResources().add(RESOURCE_NAME_TESTDB);
1412 groupCR.setUDynMembershipCond("firstname==issueSYNCOPE1099");
1413
1414 GroupTO group = createGroup(groupCR).getEntity();
1415 assertNotNull(group);
1416
1417
1418 UserCR userCR = UserITCase.getUniqueSample("syncope1099U@apache.org");
1419 userCR.getPlainAttr("firstname").get().getValues().set(0, "issueSYNCOPE1099");
1420
1421 ProvisioningResult<UserTO> created = createUser(userCR);
1422 assertNotNull(created);
1423
1424
1425 UserTO user = created.getEntity();
1426 String groupKey = group.getKey();
1427 assertTrue(user.getDynMemberships().stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
1428 assertTrue(user.getResources().contains(RESOURCE_NAME_TESTDB));
1429
1430
1431 assertFalse(created.getPropagationStatuses().isEmpty());
1432 assertEquals(RESOURCE_NAME_TESTDB, created.getPropagationStatuses().get(0).getResource());
1433 }
1434
1435 @Test
1436 public void issueSYNCOPE1166() {
1437 UserCR userCR = UserITCase.getUniqueSample("syncope1166@apache.org");
1438 UserTO userTO = createUser(userCR).getEntity();
1439 assertNotNull(userTO);
1440
1441 UserUR userUR = new UserUR();
1442 userUR.setKey(userTO.getKey());
1443
1444 userUR.setPassword(new PasswordPatch.Builder().
1445 onSyncope(true).
1446 resource(RESOURCE_NAME_LDAP).
1447 value("new2Password").build());
1448
1449 userUR.getResources().add(new StringPatchItem.Builder().
1450 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
1451 userUR.getResources().add(new StringPatchItem.Builder().
1452 operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_DBVIRATTR).build());
1453
1454 ProvisioningResult<UserTO> result = updateUser(userUR);
1455 assertNotNull(result);
1456 assertEquals(2, result.getPropagationStatuses().size());
1457 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
1458 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
1459 assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(1).getResource());
1460 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(1).getStatus());
1461 }
1462
1463 @Test
1464 public void issueSYNCOPE1206() {
1465
1466 GroupCR dynGroupCR = GroupITCase.getSample("syncope1206");
1467 dynGroupCR.setUDynMembershipCond(
1468 SyncopeClient.getUserSearchConditionBuilder().is("cool").equalTo("true").query());
1469 GroupTO dynGroup = createGroup(dynGroupCR).getEntity();
1470 assertNotNull(dynGroup);
1471 assertTrue(dynGroup.getResources().contains(RESOURCE_NAME_LDAP));
1472
1473
1474 UserCR userCR = UserITCase.getUniqueSample("syncope1206@apache.org");
1475 userCR.getResources().clear();
1476
1477 ProvisioningResult<UserTO> result = createUser(userCR);
1478 assertTrue(result.getPropagationStatuses().isEmpty());
1479
1480
1481 UserUR userUR = new UserUR();
1482 userUR.setKey(result.getEntity().getKey());
1483 userUR.getPlainAttrs().add(new AttrPatch.Builder(attr("cool", "true")).build());
1484
1485 result = updateUser(userUR);
1486 assertEquals(1, result.getPropagationStatuses().size());
1487 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
1488
1489
1490 userUR = new UserUR();
1491 userUR.setKey(result.getEntity().getKey());
1492 userUR.getPlainAttrs().add(new AttrPatch.Builder(attr("cool", "false")).build());
1493
1494 result = updateUser(userUR);
1495 assertEquals(1, result.getPropagationStatuses().size());
1496 assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
1497 }
1498
1499 @Test
1500 public void issueSYNCOPE1337() {
1501
1502 String original = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
1503 "password.cipher.algorithm", null, String.class);
1504
1505 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", CipherAlgorithm.SSHA512.name());
1506
1507 try {
1508
1509 UserCR userCR = UserITCase.getUniqueSample("syncope1337@apache.org");
1510 userCR.setPassword("Password123");
1511 userCR.setRealm("/even/two");
1512 UserTO userTO = createUser(userCR).getEntity();
1513 assertNotNull(userTO);
1514
1515
1516 UserUR req = new UserUR();
1517 req.setKey(userTO.getKey());
1518 req.setPassword(new PasswordPatch.Builder().onSyncope(true).value("Password123").build());
1519 try {
1520 updateUser(req);
1521 fail("Password update should not work");
1522 } catch (SyncopeClientException e) {
1523 assertEquals(ClientExceptionType.InvalidUser, e.getType());
1524 assertTrue(e.getMessage().contains("InvalidPassword"));
1525 }
1526
1527
1528 req.setPassword(new PasswordPatch.Builder().onSyncope(true).value("Password124").build());
1529 userTO = updateUser(req).getEntity();
1530 assertNotNull(userTO);
1531
1532
1533 req.setPassword(new PasswordPatch.Builder().onSyncope(true).value("Password123").build());
1534 userTO = updateUser(req).getEntity();
1535 assertNotNull(userTO);
1536 } finally {
1537
1538 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", original);
1539 }
1540 }
1541
1542 @Test
1543 public void issueSYNCOPE1472() {
1544
1545 UserUR userUR = new UserUR();
1546 userUR.setKey("1417acbe-cbf6-4277-9372-e75e04f97000");
1547 userUR.setPassword(new PasswordPatch.Builder()
1548 .onSyncope(false)
1549 .resource(RESOURCE_NAME_TESTDB)
1550 .value("Password123")
1551 .build());
1552 userUR.getResources().add(new StringPatchItem.Builder()
1553 .value(RESOURCE_NAME_TESTDB)
1554 .operation(PatchOperation.ADD_REPLACE)
1555 .build());
1556 userUR.getAuxClasses().add(new StringPatchItem.Builder()
1557 .operation(PatchOperation.ADD_REPLACE)
1558 .value("csv")
1559 .build());
1560 userUR.getRoles().add(new StringPatchItem.Builder()
1561 .operation(PatchOperation.ADD_REPLACE)
1562 .value("Other")
1563 .build());
1564
1565 updateUser(userUR);
1566 updateUser(userUR);
1567
1568
1569 userUR.getResources().clear();
1570 userUR.getResources().add(new StringPatchItem.Builder()
1571 .value(RESOURCE_NAME_TESTDB)
1572 .operation(PatchOperation.DELETE)
1573 .build());
1574 userUR.getAuxClasses().clear();
1575 userUR.getAuxClasses().add(new StringPatchItem.Builder()
1576 .value("csv")
1577 .operation(PatchOperation.DELETE)
1578 .build());
1579 userUR.getRoles().clear();
1580 userUR.getRoles().add(new StringPatchItem.Builder()
1581 .value("Other")
1582 .operation(PatchOperation.DELETE)
1583 .build());
1584 updateUser(userUR);
1585
1586 UserTO userTO = USER_SERVICE.read("1417acbe-cbf6-4277-9372-e75e04f97000");
1587 assertFalse(userTO.getResources().contains(RESOURCE_NAME_TESTDB), "Should not contain removed resources");
1588 assertFalse(userTO.getAuxClasses().contains("csv"), "Should not contain removed auxiliary classes");
1589 assertFalse(userTO.getRoles().contains("Other"), "Should not contain removed roles");
1590 }
1591
1592 @Test
1593 public void issueSYNCOPE1699() throws Exception {
1594 UserTO userTO = createUser(UserITCase.getUniqueSample("syncope1669@apache.org")).getEntity();
1595
1596 UserUR req = new UserUR();
1597 req.setUsername(new StringReplacePatchItem.Builder().value("newUsername" + getUUIDString()).build());
1598
1599 WebClient webClient = WebClient.create(ADDRESS + "/users/" + userTO.getKey(), ADMIN_UNAME, ADMIN_PWD, null).
1600 accept(MediaType.APPLICATION_JSON_TYPE).
1601 type(MediaType.APPLICATION_JSON_TYPE);
1602
1603 Response response = webClient.invoke(HttpMethod.PATCH, JSON_MAPPER.writeValueAsString(req));
1604 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
1605
1606
1607 req.setKey(UUID.randomUUID().toString());
1608 response = webClient.invoke(HttpMethod.PATCH, JSON_MAPPER.writeValueAsString(req));
1609 assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
1610
1611
1612 userTO = USER_SERVICE.read(req.getUsername().getValue());
1613 assertNotNull(userTO);
1614 }
1615
1616 @Test
1617 public void issueSYNCOPE1750() {
1618 UserCR userCR = UserITCase.getUniqueSample("syncope1750@apache.org");
1619 userCR.getResources().add(RESOURCE_NAME_NOPROPAGATION);
1620 UserTO userTO = createUser(userCR).getEntity();
1621
1622 UserUR req = new UserUR.Builder(userTO.getKey()).password(new PasswordPatch.Builder().
1623 onSyncope(false).resource(RESOURCE_NAME_NOPROPAGATION).value("short").build()).build();
1624
1625 try {
1626 USER_SERVICE.update(req);
1627 fail();
1628 } catch (SyncopeClientException e) {
1629 assertEquals(ClientExceptionType.InvalidUser, e.getType());
1630 assertTrue(e.getMessage().contains("InvalidPassword: Password must be 10 or more characters in length."));
1631 }
1632 }
1633
1634 @Test
1635 public void issueSYNCOPE1793() {
1636 RoleTO role = new RoleTO();
1637 role.setKey("syncope1793" + getUUIDString());
1638 role.getRealms().add(SyncopeConstants.ROOT_REALM);
1639 role.getEntitlements().add(IdRepoEntitlement.USER_UPDATE);
1640 role = createRole(role);
1641
1642 UserCR userCR = UserITCase.getUniqueSample("syncope1793@apache.org");
1643 userCR.getRoles().add(role.getKey());
1644 UserTO userTO = createUser(userCR).getEntity();
1645
1646 UserService userService = CLIENT_FACTORY.create(userTO.getUsername(), "password123").
1647 getService(UserService.class);
1648 Response response = userService.associate(new ResourceAR.Builder().key(userTO.getKey()).
1649 resource(RESOURCE_NAME_NOPROPAGATION).action(ResourceAssociationAction.ASSIGN).build());
1650 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
1651 }
1652
1653 @Test
1654 public void issueSYNCOPE1809() throws IOException {
1655
1656 PlainSchemaTO externalKeySchemaTO = new PlainSchemaTO();
1657 externalKeySchemaTO.setKey("externalKey");
1658 externalKeySchemaTO.setType(AttrSchemaType.String);
1659 externalKeySchemaTO.setReadonly(true);
1660 SCHEMA_SERVICE.create(SchemaType.PLAIN, externalKeySchemaTO);
1661 try {
1662 AnyTypeClassTO minimalUser = ANY_TYPE_CLASS_SERVICE.read("minimal user");
1663 minimalUser.getPlainSchemas().add(externalKeySchemaTO.getKey());
1664 ANY_TYPE_CLASS_SERVICE.update(minimalUser);
1665 ResourceTO restResourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_REST);
1666 restResourceTO.getProvision(AnyTypeKind.USER.name())
1667 .ifPresent(p -> p.setUidOnCreate(externalKeySchemaTO.getKey()));
1668 RESOURCE_SERVICE.update(restResourceTO);
1669 UserCR userCR = UserITCase.getUniqueSample("rest@syncope.apache.org");
1670 userCR.getResources().clear();
1671 userCR.getResources().add(RESOURCE_NAME_REST);
1672
1673
1674 ProvisioningResult<UserTO> result = createUser(userCR);
1675 assertEquals(1, result.getPropagationStatuses().size());
1676 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
1677 assertEquals(RESOURCE_NAME_REST, result.getPropagationStatuses().get(0).getResource());
1678 assertEquals("surname", result.getEntity().getPlainAttr("surname").get().getValues().get(0));
1679
1680 assertTrue(result.getEntity().getPlainAttr("externalKey").isPresent());
1681 assertEquals(result.getEntity().getKey(),
1682 result.getEntity().getPlainAttr("externalKey").get().getValues().get(0));
1683
1684 result = updateUser(new UserUR.Builder(result.getEntity()
1685 .getKey()).resource(new StringPatchItem.Builder().value(RESOURCE_NAME_REST)
1686 .operation(PatchOperation.DELETE)
1687 .build()).build());
1688 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
1689
1690 assertFalse(result.getEntity().getPlainAttr("externalKey").isPresent());
1691
1692
1693 userCR = UserITCase.getUniqueSample("rest@syncope.apache.org");
1694 userCR.getResources().clear();
1695 userCR.getResources().add(RESOURCE_NAME_REST);
1696 result = createUser(userCR);
1697 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
1698
1699 assertNotNull(parseBatchResponse(USER_SERVICE.deassociate(new ResourceDR.Builder().key(result.getEntity()
1700 .getKey()).action(ResourceDeassociationAction.DEPROVISION).resource(RESOURCE_NAME_REST).build())));
1701 UserTO restUserTO = USER_SERVICE.read(result.getEntity().getKey());
1702 assertFalse(restUserTO.getPlainAttr("externalKey").isPresent());
1703
1704
1705 userCR = UserITCase.getUniqueSample("rest@syncope.apache.org");
1706 userCR.getResources().clear();
1707 userCR.getResources().add(RESOURCE_NAME_REST);
1708 result = createUser(userCR);
1709 assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
1710
1711 assertNotNull(parseBatchResponse(USER_SERVICE.deassociate(new ResourceDR.Builder().key(result.getEntity()
1712 .getKey()).action(ResourceDeassociationAction.UNLINK).resource(RESOURCE_NAME_REST).build())));
1713 restUserTO = USER_SERVICE.read(result.getEntity().getKey());
1714 assertTrue(restUserTO.getPlainAttr("externalKey").isPresent());
1715 } finally {
1716
1717 SCHEMA_SERVICE.delete(SchemaType.PLAIN, externalKeySchemaTO.getKey());
1718 }
1719 }
1720
1721 @Test
1722 void issueSYNCOPE1818() {
1723 UserTO rossini = USER_SERVICE.read("rossini");
1724 try {
1725
1726 updateUser(new UserUR.Builder(rossini.getKey()).
1727 plainAttr(attrAddReplacePatch("email", "rossini@apache.org")).
1728 resource(new StringPatchItem.Builder().value(RESOURCE_NAME_DBPULL).build()).
1729 build());
1730
1731
1732 ExecTO execution = AbstractTaskITCase.execProvisioningTask(TASK_SERVICE,
1733 TaskType.PULL,
1734 "7c2242f4-14af-4ab5-af31-cdae23783655",
1735 MAX_WAIT_SECONDS,
1736 false);
1737 assertEquals("SUCCESS", execution.getStatus());
1738 assertFalse(rossini.isSuspended());
1739 assertEquals("active", rossini.getStatus());
1740
1741
1742 PushTaskTO pushTaskTO = new PushTaskTO();
1743 pushTaskTO.setSourceRealm(SyncopeConstants.ROOT_REALM);
1744 pushTaskTO.setMatchingRule(MatchingRule.UPDATE);
1745 pushTaskTO.setUnmatchingRule(UnmatchingRule.ASSIGN);
1746 pushTaskTO.setPerformCreate(true);
1747 pushTaskTO.setPerformUpdate(true);
1748 pushTaskTO.setSyncStatus(true);
1749 RECONCILIATION_SERVICE.push(new ReconQuery.Builder(AnyTypeKind.USER.name(), RESOURCE_NAME_LDAP).anyKey(
1750 rossini.getKey()).build(), pushTaskTO);
1751
1752
1753 JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
1754 jdbcTemplate.update("UPDATE TESTPULL SET EMAIL ='gioacchino.rossini@apache.org', STATUS = "
1755 + "'false' WHERE USERNAME = 'rossini'");
1756
1757
1758 execution = AbstractTaskITCase.execProvisioningTask(
1759 TASK_SERVICE,
1760 TaskType.PULL,
1761 "7c2242f4-14af-4ab5-af31-cdae23783655",
1762 MAX_WAIT_SECONDS,
1763 false);
1764 assertEquals("SUCCESS", execution.getStatus());
1765
1766 rossini = USER_SERVICE.read("rossini");
1767 assertTrue(rossini.isSuspended());
1768 assertEquals("suspended", rossini.getStatus());
1769 assertTrue(rossini.getPlainAttr("email").get().getValues().contains("gioacchino.rossini@apache.org"));
1770
1771 ReconStatus onLDAP = RECONCILIATION_SERVICE.status(new ReconQuery.Builder(AnyTypeKind.USER.name(),
1772 RESOURCE_NAME_LDAP).anyKey(rossini.getKey()).build());
1773 Attr enableAttr = onLDAP.getOnResource().getAttr(OperationalAttributes.ENABLE_NAME).orElseThrow();
1774 assertFalse(Boolean.parseBoolean(enableAttr.getValues().get(0)));
1775
1776
1777 jdbcTemplate.update("UPDATE TESTPULL SET EMAIL = 'rossini.gioacchino@apache.org', STATUS = "
1778 + "'true' WHERE USERNAME = 'rossini'");
1779
1780
1781 execution = AbstractTaskITCase.execProvisioningTask(
1782 TASK_SERVICE,
1783 TaskType.PULL,
1784 "7c2242f4-14af-4ab5-af31-cdae23783655",
1785 MAX_WAIT_SECONDS,
1786 false);
1787 assertEquals("SUCCESS", execution.getStatus());
1788
1789 rossini = USER_SERVICE.read("rossini");
1790 assertFalse(rossini.isSuspended());
1791 assertEquals("active", rossini.getStatus());
1792
1793 if (!IS_FLOWABLE_ENABLED) {
1794
1795
1796 assertTrue(rossini.getPlainAttr("email").get().getValues().contains("rossini.gioacchino@apache.org"));
1797
1798 onLDAP = RECONCILIATION_SERVICE.status(new ReconQuery.Builder(
1799 AnyTypeKind.USER.name(), RESOURCE_NAME_LDAP).anyKey(rossini.getKey()).build());
1800 enableAttr = onLDAP.getOnResource().getAttr(OperationalAttributes.ENABLE_NAME).orElseThrow();
1801 assertTrue(Boolean.parseBoolean(enableAttr.getValues().get(0)));
1802 }
1803 } finally {
1804
1805 updateUser(new UserUR.Builder(rossini.getKey()).
1806 plainAttrs(
1807 attrAddReplacePatch("surname", "Rossini"),
1808 new AttrPatch.Builder(
1809 new Attr.Builder("email").build()).operation(PatchOperation.DELETE).build()).
1810 resource(new StringPatchItem.Builder().
1811 value(RESOURCE_NAME_DBPULL).operation(PatchOperation.DELETE).build()).
1812 build());
1813
1814 if (USER_SERVICE.read("rossini").isSuspended()) {
1815 USER_SERVICE.status(new StatusR.Builder(rossini.getKey(), StatusRType.REACTIVATE).onSyncope(true)
1816 .resources(rossini.getResources()).build());
1817 }
1818
1819 JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
1820 jdbcTemplate.update("DELETE FROM TESTPULL WHERE USERNAME = 'rossini'");
1821 }
1822 }
1823 }