View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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.assertTrue;
25  import static org.junit.jupiter.api.Assertions.fail;
26  
27  import java.util.List;
28  import org.apache.syncope.common.lib.types.AnyTypeKind;
29  import org.apache.syncope.core.persistence.api.attrvalue.validation.PlainAttrValidationManager;
30  import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO;
31  import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
32  import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
33  import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
34  import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
35  import org.apache.syncope.core.persistence.api.dao.UserDAO;
36  import org.apache.syncope.core.persistence.api.dao.search.DynRealmCond;
37  import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
38  import org.apache.syncope.core.persistence.api.entity.DynRealm;
39  import org.apache.syncope.core.persistence.api.entity.DynRealmMembership;
40  import org.apache.syncope.core.persistence.api.entity.user.User;
41  import org.apache.syncope.core.persistence.jpa.AbstractTest;
42  import org.junit.jupiter.api.Test;
43  import org.springframework.beans.factory.annotation.Autowired;
44  import org.springframework.transaction.annotation.Transactional;
45  
46  @Transactional("Master")
47  public class DynRealmTest extends AbstractTest {
48  
49      @Autowired
50      private AnyMatchDAO anyMatcher;
51  
52      @Autowired
53      private AnyTypeDAO anyTypeDAO;
54  
55      @Autowired
56      private DynRealmDAO dynRealmDAO;
57  
58      @Autowired
59      private AnySearchDAO searchDAO;
60  
61      @Autowired
62      private UserDAO userDAO;
63  
64      @Autowired
65      private PlainSchemaDAO plainSchemaDAO;
66  
67      @Autowired
68      private PlainAttrValidationManager plainAttrValidationManager;
69  
70      @Test
71      public void misc() {
72          DynRealm dynRealm = entityFactory.newEntity(DynRealm.class);
73          dynRealm.setKey("/name");
74  
75          DynRealmMembership memb = entityFactory.newEntity(DynRealmMembership.class);
76          memb.setDynRealm(dynRealm);
77          memb.setAnyType(anyTypeDAO.findUser());
78          memb.setFIQLCond("cool==true");
79  
80          dynRealm.add(memb);
81          memb.setDynRealm(dynRealm);
82  
83          // invalid key (starts with /)
84          try {
85              dynRealmDAO.save(dynRealm);
86              fail("This should not happen");
87          } catch (Exception e) {
88              assertNotNull(e);
89          }
90  
91          dynRealm.setKey("name");
92          DynRealm actual = dynRealmDAO.saveAndRefreshDynMemberships(dynRealm);
93          assertNotNull(actual);
94  
95          entityManager().flush();
96  
97          DynRealmCond dynRealmCond = new DynRealmCond();
98          dynRealmCond.setDynRealm(actual.getKey());
99          List<User> matching = searchDAO.search(SearchCond.getLeaf(dynRealmCond), AnyTypeKind.USER);
100         assertNotNull(matching);
101         assertFalse(matching.isEmpty());
102 
103         User user = matching.get(0);
104         assertTrue(anyMatcher.matches(user, SearchCond.getLeaf(dynRealmCond)));
105 
106         assertTrue(userDAO.findDynRealms(user.getKey()).contains(actual.getKey()));
107     }
108 
109     @Test
110     public void issueSYNCOPE1806() {
111         // 1. create two dyn realms with same condition
112         DynRealm realm1 = entityFactory.newEntity(DynRealm.class);
113         realm1.setKey("realm1");
114 
115         DynRealmMembership memb1 = entityFactory.newEntity(DynRealmMembership.class);
116         memb1.setDynRealm(realm1);
117         memb1.setAnyType(anyTypeDAO.findUser());
118         memb1.setFIQLCond("cool==true");
119 
120         realm1.add(memb1);
121         memb1.setDynRealm(realm1);
122 
123         realm1 = dynRealmDAO.saveAndRefreshDynMemberships(realm1);
124 
125         DynRealm realm2 = entityFactory.newEntity(DynRealm.class);
126         realm2.setKey("realm2");
127 
128         DynRealmMembership memb2 = entityFactory.newEntity(DynRealmMembership.class);
129         memb2.setDynRealm(realm2);
130         memb2.setAnyType(anyTypeDAO.findUser());
131         memb2.setFIQLCond("cool==true");
132 
133         realm2.add(memb2);
134         memb2.setDynRealm(realm2);
135 
136         realm2 = dynRealmDAO.saveAndRefreshDynMemberships(realm2);
137 
138         entityManager().flush();
139 
140         // 2. verify that dynamic members are the same
141         DynRealmCond dynRealmCond1 = new DynRealmCond();
142         dynRealmCond1.setDynRealm(realm1.getKey());
143         List<User> matching1 = searchDAO.search(SearchCond.getLeaf(dynRealmCond1), AnyTypeKind.USER);
144 
145         DynRealmCond dynRealmCond2 = new DynRealmCond();
146         dynRealmCond2.setDynRealm(realm2.getKey());
147         List<User> matching2 = searchDAO.search(SearchCond.getLeaf(dynRealmCond2), AnyTypeKind.USER);
148 
149         assertEquals(matching1, matching2);
150         assertEquals(1, matching1.size());
151         assertTrue(matching1.stream().anyMatch(u -> "c9b2dec2-00a7-4855-97c0-d854842b4b24".equals(u.getKey())));
152 
153         // 3. update an user to let them become part of both dyn realms        
154         anyUtilsFactory.getInstance(AnyTypeKind.USER).addAttr(
155                 plainAttrValidationManager,
156                 "823074dc-d280-436d-a7dd-07399fae48ec",
157                 plainSchemaDAO.find("cool"),
158                 "true");
159 
160         entityManager().flush();
161 
162         // 4. verify that dynamic members are still the same
163         matching1 = searchDAO.search(SearchCond.getLeaf(dynRealmCond1), AnyTypeKind.USER);
164         matching2 = searchDAO.search(SearchCond.getLeaf(dynRealmCond2), AnyTypeKind.USER);
165         assertEquals(matching1, matching2);
166         assertEquals(2, matching1.size());
167         assertTrue(matching1.stream().anyMatch(u -> "c9b2dec2-00a7-4855-97c0-d854842b4b24".equals(u.getKey())));
168         assertTrue(matching1.stream().anyMatch(u -> "823074dc-d280-436d-a7dd-07399fae48ec".equals(u.getKey())));
169     }
170 }