1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.outer;
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.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Set;
33 import java.util.stream.Collectors;
34 import javax.persistence.Query;
35 import org.apache.syncope.common.lib.SyncopeConstants;
36 import org.apache.syncope.common.lib.types.AnyTypeKind;
37 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
38 import org.apache.syncope.core.persistence.api.attrvalue.validation.PlainAttrValidationManager;
39 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
40 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
41 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
42 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
43 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
44 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
45 import org.apache.syncope.core.persistence.api.dao.UserDAO;
46 import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
47 import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
48 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
49 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
50 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
51 import org.apache.syncope.core.persistence.api.entity.group.Group;
52 import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
53 import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
54 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
55 import org.apache.syncope.core.persistence.api.entity.user.User;
56 import org.apache.syncope.core.persistence.jpa.AbstractTest;
57 import org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO;
58 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
59 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
60 import org.junit.jupiter.api.Test;
61 import org.springframework.beans.factory.annotation.Autowired;
62 import org.springframework.transaction.annotation.Transactional;
63
64 @Transactional("Master")
65 public class GroupTest extends AbstractTest {
66
67 @Autowired
68 private AnyTypeDAO anyTypeDAO;
69
70 @Autowired
71 private AnyObjectDAO anyObjectDAO;
72
73 @Autowired
74 private UserDAO userDAO;
75
76 @Autowired
77 private GroupDAO groupDAO;
78
79 @Autowired
80 private RealmDAO realmDAO;
81
82 @Autowired
83 private PlainSchemaDAO plainSchemaDAO;
84
85 @Autowired
86 private AnyTypeClassDAO anyTypeClassDAO;
87
88 @Autowired
89 private PlainAttrValidationManager validator;
90
91 @Test
92 public void saveWithTwoOwners() {
93 assertThrows(InvalidEntityException.class, () -> {
94 Group root = groupDAO.findByName("root");
95 assertNotNull(root);
96
97 User user = userDAO.findByUsername("rossini");
98 assertNotNull(user);
99
100 Group group = entityFactory.newEntity(Group.class);
101 group.setRealm(realmDAO.getRoot());
102 group.setName("error");
103 group.setUserOwner(user);
104 group.setGroupOwner(root);
105
106 groupDAO.save(group);
107 });
108 }
109
110 @Test
111 public void findByOwner() {
112 Group group = groupDAO.find("ebf97068-aa4b-4a85-9f01-680e8c4cf227");
113 assertNotNull(group);
114
115 User user = userDAO.find("823074dc-d280-436d-a7dd-07399fae48ec");
116 assertNotNull(user);
117
118 assertEquals(user, group.getUserOwner());
119
120 List<Group> ownedGroups = groupDAO.findOwnedByUser(user.getKey());
121 assertFalse(ownedGroups.isEmpty());
122 assertEquals(1, ownedGroups.size());
123 assertTrue(ownedGroups.contains(group));
124 }
125
126 @Test
127 public void create() {
128 Group group = entityFactory.newEntity(Group.class);
129 group.setRealm(realmDAO.getRoot());
130 group.setName("new");
131
132 TypeExtension typeExt = entityFactory.newEntity(TypeExtension.class);
133 typeExt.setAnyType(anyTypeDAO.findUser());
134 typeExt.add(anyTypeClassDAO.find("csv"));
135 typeExt.add(anyTypeClassDAO.find("other"));
136
137 group.add(typeExt);
138 typeExt.setGroup(group);
139
140 groupDAO.save(group);
141
142 entityManager().flush();
143
144 group = groupDAO.findByName("new");
145 assertNotNull(group);
146 assertEquals(1, group.getTypeExtensions().size());
147 assertEquals(2, group.getTypeExtension(anyTypeDAO.findUser()).get().getAuxClasses().size());
148 }
149
150 @Test
151 public void createWithInternationalCharacters() {
152 Group group = entityFactory.newEntity(Group.class);
153 group.setName("räksmörgås");
154 group.setRealm(realmDAO.findByFullPath(SyncopeConstants.ROOT_REALM));
155
156 groupDAO.save(group);
157 entityManager().flush();
158 }
159
160 @Test
161 public void delete() {
162 Collection<Group> groups = userDAO.findAllGroups(userDAO.findByUsername("verdi"));
163 assertTrue(groups.stream().anyMatch(g -> "b1f7c12d-ec83-441f-a50e-1691daaedf3b".equals(g.getKey())));
164 int before = userDAO.findAllGroups(userDAO.findByUsername("verdi")).size();
165
166 groupDAO.delete("b1f7c12d-ec83-441f-a50e-1691daaedf3b");
167
168 entityManager().flush();
169
170 assertNull(groupDAO.find("b1f7c12d-ec83-441f-a50e-1691daaedf3b"));
171 assertEquals(before - 1, userDAO.findAllGroups(userDAO.findByUsername("verdi")).size());
172 assertNull(findPlainAttr("f82fc61f-8e74-4a4b-9f9e-b8a41f38aad9", GPlainAttr.class));
173 assertNull(findPlainAttrValue("49f35879-2510-4f11-a901-24152f753538", GPlainAttrValue.class));
174 assertNotNull(plainSchemaDAO.find("icon"));
175 }
176
177
178
179
180
181
182 @SuppressWarnings("unchecked")
183 public List<Group> findDynGroups(final User user) {
184 Query query = entityManager().createNativeQuery(
185 "SELECT group_id FROM " + JPAGroupDAO.UDYNMEMB_TABLE + " WHERE any_id=?");
186 query.setParameter(1, user.getKey());
187
188 List<Group> result = new ArrayList<>();
189 query.getResultList().stream().map(resultKey -> resultKey instanceof Object[]
190 ? (String) ((Object[]) resultKey)[0]
191 : ((String) resultKey)).
192 forEach(actualKey -> {
193 Group group = groupDAO.find(actualKey.toString());
194 if (group != null && !result.contains(group)) {
195 result.add(group);
196 }
197 });
198 return result;
199 }
200
201 @Test
202 public void udynMembership() {
203
204 User user = entityFactory.newEntity(User.class);
205 user.setUsername("username");
206 user.setRealm(realmDAO.findByFullPath("/even/two"));
207 user.add(anyTypeClassDAO.find("other"));
208
209 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
210 attr.setOwner(user);
211 attr.setSchema(plainSchemaDAO.find("cool"));
212 attr.add(validator, "true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
213 user.add(attr);
214
215 user = userDAO.save(user);
216 String newUserKey = user.getKey();
217 assertNotNull(newUserKey);
218
219
220 Group group = entityFactory.newEntity(Group.class);
221 group.setRealm(realmDAO.getRoot());
222 group.setName("new");
223
224 UDynGroupMembership dynMembership = entityFactory.newEntity(UDynGroupMembership.class);
225 dynMembership.setFIQLCond("cool==true");
226 dynMembership.setGroup(group);
227
228 group.setUDynMembership(dynMembership);
229
230 Group actual = groupDAO.saveAndRefreshDynMemberships(group);
231 assertNotNull(actual);
232
233 entityManager().flush();
234
235
236 actual = groupDAO.find(actual.getKey());
237 assertNotNull(actual);
238 assertNotNull(actual.getUDynMembership());
239 assertNotNull(actual.getUDynMembership().getKey());
240 assertEquals(actual, actual.getUDynMembership().getGroup());
241
242
243 List<String> members = groupDAO.findUDynMembers(actual);
244 assertEquals(2, members.size());
245 assertEquals(Set.of("c9b2dec2-00a7-4855-97c0-d854842b4b24", newUserKey), new HashSet<>(members));
246
247 user = userDAO.findByUsername("bellini");
248 assertNotNull(user);
249 Collection<Group> dynGroupMemberships = findDynGroups(user);
250 assertEquals(1, dynGroupMemberships.size());
251 assertTrue(dynGroupMemberships.contains(actual.getUDynMembership().getGroup()));
252
253
254 userDAO.delete(newUserKey);
255
256 entityManager().flush();
257
258 actual = groupDAO.find(actual.getKey());
259 members = groupDAO.findUDynMembers(actual);
260 assertEquals(1, members.size());
261 assertEquals("c9b2dec2-00a7-4855-97c0-d854842b4b24", members.get(0));
262
263
264 String dynMembershipKey = actual.getUDynMembership().getKey();
265
266 groupDAO.delete(actual);
267
268 entityManager().flush();
269
270 assertNull(entityManager().find(JPAUDynGroupMembership.class, dynMembershipKey));
271
272 dynGroupMemberships = findDynGroups(user);
273 assertTrue(dynGroupMemberships.isEmpty());
274 }
275
276
277
278
279
280
281 @SuppressWarnings("unchecked")
282 public List<Group> findDynGroups(final AnyObject anyObject) {
283 Query query = entityManager().createNativeQuery(
284 "SELECT group_id FROM " + JPAGroupDAO.ADYNMEMB_TABLE + " WHERE any_id=?");
285 query.setParameter(1, anyObject.getKey());
286
287 List<Group> result = new ArrayList<>();
288 query.getResultList().stream().map(resultKey -> resultKey instanceof Object[]
289 ? (String) ((Object[]) resultKey)[0]
290 : ((String) resultKey)).
291 forEach(actualKey -> {
292 Group group = groupDAO.find(actualKey.toString());
293 if (group != null && !result.contains(group)) {
294 result.add(group);
295 }
296 });
297 return result;
298 }
299
300 @Test
301 public void adynMembership() {
302
303 AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
304 anyObject.setName("name");
305 anyObject.setType(anyTypeDAO.find("PRINTER"));
306 anyObject.setRealm(realmDAO.findByFullPath("/even/two"));
307
308 APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
309 attr.setOwner(anyObject);
310 attr.setSchema(plainSchemaDAO.find("model"));
311 attr.add(validator, "Canon MFC8030", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
312 anyObject.add(attr);
313
314 anyObject = anyObjectDAO.save(anyObject);
315 String newAnyObjectKey = anyObject.getKey();
316 assertNotNull(newAnyObjectKey);
317
318
319 Group group = entityFactory.newEntity(Group.class);
320 group.setRealm(realmDAO.getRoot());
321 group.setName("new");
322
323 ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
324 dynMembership.setAnyType(anyTypeDAO.find("PRINTER"));
325 dynMembership.setFIQLCond("model==Canon MFC8030");
326 dynMembership.setGroup(group);
327
328 group.add(dynMembership);
329
330 Group actual = groupDAO.saveAndRefreshDynMemberships(group);
331 assertNotNull(actual);
332
333 entityManager().flush();
334
335
336 actual = groupDAO.find(actual.getKey());
337 assertNotNull(actual);
338 assertNotNull(actual.getADynMembership(anyTypeDAO.find("PRINTER")).get());
339 assertNotNull(actual.getADynMembership(anyTypeDAO.find("PRINTER")).get().getKey());
340 assertEquals(actual, actual.getADynMembership(anyTypeDAO.find("PRINTER")).get().getGroup());
341
342
343 List<String> members = groupDAO.findADynMembers(actual).stream().filter(object
344 -> "PRINTER".equals(anyObjectDAO.find(object).getType().getKey())).collect(Collectors.toList());
345 assertEquals(2, members.size());
346 assertEquals(
347 Set.of("fc6dbc3a-6c07-4965-8781-921e7401a4a5", newAnyObjectKey),
348 new HashSet<>(members));
349
350 anyObject = anyObjectDAO.find("fc6dbc3a-6c07-4965-8781-921e7401a4a5");
351 assertNotNull(anyObject);
352 Collection<Group> dynGroupMemberships = findDynGroups(anyObject);
353 assertEquals(1, dynGroupMemberships.size());
354 assertTrue(dynGroupMemberships.contains(actual.getADynMembership(anyTypeDAO.find("PRINTER")).get().getGroup()));
355
356
357 anyObjectDAO.delete(newAnyObjectKey);
358
359 entityManager().flush();
360
361 actual = groupDAO.find(actual.getKey());
362 members = groupDAO.findADynMembers(actual).stream().filter(object
363 -> "PRINTER".equals(anyObjectDAO.find(object).getType().getKey())).collect(Collectors.toList());
364 assertEquals(1, members.size());
365 assertEquals("fc6dbc3a-6c07-4965-8781-921e7401a4a5", members.get(0));
366
367
368 String dynMembershipKey = actual.getADynMembership(anyTypeDAO.find("PRINTER")).get().getKey();
369
370 groupDAO.delete(actual);
371
372 entityManager().flush();
373
374 assertNull(entityManager().find(JPAADynGroupMembership.class, dynMembershipKey));
375
376 dynGroupMemberships = findDynGroups(anyObject);
377 assertTrue(dynGroupMemberships.isEmpty());
378 }
379
380 @Test
381 public void issueSYNCOPE1512() {
382 Group group = groupDAO.findByName("root");
383 assertNotNull(group);
384
385
386 GPlainAttr title = entityFactory.newEntity(GPlainAttr.class);
387 title.setOwner(group);
388 title.setSchema(plainSchemaDAO.find("title"));
389 title.add(validator, "syncope's group", anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
390 group.add(title);
391
392
393 GPlainAttr originalName = entityFactory.newEntity(GPlainAttr.class);
394 originalName.setOwner(group);
395 originalName.setSchema(plainSchemaDAO.find("originalName"));
396 originalName.add(validator, "syncope's group", anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
397 group.add(originalName);
398
399 groupDAO.save(group);
400
401 entityManager().flush();
402
403 group = groupDAO.find(group.getKey());
404 assertEquals("syncope's group", group.getPlainAttr("title").get().getValuesAsStrings().get(0));
405 assertEquals("syncope's group", group.getPlainAttr("originalName").get().getValuesAsStrings().get(0));
406 }
407 }