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.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.junit.jupiter.api.Assertions.fail;
26
27 import com.fasterxml.jackson.core.JsonProcessingException;
28 import javax.ws.rs.core.Response;
29 import org.apache.syncope.client.lib.SyncopeClient;
30 import org.apache.syncope.common.lib.Attr;
31 import org.apache.syncope.common.lib.SyncopeClientException;
32 import org.apache.syncope.common.lib.request.AnyObjectCR;
33 import org.apache.syncope.common.lib.request.AnyObjectUR;
34 import org.apache.syncope.common.lib.request.AttrPatch;
35 import org.apache.syncope.common.lib.request.GroupCR;
36 import org.apache.syncope.common.lib.request.MembershipUR;
37 import org.apache.syncope.common.lib.request.ResourceDR;
38 import org.apache.syncope.common.lib.request.UserCR;
39 import org.apache.syncope.common.lib.request.UserUR;
40 import org.apache.syncope.common.lib.to.AnyObjectTO;
41 import org.apache.syncope.common.lib.to.ExecTO;
42 import org.apache.syncope.common.lib.to.GroupTO;
43 import org.apache.syncope.common.lib.to.Item;
44 import org.apache.syncope.common.lib.to.MembershipTO;
45 import org.apache.syncope.common.lib.to.PagedResult;
46 import org.apache.syncope.common.lib.to.PullTaskTO;
47 import org.apache.syncope.common.lib.to.ResourceTO;
48 import org.apache.syncope.common.lib.to.TypeExtensionTO;
49 import org.apache.syncope.common.lib.to.UserTO;
50 import org.apache.syncope.common.lib.types.AnyTypeKind;
51 import org.apache.syncope.common.lib.types.ClientExceptionType;
52 import org.apache.syncope.common.lib.types.ExecStatus;
53 import org.apache.syncope.common.lib.types.MappingPurpose;
54 import org.apache.syncope.common.lib.types.PatchOperation;
55 import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
56 import org.apache.syncope.common.lib.types.TaskType;
57 import org.apache.syncope.common.rest.api.beans.AnyQuery;
58 import org.apache.syncope.common.rest.api.service.TaskService;
59 import org.apache.syncope.fit.AbstractITCase;
60 import org.junit.jupiter.api.Test;
61 import org.springframework.jdbc.core.JdbcTemplate;
62
63 public class MembershipITCase extends AbstractITCase {
64
65 @Test
66 public void misc() throws JsonProcessingException {
67 UserCR userCR = UserITCase.getUniqueSample("memb@apache.org");
68 userCR.setRealm("/even/two");
69 userCR.getPlainAttrs().add(new Attr.Builder("aLong").value("1976").build());
70 userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
71
72
73
74 MembershipTO membership = new MembershipTO.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build();
75 membership.getPlainAttrs().add(new Attr.Builder("aLong").value("1977").build());
76
77
78 membership.getPlainAttrs().add(new Attr.Builder("fullname").value("discarded").build());
79
80 userCR.getMemberships().add(membership);
81
82
83 try {
84 createUser(userCR);
85 fail("This should not happen");
86 } catch (SyncopeClientException e) {
87 assertEquals(ClientExceptionType.InvalidEntity, e.getType());
88 assertTrue(e.getMessage().contains("InvalidPlainAttr: fullname not allowed for membership of group"));
89 }
90
91
92 membership.getPlainAttrs().remove(membership.getPlainAttr("fullname").get());
93 UserTO userTO = null;
94 try {
95 userTO = createUser(userCR).getEntity();
96
97
98 assertEquals(1, userTO.getPlainAttr("aLong").get().getValues().size());
99 assertEquals("1976", userTO.getPlainAttr("aLong").get().getValues().get(0));
100
101
102 assertEquals(1, userCR.getMemberships().size());
103 membership = userTO.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").get();
104 assertNotNull(membership);
105 assertEquals(1, membership.getPlainAttr("aLong").get().getValues().size());
106 assertEquals("1977", membership.getPlainAttr("aLong").get().getValues().get(0));
107
108
109 assertFalse(membership.getDerAttr("csvuserid").get().getValues().isEmpty());
110 assertFalse(membership.getDerAttr("noschema").get().getValues().isEmpty());
111
112
113 UserUR userUR = new UserUR();
114 userUR.setKey(userTO.getKey());
115
116 userUR.getPlainAttrs().
117 add(new AttrPatch.Builder(new Attr.Builder("aLong").value("1977").build()).build());
118
119 MembershipUR membershipPatch = new MembershipUR.Builder(membership.getGroupKey()).build();
120 membershipPatch.getPlainAttrs().add(new Attr.Builder("aLong").value("1976").build());
121 membershipPatch.getPlainAttrs().add(new Attr.Builder("ctype").value("membership type").build());
122 userUR.getMemberships().add(membershipPatch);
123
124 userTO = updateUser(userUR).getEntity();
125
126
127 assertEquals(1, userTO.getPlainAttr("aLong").get().getValues().size());
128 assertEquals("1977", userTO.getPlainAttr("aLong").get().getValues().get(0));
129 assertFalse(userTO.getPlainAttr("ctype").isPresent());
130
131
132 assertEquals(1, userCR.getMemberships().size());
133 membership = userTO.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").get();
134 assertNotNull(membership);
135 assertEquals(1, membership.getPlainAttr("aLong").get().getValues().size());
136 assertEquals("1976", membership.getPlainAttr("aLong").get().getValues().get(0));
137
138
139 assertEquals("membership type", membership.getPlainAttr("ctype").get().getValues().get(0));
140
141
142 userUR = new UserUR();
143 userUR.setKey(userTO.getKey());
144
145 membershipPatch = new MembershipUR.Builder(membership.getGroupKey()).
146 operation(PatchOperation.DELETE).build();
147 userUR.getMemberships().add(membershipPatch);
148
149 userTO = updateUser(userUR).getEntity();
150
151 assertTrue(userTO.getMemberships().isEmpty());
152 } finally {
153 if (userTO != null) {
154 USER_SERVICE.delete(userTO.getKey());
155 }
156 }
157 }
158
159 @Test
160 public void deleteUserWithMembership() {
161 UserCR userCR = UserITCase.getUniqueSample("memb@apache.org");
162 userCR.setRealm("/even/two");
163 userCR.getPlainAttrs().add(new Attr.Builder("aLong").value("1976").build());
164
165 MembershipTO membership = new MembershipTO.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build();
166 membership.getPlainAttrs().add(new Attr.Builder("aLong").value("1977").build());
167 userCR.getMemberships().add(membership);
168
169 UserTO user = createUser(userCR).getEntity();
170 assertNotNull(user.getKey());
171
172 USER_SERVICE.delete(user.getKey());
173 }
174
175 @Test
176 public void onGroupDelete() {
177
178 TypeExtensionTO typeExtension = new TypeExtensionTO();
179 typeExtension.setAnyType(AnyTypeKind.USER.name());
180 typeExtension.getAuxClasses().add("csv");
181 typeExtension.getAuxClasses().add("other");
182
183 GroupCR groupCR = GroupITCase.getBasicSample("typeExt");
184 groupCR.getTypeExtensions().add(typeExtension);
185 GroupTO groupTO = createGroup(groupCR).getEntity();
186 assertNotNull(groupTO);
187
188
189 UserCR userCR = UserITCase.getUniqueSample("typeExt@apache.org");
190
191 MembershipTO membership = new MembershipTO.Builder(groupTO.getKey()).build();
192 membership.getPlainAttrs().add(new Attr.Builder("aLong").value("1454").build());
193 userCR.getMemberships().add(membership);
194
195 UserTO user = createUser(userCR).getEntity();
196
197
198 assertEquals(1, user.getMemberships().size());
199 membership = user.getMembership(groupTO.getKey()).get();
200 assertNotNull(membership);
201 assertEquals(1, membership.getPlainAttr("aLong").get().getValues().size());
202 assertEquals("1454", membership.getPlainAttr("aLong").get().getValues().get(0));
203
204
205 assertFalse(membership.getDerAttr("csvuserid").get().getValues().isEmpty());
206 assertFalse(membership.getDerAttr("noschema").get().getValues().isEmpty());
207
208
209 GROUP_SERVICE.delete(groupTO.getKey());
210
211
212 user = USER_SERVICE.read(user.getKey());
213 assertTrue(user.getMemberships().isEmpty());
214 }
215
216 @Test
217 public void pull() {
218
219 ResourceTO newResource = RESOURCE_SERVICE.read(RESOURCE_NAME_DBPULL);
220 newResource.setKey(getUUIDString());
221
222 Item item = newResource.getProvision("USER").get().getMapping().getItems().stream().
223 filter(object -> "firstname".equals(object.getIntAttrName())).findFirst().get();
224 assertNotNull(item);
225 assertEquals("ID", item.getExtAttrName());
226 item.setIntAttrName("memberships[additional].aLong");
227 item.setPurpose(MappingPurpose.BOTH);
228
229 item = newResource.getProvision("USER").get().getMapping().getItems().stream().
230 filter(object -> "fullname".equals(object.getIntAttrName())).findFirst().get();
231 item.setPurpose(MappingPurpose.PULL);
232
233 PullTaskTO newTask = null;
234 try {
235 newResource = createResource(newResource);
236 assertNotNull(newResource);
237
238
239 UserCR userCR = UserITCase.getUniqueSample("memb@apache.org");
240 userCR.setRealm("/even/two");
241 UserTO user;
242 userCR.getPlainAttrs().removeIf(attr -> "ctype".equals(attr.getSchema()));
243 userCR.getResources().clear();
244 userCR.getResources().add(newResource.getKey());
245
246 MembershipTO membership = new MembershipTO.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build();
247 membership.getPlainAttrs().add(new Attr.Builder("aLong").value("5432").build());
248 userCR.getMemberships().add(membership);
249
250 user = createUser(userCR).getEntity();
251 assertNotNull(user);
252
253
254 JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
255 String idOnResource = queryForObject(
256 jdbcTemplate, MAX_WAIT_SECONDS, "SELECT id FROM testpull WHERE id=?", String.class, "5432");
257 assertEquals("5432", idOnResource);
258
259
260 ResourceDR req = new ResourceDR();
261 req.setKey(user.getKey());
262 req.setAction(ResourceDeassociationAction.UNLINK);
263 req.getResources().add(newResource.getKey());
264 assertNotNull(parseBatchResponse(USER_SERVICE.deassociate(req)));
265
266 USER_SERVICE.delete(user.getKey());
267
268
269 newTask = TASK_SERVICE.read(TaskType.PULL, "7c2242f4-14af-4ab5-af31-cdae23783655", true);
270 newTask.setName(getUUIDString());
271 newTask.setResource(newResource.getKey());
272 newTask.setDestinationRealm("/even/two");
273
274 Response response = TASK_SERVICE.create(TaskType.PULL, newTask);
275 newTask = getObject(response.getLocation(), TaskService.class, PullTaskTO.class);
276 assertNotNull(newTask);
277
278 ExecTO execution = AbstractTaskITCase.execProvisioningTask(
279 TASK_SERVICE, TaskType.PULL, newTask.getKey(), MAX_WAIT_SECONDS, false);
280 assertEquals(ExecStatus.SUCCESS, ExecStatus.valueOf(execution.getStatus()));
281
282
283 if (IS_EXT_SEARCH_ENABLED) {
284 try {
285 Thread.sleep(2000);
286 } catch (InterruptedException ex) {
287
288 }
289 }
290 PagedResult<UserTO> users = USER_SERVICE.search(new AnyQuery.Builder().
291 realm("/").
292 fiql(SyncopeClient.getUserSearchConditionBuilder().
293 is("username").equalTo(user.getUsername()).query()).build());
294 assertEquals(1, users.getTotalCount());
295 assertEquals(1, users.getResult().get(0).getMemberships().size());
296 assertEquals("5432", users.getResult().get(0).getMemberships().get(0).
297 getPlainAttr("aLong").get().getValues().get(0));
298 } catch (Exception e) {
299 LOG.error("Unexpected error", e);
300 fail(e::getMessage);
301 } finally {
302 if (newTask != null && !"83f7e85d-9774-43fe-adba-ccd856312994".equals(newTask.getKey())) {
303 TASK_SERVICE.delete(TaskType.PULL, newTask.getKey());
304 }
305 RESOURCE_SERVICE.delete(newResource.getKey());
306 }
307 }
308
309 @Test
310 public void createDoubleMembership() {
311 AnyObjectCR anyObjectCR = AnyObjectITCase.getSample("createDoubleMembership");
312 anyObjectCR.setRealm("/even/two");
313 anyObjectCR.getMemberships().add(new MembershipTO.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build());
314 anyObjectCR.getMemberships().add(new MembershipTO.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build());
315
316 try {
317 createAnyObject(anyObjectCR);
318 fail("This should not happen");
319 } catch (SyncopeClientException e) {
320 assertEquals(ClientExceptionType.InvalidMembership, e.getType());
321 }
322 }
323
324 @Test
325 public void updateDoubleMembership() {
326 AnyObjectCR anyObjecCR = AnyObjectITCase.getSample("update");
327 anyObjecCR.setRealm("/even/two");
328 AnyObjectTO anyObjecTO = createAnyObject(anyObjecCR).getEntity();
329 assertNotNull(anyObjecTO.getKey());
330
331 AnyObjectUR req = new AnyObjectUR();
332 req.setKey(anyObjecTO.getKey());
333 req.getMemberships().add(new MembershipUR.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build());
334 MembershipUR mp = new MembershipUR.Builder("034740a9-fa10-453b-af37-dc7897e98fb1").build();
335 mp.getPlainAttrs().add(attr("any", "useless"));
336 req.getMemberships().add(mp);
337
338 try {
339 updateAnyObject(req).getEntity();
340 fail("This should not happen");
341 } catch (SyncopeClientException e) {
342 assertEquals(ClientExceptionType.InvalidMembership, e.getType());
343 }
344 }
345 }