1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.fit.console;
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.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.fail;
25
26 import javax.ws.rs.core.GenericType;
27 import javax.ws.rs.core.Response;
28 import org.apache.commons.lang3.RandomStringUtils;
29 import org.apache.syncope.client.console.SyncopeConsoleSession;
30 import org.apache.syncope.client.console.panels.search.SearchClause;
31 import org.apache.syncope.client.ui.commons.Constants;
32 import org.apache.syncope.common.lib.Attr;
33 import org.apache.syncope.common.lib.SyncopeClientException;
34 import org.apache.syncope.common.lib.request.UserCR;
35 import org.apache.syncope.common.lib.to.LinkedAccountTO;
36 import org.apache.syncope.common.lib.to.ProvisioningResult;
37 import org.apache.syncope.common.lib.to.UserTO;
38 import org.apache.syncope.common.lib.types.ClientExceptionType;
39 import org.apache.syncope.common.rest.api.service.UserService;
40 import org.apache.syncope.fit.core.UserITCase;
41 import org.apache.wicket.Component;
42 import org.apache.wicket.markup.html.form.DropDownChoice;
43 import org.apache.wicket.util.tester.FormTester;
44 import org.junit.jupiter.api.AfterEach;
45 import org.junit.jupiter.api.BeforeEach;
46 import org.junit.jupiter.api.Test;
47
48 public class LinkedAccountsITCase extends AbstractConsoleITCase {
49
50 private static final String TAB_PANEL = "body:content:body:container:content:tabbedPanel:panel:searchResult:";
51
52 private static final String RESULT_DATA_TABLE =
53 "searchResult:container:content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable:";
54
55 private static final String RESOURCES_DATA_TABLE =
56 "view:resources:container:content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable:";
57
58 private static final String SELECT_USER_ACTION = "searchResult:outerObjectsRepeater:1:outer:container:content:"
59 + "togglePanelContainer:container:actions:actions:actionRepeater:0:action:action";
60
61 private static final String SELECT_RESOURCE_ACTION =
62 "view:resources:outerObjectsRepeater:1:outer:container:content:"
63 + "togglePanelContainer:container:actions:actions:actionRepeater:0:action:action";
64
65 private static final String PARENT_FORM = "outerObjectsRepeater:2:outer:form:";
66
67 private static final String FORM = PARENT_FORM + "content:form:";
68
69 private static final String SEARCH_PANEL = FORM + "view:ownerContainer:search:";
70
71 private static final String USER_SEARCH_PANEL = SEARCH_PANEL + "usersearch:";
72
73 private static final String USER_SEARCH_FORM = TAB_PANEL + USER_SEARCH_PANEL
74 + "searchFormContainer:search:multiValueContainer:innerForm:";
75
76 private static final String CONTAINER = TAB_PANEL + "container:content:";
77
78 private static UserTO USER;
79
80 @BeforeEach
81 public void login() {
82 doLogin(ADMIN_UNAME, ADMIN_PWD);
83
84
85 String email = "linkedAccount" + RandomStringUtils.randomNumeric(4) + "@syncope.apache.org";
86 UserCR userCR = UserITCase.getSample(email);
87 String connObjectKeyValue = "uid=" + userCR.getUsername() + ",ou=People,o=isp";
88
89 LinkedAccountTO account = new LinkedAccountTO.Builder("resource-ldap", connObjectKeyValue).build();
90 account.getPlainAttrs().add(new Attr.Builder("surname").value("LINKED_SURNAME").build());
91 userCR.getLinkedAccounts().add(account);
92
93 UserService userService = SyncopeConsoleSession.get().getService(UserService.class);
94 Response response = userService.create(userCR);
95 USER = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
96 }).getEntity();
97 assertNotNull(USER.getKey());
98 assertEquals(account.getConnObjectKeyValue(), USER.getLinkedAccounts().get(0).getConnObjectKeyValue());
99 }
100
101 @AfterEach
102 public void cleanUp() {
103 try {
104 SyncopeConsoleSession.get().getService(UserService.class).delete(USER.getKey());
105 } catch (SyncopeClientException e) {
106 if (e.getType() != ClientExceptionType.NotFound) {
107 throw e;
108 }
109 }
110 }
111
112 @Test
113 public void createLinkedAccountAndMergeWithUser() {
114
115 TESTER.clickLink("body:realmsLI:realms", false);
116 TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");
117
118 Component verdiUserComponent = findComponentByProp("username", CONTAINER
119 + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "verdi");
120 assertNotNull(verdiUserComponent);
121 TESTER.executeAjaxEvent(verdiUserComponent.getPageRelativePath(), Constants.ON_CLICK);
122
123
124 TESTER.clickLink(TAB_PANEL + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
125 + "actions:actions:actionRepeater:6:action:action");
126
127 TESTER.executeAjaxEvent(USER_SEARCH_FORM + "content:panelPlus:add", Constants.ON_CLICK);
128 FormTester formTester = TESTER.newFormTester(USER_SEARCH_FORM);
129
130 DropDownChoice<?> type = (DropDownChoice<?>) TESTER.getComponentFromLastRenderedPage(USER_SEARCH_FORM
131 + "content:view:0:panel:container:type:dropDownChoiceField");
132 TESTER.executeAjaxEvent(USER_SEARCH_FORM + "content:view:0:panel:container:type:dropDownChoiceField",
133 Constants.ON_CHANGE);
134 type.setModelValue(new String[] { "ATTRIBUTE" });
135 type.setDefaultModelObject(SearchClause.Type.ATTRIBUTE);
136
137 formTester.setValue("content:view:0:panel:container:property:textField", "username");
138 TESTER.executeAjaxEvent(formTester.getForm().
139 get("content:view:0:panel:container:property:textField"), Constants.ON_KEYDOWN);
140 formTester.setValue("content:view:0:panel:container:value:textField", USER.getUsername());
141 TESTER.executeAjaxEvent(formTester.getForm().
142 get("content:view:0:panel:container:value:textField"), Constants.ON_KEYDOWN);
143
144 TESTER.cleanupFeedbackMessages();
145 Component searchButton = formTester.getForm().
146 get("content:view:0:panel:container:operatorContainer:operator:search");
147 TESTER.clickLink(searchButton);
148 TESTER.executeAjaxEvent(searchButton.getPageRelativePath(), Constants.ON_CLICK);
149 TESTER.assertNoErrorMessage();
150
151
152 Component comp = findComponentByProp("username", TAB_PANEL + SEARCH_PANEL + RESULT_DATA_TABLE, USER.
153 getUsername());
154 TESTER.executeAjaxEvent(comp.getPageRelativePath(), Constants.ON_CLICK);
155
156
157 TESTER.clickLink(TAB_PANEL + SEARCH_PANEL + SELECT_USER_ACTION);
158
159
160 TESTER.getComponentFromLastRenderedPage(TAB_PANEL + FORM + "view").setEnabled(false);
161 formTester = TESTER.newFormTester(TAB_PANEL + FORM);
162 formTester.submit("buttons:next");
163
164
165 comp = findComponentByProp("key", TAB_PANEL + FORM + RESOURCES_DATA_TABLE + "body:rows", "resource-ldap");
166 assertNotNull(comp);
167 TESTER.executeAjaxEvent(comp.getPageRelativePath(), Constants.ON_CLICK);
168 TESTER.clickLink(TAB_PANEL + FORM + SELECT_RESOURCE_ACTION);
169
170
171 TESTER.getComponentFromLastRenderedPage(TAB_PANEL + FORM + "view").setEnabled(false);
172 formTester = TESTER.newFormTester(TAB_PANEL + FORM);
173 formTester.submit("buttons:next");
174
175
176 TESTER.getComponentFromLastRenderedPage(TAB_PANEL + FORM + "view").setEnabled(false);
177 formTester = TESTER.newFormTester(TAB_PANEL + FORM);
178 formTester.submit("buttons:finish");
179
180 UserService userService = SyncopeConsoleSession.get().getService(UserService.class);
181
182
183 try {
184 userService.read(USER.getKey());
185 fail("User must have been deleted; expect an exception here");
186 } catch (SyncopeClientException e) {
187 assertEquals(ClientExceptionType.NotFound, e.getType());
188 }
189
190 UserTO verdi = userService.read("verdi");
191 assertFalse(verdi.getLinkedAccounts().isEmpty());
192 }
193 }