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
28 import com.fasterxml.jackson.databind.node.ObjectNode;
29 import java.util.List;
30 import java.util.Optional;
31 import java.util.UUID;
32 import javax.naming.NamingException;
33 import javax.ws.rs.core.HttpHeaders;
34 import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.Response;
36 import org.apache.commons.lang3.RandomStringUtils;
37 import org.apache.commons.lang3.StringUtils;
38 import org.apache.cxf.jaxrs.client.WebClient;
39 import org.apache.syncope.common.lib.SyncopeClientException;
40 import org.apache.syncope.common.lib.SyncopeConstants;
41 import org.apache.syncope.common.lib.policy.PullPolicyTO;
42 import org.apache.syncope.common.lib.request.LinkedAccountUR;
43 import org.apache.syncope.common.lib.request.UserCR;
44 import org.apache.syncope.common.lib.request.UserUR;
45 import org.apache.syncope.common.lib.to.ConnObject;
46 import org.apache.syncope.common.lib.to.ExecTO;
47 import org.apache.syncope.common.lib.to.ImplementationTO;
48 import org.apache.syncope.common.lib.to.LinkedAccountTO;
49 import org.apache.syncope.common.lib.to.PagedResult;
50 import org.apache.syncope.common.lib.to.PropagationTaskTO;
51 import org.apache.syncope.common.lib.to.PullTaskTO;
52 import org.apache.syncope.common.lib.to.PushTaskTO;
53 import org.apache.syncope.common.lib.to.ResourceTO;
54 import org.apache.syncope.common.lib.to.TaskTO;
55 import org.apache.syncope.common.lib.to.UserTO;
56 import org.apache.syncope.common.lib.types.AnyTypeKind;
57 import org.apache.syncope.common.lib.types.ExecStatus;
58 import org.apache.syncope.common.lib.types.IdMImplementationType;
59 import org.apache.syncope.common.lib.types.ImplementationEngine;
60 import org.apache.syncope.common.lib.types.MatchingRule;
61 import org.apache.syncope.common.lib.types.PatchOperation;
62 import org.apache.syncope.common.lib.types.PolicyType;
63 import org.apache.syncope.common.lib.types.PullMode;
64 import org.apache.syncope.common.lib.types.ResourceOperation;
65 import org.apache.syncope.common.lib.types.TaskType;
66 import org.apache.syncope.common.lib.types.UnmatchingRule;
67 import org.apache.syncope.common.rest.api.RESTHeaders;
68 import org.apache.syncope.common.rest.api.beans.TaskQuery;
69 import org.apache.syncope.common.rest.api.service.TaskService;
70 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
71 import org.apache.syncope.fit.AbstractITCase;
72 import org.apache.syncope.fit.core.reference.LinkedAccountSamplePullCorrelationRule;
73 import org.apache.syncope.fit.core.reference.LinkedAccountSamplePullCorrelationRuleConf;
74 import org.junit.jupiter.api.Test;
75
76 public class LinkedAccountITCase extends AbstractITCase {
77
78 @Test
79 public void createWithLinkedAccountThenUpdateThenRemove() throws NamingException {
80
81 UserCR userCR = UserITCase.getSample(
82 "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
83 String connObjectKeyValue = "firstAccountOf" + userCR.getUsername();
84 String privilege = APPLICATION_SERVICE.read("mightyApp").getPrivileges().get(0).getKey();
85
86 LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
87 account.getPlainAttrs().add(attr("surname", "LINKED_SURNAME"));
88 account.getPrivileges().add(privilege);
89 userCR.getLinkedAccounts().add(account);
90
91 UserTO user = createUser(userCR).getEntity();
92 assertNotNull(user.getKey());
93 assertEquals(privilege, user.getLinkedAccounts().get(0).getPrivileges().iterator().next());
94
95
96 PagedResult<PropagationTaskTO> tasks = TASK_SERVICE.search(
97 new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
98 anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
99 assertEquals(1, tasks.getTotalCount());
100 assertEquals(connObjectKeyValue, tasks.getResult().get(0).getConnObjectKey());
101 assertEquals(ResourceOperation.CREATE, tasks.getResult().get(0).getOperation());
102 assertEquals(ExecStatus.SUCCESS.name(), tasks.getResult().get(0).getLatestExecStatus());
103
104 ConnObject ldapObj = RESOURCE_SERVICE.readConnObject(
105 RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), connObjectKeyValue);
106 assertNotNull(ldapObj);
107 assertEquals(user.getPlainAttr("email").get().getValues(), ldapObj.getAttr("mail").get().getValues());
108 assertEquals("LINKED_SURNAME", ldapObj.getAttr("sn").get().getValues().get(0));
109
110
111 UserUR userUR = new UserUR();
112 userUR.setKey(user.getKey());
113
114 account.getPlainAttrs().clear();
115 account.getPlainAttrs().add(attr("email", "UPDATED_EMAIL@syncope.apache.org"));
116 account.getPlainAttrs().add(attr("surname", "UPDATED_SURNAME"));
117 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
118
119 user = updateUser(userUR).getEntity();
120 assertEquals(1, user.getLinkedAccounts().size());
121
122
123 ldapObj = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), connObjectKeyValue);
124 assertNotNull(ldapObj);
125
126 assertTrue(ldapObj.getAttr("mail").get().getValues().contains("UPDATED_EMAIL@syncope.apache.org"));
127 assertEquals("UPDATED_SURNAME", ldapObj.getAttr("sn").get().getValues().get(0));
128
129
130 userUR = new UserUR();
131 userUR.setKey(user.getKey());
132 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().
133 operation(PatchOperation.DELETE).
134 linkedAccountTO(user.getLinkedAccounts().get(0)).build());
135
136 user = updateUser(userUR).getEntity();
137 assertTrue(user.getLinkedAccounts().isEmpty());
138
139
140 tasks = TASK_SERVICE.search(
141 new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
142 anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
143 assertEquals(3, tasks.getTotalCount());
144
145 Optional<PropagationTaskTO> deletTask =
146 tasks.getResult().stream().filter(task -> task.getOperation() == ResourceOperation.DELETE).findFirst();
147 assertTrue(deletTask.isPresent());
148 assertEquals(connObjectKeyValue, deletTask.get().getConnObjectKey());
149 assertEquals(ExecStatus.SUCCESS.name(), deletTask.get().getLatestExecStatus());
150
151 assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue));
152 }
153
154 @Test
155 public void createWithLinkedAccountThenUpdateUsingPutThenRemove() throws NamingException {
156
157 UserCR userCR = UserITCase.getSample(
158 "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
159 String connObjectKeyValue = "uid=" + userCR.getUsername() + ",ou=People,o=isp";
160 String privilege = APPLICATION_SERVICE.read("mightyApp").getPrivileges().get(0).getKey();
161
162 LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
163 account.setUsername("LinkedUsername");
164 account.getPlainAttrs().add(attr("surname", "LINKED_SURNAME"));
165 account.getPrivileges().add(privilege);
166 userCR.getLinkedAccounts().add(account);
167
168 UserTO user = createUser(userCR).getEntity();
169 assertNotNull(user.getKey());
170 assertEquals(1, user.getLinkedAccounts().size());
171 assertEquals(privilege, user.getLinkedAccounts().get(0).getPrivileges().iterator().next());
172 assertEquals("LinkedUsername", user.getLinkedAccounts().get(0).getUsername());
173 assertEquals("LINKED_SURNAME", account.getPlainAttr("surname").get().getValues().get(0));
174
175
176 account.getPlainAttrs().clear();
177 account.setUsername("LinkedUsernameUpdated");
178 account.getPlainAttrs().add(attr("email", "UPDATED_EMAIL@syncope.apache.org"));
179 account.getPlainAttrs().add(attr("surname", "UPDATED_SURNAME"));
180 user.getLinkedAccounts().clear();
181 user.getLinkedAccounts().add(account);
182
183 user = updateUser(user).getEntity();
184 assertEquals(1, user.getLinkedAccounts().size());
185 assertEquals("LinkedUsernameUpdated", user.getLinkedAccounts().get(0).getUsername());
186 assertEquals("UPDATED_SURNAME", account.getPlainAttr("surname").get().getValues().get(0));
187
188
189 user.getLinkedAccounts().clear();
190 user = updateUser(user).getEntity();
191 assertTrue(user.getLinkedAccounts().isEmpty());
192 }
193
194 @Test
195 public void createWithoutLinkedAccountThenAdd() throws NamingException {
196
197 UserCR userCR = UserITCase.getSample(
198 "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
199 String connObjectKeyValue = "uid=" + userCR.getUsername() + ",ou=People,o=isp";
200
201 UserTO user = createUser(userCR).getEntity();
202 assertNotNull(user.getKey());
203 assertTrue(user.getLinkedAccounts().isEmpty());
204
205 PagedResult<PropagationTaskTO> tasks = TASK_SERVICE.search(
206 new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
207 anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
208 assertEquals(0, tasks.getTotalCount());
209
210 assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue));
211
212
213 UserUR userUR = new UserUR();
214 userUR.setKey(user.getKey());
215
216 LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
217 account.getPlainAttrs().add(attr("surname", "LINKED_SURNAME"));
218 account.setPassword("Password123");
219 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
220
221 user = updateUser(userUR).getEntity();
222 assertEquals(1, user.getLinkedAccounts().size());
223
224
225 tasks = TASK_SERVICE.search(
226 new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
227 anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
228 assertEquals(1, tasks.getTotalCount());
229 assertEquals(connObjectKeyValue, tasks.getResult().get(0).getConnObjectKey());
230 assertEquals(ResourceOperation.CREATE, tasks.getResult().get(0).getOperation());
231 assertEquals(ExecStatus.SUCCESS.name(), tasks.getResult().get(0).getLatestExecStatus());
232
233 ConnObject ldapObj = RESOURCE_SERVICE.readConnObject(
234 RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), connObjectKeyValue);
235 assertNotNull(ldapObj);
236 assertEquals(user.getPlainAttr("email").get().getValues(), ldapObj.getAttr("mail").get().getValues());
237 assertEquals("LINKED_SURNAME", ldapObj.getAttr("sn").get().getValues().get(0));
238 }
239
240 @Test
241 public void createWithoutLinkedAccountThenAddAndUpdatePassword() throws NamingException {
242
243 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "return.password.value", true);
244
245
246 UserCR userCR = UserITCase.getSample(
247 "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
248 String connObjectKeyValue = "uid=" + userCR.getUsername() + ",ou=People,o=isp";
249
250 UserTO user = createUser(userCR).getEntity();
251 assertNotNull(user.getKey());
252 assertTrue(user.getLinkedAccounts().isEmpty());
253
254
255 UserUR userUR = new UserUR();
256 userUR.setKey(user.getKey());
257
258 LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
259 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
260
261 user = updateUser(userUR).getEntity();
262 assertEquals(1, user.getLinkedAccounts().size());
263 assertNull(user.getLinkedAccounts().get(0).getPassword());
264
265
266 account.setPassword("Password123");
267 userUR = new UserUR();
268 userUR.setKey(user.getKey());
269 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
270 user = updateUser(userUR).getEntity();
271 assertNotNull(user.getLinkedAccounts().get(0).getPassword());
272
273
274 String beforeUpdatePassword = user.getLinkedAccounts().get(0).getPassword();
275 account.setPassword("Password123Updated");
276 userUR = new UserUR();
277 userUR.setKey(user.getKey());
278
279 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
280 user = updateUser(userUR).getEntity();
281 assertNotNull(user.getLinkedAccounts().get(0).getPassword());
282 assertNotEquals(beforeUpdatePassword, user.getLinkedAccounts().get(0).getPassword());
283
284
285 account.setPassword(null);
286 userUR = new UserUR();
287 userUR.setKey(user.getKey());
288
289 userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
290 user = updateUser(userUR).getEntity();
291 assertNull(user.getLinkedAccounts().get(0).getPassword());
292
293 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "return.password.value", false);
294 }
295
296 @Test
297 public void push() {
298
299 String origpwdCipherAlgo = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
300 "password.cipher.algorithm", null, String.class);
301
302
303 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "AES");
304
305 String userKey = null;
306 String connObjectKeyValue = UUID.randomUUID().toString();
307 try {
308
309 UserCR userCR = UserITCase.getSample(
310 "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
311
312 LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_REST, connObjectKeyValue).build();
313 userCR.getLinkedAccounts().add(account);
314
315 UserTO user = createUser(userCR).getEntity();
316 userKey = user.getKey();
317 assertNotNull(userKey);
318 assertNotEquals(userKey, connObjectKeyValue);
319
320
321 PagedResult<PropagationTaskTO> tasks = TASK_SERVICE.search(
322 new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_REST).
323 anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
324 assertEquals(1, tasks.getTotalCount());
325 assertEquals(connObjectKeyValue, tasks.getResult().get(0).getConnObjectKey());
326 assertEquals(ResourceOperation.CREATE, tasks.getResult().get(0).getOperation());
327 assertEquals(ExecStatus.SUCCESS.name(), tasks.getResult().get(0).getLatestExecStatus());
328
329 WebClient webClient = WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + connObjectKeyValue).
330 accept(MediaType.APPLICATION_JSON_TYPE);
331 Response response = webClient.get();
332 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
333
334
335 response = webClient.delete();
336 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
337
338 response = webClient.get();
339 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
340
341
342 PushTaskTO sendUser = new PushTaskTO();
343 sendUser.setName("Send User " + user.getUsername());
344 sendUser.setResource(RESOURCE_NAME_REST);
345 sendUser.setUnmatchingRule(UnmatchingRule.PROVISION);
346 sendUser.setMatchingRule(MatchingRule.UPDATE);
347 sendUser.setSourceRealm(SyncopeConstants.ROOT_REALM);
348 sendUser.getFilters().put(AnyTypeKind.USER.name(), "username==" + user.getUsername());
349 sendUser.setPerformCreate(true);
350 sendUser.setPerformUpdate(true);
351
352 response = TASK_SERVICE.create(TaskType.PUSH, sendUser);
353 sendUser = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
354 assertNotNull(sendUser);
355
356
357 AbstractTaskITCase.execProvisioningTask(
358 TASK_SERVICE, TaskType.PUSH, sendUser.getKey(), MAX_WAIT_SECONDS, false);
359
360 TaskTO task = TASK_SERVICE.read(TaskType.PUSH, sendUser.getKey(), true);
361 assertEquals(1, task.getExecutions().size());
362 assertEquals(ExecStatus.SUCCESS.name(), task.getExecutions().get(0).getStatus());
363
364 tasks = TASK_SERVICE.search(
365 new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_REST).
366 anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
367 assertEquals(3, tasks.getTotalCount());
368
369
370 response = webClient.get();
371 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
372
373 webClient = WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + userKey).
374 accept(MediaType.APPLICATION_JSON_TYPE);
375 response = webClient.get();
376 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
377 } finally {
378
379 confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", origpwdCipherAlgo);
380
381
382 if (userKey != null) {
383 WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + connObjectKeyValue).delete();
384 WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + userKey).delete();
385
386 USER_SERVICE.delete(userKey);
387 }
388 }
389 }
390
391 @Test
392 public void pull() {
393
394
395
396 ResourceTO restResource = RESOURCE_SERVICE.read(RESOURCE_NAME_REST);
397 if (restResource.getPullPolicy() == null) {
398 ImplementationTO rule = null;
399 try {
400 rule = IMPLEMENTATION_SERVICE.read(
401 IdMImplementationType.PULL_CORRELATION_RULE, "LinkedAccountSamplePullCorrelationRule");
402 } catch (SyncopeClientException e) {
403 if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) {
404 rule = new ImplementationTO();
405 rule.setKey("LinkedAccountSamplePullCorrelationRule");
406 rule.setEngine(ImplementationEngine.JAVA);
407 rule.setType(IdMImplementationType.PULL_CORRELATION_RULE);
408 rule.setBody(POJOHelper.serialize(new LinkedAccountSamplePullCorrelationRuleConf()));
409 Response response = IMPLEMENTATION_SERVICE.create(rule);
410 rule = IMPLEMENTATION_SERVICE.read(
411 rule.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
412 assertNotNull(rule.getKey());
413 }
414 }
415 assertNotNull(rule);
416
417 PullPolicyTO policy = new PullPolicyTO();
418 policy.setName("Linked Account sample Pull policy");
419 policy.getCorrelationRules().put(AnyTypeKind.USER.name(), rule.getKey());
420 Response response = POLICY_SERVICE.create(PolicyType.PULL, policy);
421 policy = POLICY_SERVICE.read(PolicyType.PULL, response.getHeaderString(RESTHeaders.RESOURCE_KEY));
422 assertNotNull(policy.getKey());
423
424 restResource.setPullPolicy(policy.getKey());
425 RESOURCE_SERVICE.update(restResource);
426 }
427
428
429
430
431
432 String pullTaskKey;
433
434 PagedResult<PullTaskTO> tasks = TASK_SERVICE.search(
435 new TaskQuery.Builder(TaskType.PULL).resource(RESOURCE_NAME_REST).build());
436 if (tasks.getTotalCount() > 0) {
437 pullTaskKey = tasks.getResult().get(0).getKey();
438 } else {
439 PullTaskTO task = new PullTaskTO();
440 task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
441 task.setName("Linked Account Pull Task");
442 task.setActive(true);
443 task.setResource(RESOURCE_NAME_REST);
444 task.setPullMode(PullMode.INCREMENTAL);
445 task.setPerformCreate(true);
446 task.setPerformUpdate(true);
447 task.setPerformDelete(true);
448 task.setSyncStatus(true);
449
450 Response response = TASK_SERVICE.create(TaskType.PULL, task);
451 task = TASK_SERVICE.read(TaskType.PULL, response.getHeaderString(RESTHeaders.RESOURCE_KEY), false);
452 assertNotNull(task.getKey());
453 pullTaskKey = task.getKey();
454 }
455 assertNotNull(pullTaskKey);
456
457
458
459 WebClient webClient = WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users").
460 accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE);
461
462 ObjectNode user = JSON_MAPPER.createObjectNode();
463 user.put("username", "linkedaccount1");
464 user.put("password", "Password123");
465 user.put("firstName", "Pasquale");
466 user.put("surname", "Vivaldi");
467 user.put("email", "vivaldi@syncope.org");
468
469 Response response = webClient.post(user.toString());
470 assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
471 String user1Key = StringUtils.substringAfterLast(response.getHeaderString(HttpHeaders.LOCATION), "/");
472 assertNotNull(user1Key);
473
474 user = JSON_MAPPER.createObjectNode();
475 user.put("username", "vivaldi");
476 user.put("password", "Password123");
477 user.put("firstName", "Giovannino");
478 user.put("surname", "Vivaldi");
479 user.put("email", "vivaldi@syncope.org");
480
481 response = webClient.post(user.toString());
482 assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
483 String user2Key = StringUtils.substringAfterLast(response.getHeaderString(HttpHeaders.LOCATION), "/");
484 assertNotNull(user2Key);
485
486 user = JSON_MAPPER.createObjectNode();
487 user.put("username", "not.vivaldi");
488 user.put("password", "Password123");
489 user.put("email", "not.vivaldi@syncope.org");
490
491 response = webClient.post(user.toString());
492 assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
493 String user3Key = StringUtils.substringAfterLast(response.getHeaderString(HttpHeaders.LOCATION), "/");
494 assertNotNull(user3Key);
495
496
497 try {
498 List<LinkedAccountTO> accounts = USER_SERVICE.read("vivaldi").getLinkedAccounts();
499 assertTrue(accounts.isEmpty());
500
501 ExecTO exec = AbstractTaskITCase.execProvisioningTask(
502 TASK_SERVICE, TaskType.PULL, pullTaskKey, MAX_WAIT_SECONDS, false);
503 assertEquals(ExecStatus.SUCCESS, ExecStatus.valueOf(exec.getStatus()));
504 assertTrue(exec.getMessage().contains("Accounts created"));
505
506 accounts = USER_SERVICE.read("vivaldi").getLinkedAccounts();
507 assertEquals(3, accounts.size());
508
509 Optional<LinkedAccountTO> firstAccount = accounts.stream().
510 filter(account -> user1Key.equals(account.getConnObjectKeyValue())).
511 findFirst();
512 assertTrue(firstAccount.isPresent());
513 assertFalse(firstAccount.get().isSuspended());
514 assertEquals(RESOURCE_NAME_REST, firstAccount.get().getResource());
515 assertEquals("linkedaccount1", firstAccount.get().getUsername());
516 assertEquals("Pasquale", firstAccount.get().getPlainAttr("firstname").get().getValues().get(0));
517
518 Optional<LinkedAccountTO> secondAccount = accounts.stream().
519 filter(account -> user2Key.equals(account.getConnObjectKeyValue())).
520 findFirst();
521 assertTrue(secondAccount.isPresent());
522 assertFalse(secondAccount.get().isSuspended());
523 assertEquals(RESOURCE_NAME_REST, secondAccount.get().getResource());
524 assertNull(secondAccount.get().getUsername());
525 assertEquals("Giovannino", secondAccount.get().getPlainAttr("firstname").get().getValues().get(0));
526
527 Optional<LinkedAccountTO> thirdAccount = accounts.stream().
528 filter(account -> user3Key.equals(account.getConnObjectKeyValue())).
529 filter(account -> "not.vivaldi".equals(account.getUsername())).
530 findFirst();
531 assertTrue(thirdAccount.isPresent());
532 assertFalse(thirdAccount.get().isSuspended());
533 assertEquals(RESOURCE_NAME_REST, thirdAccount.get().getResource());
534 assertEquals("not.vivaldi", thirdAccount.get().getUsername());
535
536
537 response = webClient.path(user1Key).delete();
538 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
539
540 user = JSON_MAPPER.createObjectNode();
541 user.put("username", "linkedaccount2");
542 response = webClient.replacePath(user2Key).put(user.toString());
543 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
544
545 user = JSON_MAPPER.createObjectNode();
546 user.put("status", "INACTIVE");
547 response = webClient.replacePath(user3Key).put(user.toString());
548 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
549
550
551 exec = AbstractTaskITCase.execProvisioningTask(
552 TASK_SERVICE, TaskType.PULL, pullTaskKey, MAX_WAIT_SECONDS, false);
553 assertEquals(ExecStatus.SUCCESS, ExecStatus.valueOf(exec.getStatus()));
554 assertTrue(exec.getMessage().contains("Accounts updated"));
555 assertTrue(exec.getMessage().contains("Accounts deleted"));
556
557 accounts = USER_SERVICE.read("vivaldi").getLinkedAccounts();
558 assertEquals(2, accounts.size());
559
560 firstAccount = accounts.stream().
561 filter(account -> user1Key.equals(account.getConnObjectKeyValue())).
562 findFirst();
563 assertFalse(firstAccount.isPresent());
564
565 secondAccount = accounts.stream().
566 filter(account -> user2Key.equals(account.getConnObjectKeyValue())).
567 findFirst();
568 assertTrue(secondAccount.isPresent());
569 assertFalse(secondAccount.get().isSuspended());
570 assertEquals(user2Key, secondAccount.get().getConnObjectKeyValue());
571 assertEquals("linkedaccount2", secondAccount.get().getUsername());
572
573 thirdAccount = accounts.stream().
574 filter(account -> "not.vivaldi".equals(account.getUsername())).
575 findFirst();
576 assertTrue(thirdAccount.isPresent());
577 assertTrue(thirdAccount.get().isSuspended());
578 assertEquals(user3Key, thirdAccount.get().getConnObjectKeyValue());
579 } finally {
580
581 UserUR patch = new UserUR();
582 patch.setKey(LinkedAccountSamplePullCorrelationRule.VIVALDI_KEY);
583 patch.getLinkedAccounts().add(new LinkedAccountUR.Builder().
584 operation(PatchOperation.DELETE).
585 linkedAccountTO(new LinkedAccountTO.Builder(RESOURCE_NAME_REST, user2Key).build()).
586 build());
587 patch.getLinkedAccounts().add(new LinkedAccountUR.Builder().
588 operation(PatchOperation.DELETE).
589 linkedAccountTO(new LinkedAccountTO.Builder(RESOURCE_NAME_REST, user3Key).build()).
590 build());
591 USER_SERVICE.update(patch);
592
593 webClient.replacePath(user2Key).delete();
594 webClient.replacePath(user3Key).delete();
595 }
596 }
597 }