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.inner;
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.time.OffsetDateTime;
29  import java.time.temporal.ChronoUnit;
30  import java.util.List;
31  import java.util.Optional;
32  import org.apache.syncope.common.lib.types.CipherAlgorithm;
33  import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
34  import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
35  import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
36  import org.apache.syncope.core.persistence.api.dao.RealmDAO;
37  import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
38  import org.apache.syncope.core.persistence.api.dao.UserDAO;
39  import org.apache.syncope.core.persistence.api.entity.PlainSchema;
40  import org.apache.syncope.core.persistence.api.entity.user.UMembership;
41  import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
42  import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
43  import org.apache.syncope.core.persistence.api.entity.user.User;
44  import org.apache.syncope.core.persistence.jpa.AbstractTest;
45  import org.apache.syncope.core.spring.security.Encryptor;
46  import org.apache.syncope.core.spring.security.PasswordGenerator;
47  import org.junit.jupiter.api.Test;
48  import org.springframework.beans.factory.annotation.Autowired;
49  import org.springframework.transaction.annotation.Transactional;
50  
51  @Transactional("Master")
52  public class UserTest extends AbstractTest {
53  
54      @Autowired
55      private PasswordGenerator passwordGenerator;
56  
57      @Autowired
58      private UserDAO userDAO;
59  
60      @Autowired
61      private RealmDAO realmDAO;
62  
63      @Autowired
64      private ExternalResourceDAO resourceDAO;
65  
66      @Autowired
67      private PlainSchemaDAO plainSchemaDAO;
68  
69      @Autowired
70      private DerSchemaDAO derSchemaDAO;
71  
72      @Autowired
73      private SecurityQuestionDAO securityQuestionDAO;
74  
75      @Test
76      public void find() {
77          User user = userDAO.find("823074dc-d280-436d-a7dd-07399fae48ec");
78          assertNotNull(user);
79          assertEquals("puccini", user.getUsername());
80          assertFalse(user.isSuspended());
81          assertFalse(user.isMustChangePassword());
82          assertEquals("active", user.getStatus());
83          assertEquals(CipherAlgorithm.SHA1, user.getCipherAlgorithm());
84          assertEquals("e4c28e7a-9dbf-4ee7-9441-93812a0d4a28", user.getRealm().getKey());
85          assertNull(user.getSecurityQuestion());
86          assertNull(user.getSecurityAnswer());
87          assertEquals("admin", user.getCreator());
88          assertEquals("Giacomo", user.getPlainAttr("firstname").get().getValuesAsStrings().get(0));
89          assertEquals("Puccini", user.getPlainAttr("surname").get().getValuesAsStrings().get(0));
90      }
91  
92      @Test
93      public void findAll() {
94          List<User> users = userDAO.findAll(1, 100);
95          assertEquals(5, users.size());
96  
97          List<String> userKeys = userDAO.findAllKeys(1, 100);
98          assertNotNull(userKeys);
99  
100         assertEquals(users.size(), userKeys.size());
101     }
102 
103     @Test
104     public void count() {
105         int count = userDAO.count();
106         assertNotNull(count);
107         assertEquals(5, count);
108     }
109 
110     @Test
111     public void findAllByPageAndSize() {
112         // get first page
113         List<User> list = userDAO.findAll(1, 2);
114         assertEquals(2, list.size());
115 
116         // get second page
117         list = userDAO.findAll(2, 2);
118         assertEquals(2, list.size());
119 
120         // get second page with uncomplete set
121         list = userDAO.findAll(2, 3);
122         assertEquals(2, list.size());
123 
124         // get unexistent page
125         list = userDAO.findAll(3, 2);
126         assertEquals(1, list.size());
127     }
128 
129     @Test
130     public void findByDerAttrValue() {
131         List<User> list = userDAO.findByDerAttrValue(derSchemaDAO.find("cn"), "Vivaldi, Antonio", false);
132         assertEquals(1, list.size());
133 
134         list = userDAO.findByDerAttrValue(derSchemaDAO.find("cn"), "VIVALDI, ANTONIO", false);
135         assertEquals(0, list.size());
136 
137         list = userDAO.findByDerAttrValue(derSchemaDAO.find("cn"), "VIVALDI, ANTONIO", true);
138         assertEquals(1, list.size());
139     }
140 
141     @Test
142     public void findByInvalidDerAttrValue() {
143         assertTrue(userDAO.findByDerAttrValue(derSchemaDAO.find("cn"), "Antonio, Maria, Rossi", false).isEmpty());
144     }
145 
146     @Test
147     public void findByInvalidDerAttrExpression() {
148         assertTrue(userDAO.findByDerAttrValue(derSchemaDAO.find("noschema"), "Antonio, Maria", false).isEmpty());
149     }
150 
151     @Test
152     public void findByPlainAttrUniqueValue() {
153         UPlainAttrUniqueValue fullnameValue = entityFactory.newEntity(UPlainAttrUniqueValue.class);
154         fullnameValue.setStringValue("Gioacchino Rossini");
155 
156         PlainSchema fullname = plainSchemaDAO.find("fullname");
157 
158         Optional<User> found = userDAO.findByPlainAttrUniqueValue(fullname, fullnameValue, false);
159         assertTrue(found.isPresent());
160 
161         fullnameValue.setStringValue("Gioacchino ROSSINI");
162 
163         found = userDAO.findByPlainAttrUniqueValue(fullname, fullnameValue, false);
164         assertFalse(found.isPresent());
165 
166         found = userDAO.findByPlainAttrUniqueValue(fullname, fullnameValue, true);
167         assertTrue(found.isPresent());
168     }
169 
170     @Test
171     public void findByPlainAttrBooleanValue() {
172         UPlainAttrValue coolValue = entityFactory.newEntity(UPlainAttrValue.class);
173         coolValue.setBooleanValue(true);
174 
175         List<User> list = userDAO.findByPlainAttrValue(plainSchemaDAO.find("cool"), coolValue, false);
176         assertEquals(1, list.size());
177     }
178 
179     @Test
180     public void findByKey() {
181         User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
182         assertNotNull(user);
183     }
184 
185     @Test
186     public void findByUsername() {
187         User user = userDAO.findByUsername("rossini");
188         assertNotNull(user);
189         user = userDAO.findByUsername("vivaldi");
190         assertNotNull(user);
191         user = userDAO.findByUsername("user6");
192         assertNull(user);
193     }
194 
195     @Test
196     public void findMembership() {
197         UMembership memb = userDAO.findMembership("3d5e91f6-305e-45f9-ad30-4897d3d43bd9");
198         assertNotNull(memb);
199         assertEquals("1417acbe-cbf6-4277-9372-e75e04f97000", memb.getLeftEnd().getKey());
200     }
201 
202     @Test
203     public void save() {
204         User user = entityFactory.newEntity(User.class);
205         user.setUsername("username");
206         user.setRealm(realmDAO.findByFullPath("/even/two"));
207         user.setCreator("admin");
208         user.setCreationDate(OffsetDateTime.now());
209         user.setCipherAlgorithm(CipherAlgorithm.SHA256);
210         user.setPassword("password123");
211 
212         User actual = userDAO.save(user);
213         assertNotNull(actual);
214 
215         entityManager().flush();
216 
217         assertNotNull(userDAO.findLastChange(actual.getKey()));
218         assertTrue(actual.getLastChangeDate().truncatedTo(ChronoUnit.SECONDS).
219                 isEqual(userDAO.findLastChange(actual.getKey()).truncatedTo(ChronoUnit.SECONDS)));
220     }
221 
222     @Test
223     public void delete() {
224         User user = userDAO.find("b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee");
225 
226         userDAO.delete(user.getKey());
227 
228         User actual = userDAO.find("b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee");
229         assertNull(actual);
230     }
231 
232     @Test
233     public void issue237() {
234         User user = entityFactory.newEntity(User.class);
235         user.setUsername("username");
236         user.setRealm(realmDAO.findByFullPath("/even/two"));
237         user.setCreator("admin");
238         user.setCreationDate(OffsetDateTime.now());
239 
240         user.setCipherAlgorithm(CipherAlgorithm.AES);
241         user.setPassword("password123");
242 
243         User actual = userDAO.save(user);
244         assertNotNull(actual);
245     }
246 
247     @Test
248     public void issueSYNCOPE391() {
249         User user = entityFactory.newEntity(User.class);
250         user.setUsername("username");
251         user.setCipherAlgorithm(CipherAlgorithm.AES);
252         user.setPassword(null);
253         user.setRealm(realmDAO.findByFullPath("/even/two"));
254 
255         User actual = userDAO.save(user);
256         assertNull(user.getPassword());
257         assertNotNull(actual);
258     }
259 
260     @Test
261     public void testPasswordGenerator() {
262         String password = passwordGenerator.generate(resourceDAO.find("ws-target-resource-nopropagation"),
263                 List.of(realmDAO.getRoot()));
264         assertNotNull(password);
265 
266         User user = userDAO.find("c9b2dec2-00a7-4855-97c0-d854842b4b24");
267         user.setPassword(password);
268         userDAO.save(user);
269     }
270 
271     @Test
272     public void passwordGeneratorFailing() {
273         assertThrows(IllegalArgumentException.class, () -> {
274             String password = passwordGenerator.generate(resourceDAO.find("ws-target-resource-nopropagation"),
275                     List.of(realmDAO.getRoot()));
276             assertNotNull(password);
277 
278             User user = userDAO.find("c9b2dec2-00a7-4855-97c0-d854842b4b24");
279             // SYNCOPE-1666 fail because cipherAlgorithm is already set
280             user.setCipherAlgorithm(CipherAlgorithm.SHA);
281             user.setPassword(password);
282             userDAO.save(user);
283         });
284     }
285 
286     @Test
287     public void issueSYNCOPE1666() {
288         User user = entityFactory.newEntity(User.class);
289         user.setUsername("username");
290         user.setRealm(realmDAO.findByFullPath("/even/two"));
291         user.setCreator("admin");
292         user.setCreationDate(OffsetDateTime.now());
293         user.setCipherAlgorithm(CipherAlgorithm.SSHA256);
294         user.setPassword("password123");
295         user.setSecurityQuestion(securityQuestionDAO.find("887028ea-66fc-41e7-b397-620d7ea6dfbb"));
296         String securityAnswer = "my complex answer to @ $complex question è ? £12345";
297         user.setSecurityAnswer(securityAnswer);
298 
299         User actual = userDAO.save(user);
300         assertNotNull(actual);
301         assertNotNull(actual.getSecurityAnswer());
302         assertTrue(Encryptor.getInstance().verify(securityAnswer, CipherAlgorithm.SSHA256, actual.getSecurityAnswer()));
303     }
304 }