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.assertTrue;
26  
27  import java.util.List;
28  import java.util.UUID;
29  import org.apache.commons.lang3.ClassUtils;
30  import org.apache.syncope.common.lib.auth.AuthModuleConf;
31  import org.apache.syncope.common.lib.auth.DuoMfaAuthModuleConf;
32  import org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf;
33  import org.apache.syncope.common.lib.auth.JDBCAuthModuleConf;
34  import org.apache.syncope.common.lib.auth.JaasAuthModuleConf;
35  import org.apache.syncope.common.lib.auth.LDAPAuthModuleConf;
36  import org.apache.syncope.common.lib.auth.OIDCAuthModuleConf;
37  import org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf;
38  import org.apache.syncope.common.lib.auth.SimpleMfaAuthModuleConf;
39  import org.apache.syncope.common.lib.auth.StaticAuthModuleConf;
40  import org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf;
41  import org.apache.syncope.common.lib.auth.U2FAuthModuleConf;
42  import org.apache.syncope.common.lib.to.Item;
43  import org.apache.syncope.common.lib.types.AuthModuleState;
44  import org.apache.syncope.core.persistence.api.dao.AuthModuleDAO;
45  import org.apache.syncope.core.persistence.api.entity.am.AuthModule;
46  import org.apache.syncope.core.persistence.jpa.AbstractTest;
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 AuthModuleTest extends AbstractTest {
53  
54      @Autowired
55      private AuthModuleDAO authModuleDAO;
56  
57      @Test
58      public void findAll() {
59          List<AuthModule> modules = authModuleDAO.findAll();
60          assertNotNull(modules);
61          assertFalse(modules.isEmpty());
62          assertTrue(modules.size() >= 10);
63      }
64  
65      @Test
66      public void find() {
67          AuthModule authModule = authModuleDAO.find("DefaultLDAPAuthModule");
68          assertNotNull(authModule);
69          assertTrue(authModule.getConf() instanceof LDAPAuthModuleConf);
70  
71          authModule = authModuleDAO.find("DefaultSimpleMfaAuthModule");
72          assertNotNull(authModule);
73          assertTrue(authModule.getConf() instanceof SimpleMfaAuthModuleConf);
74  
75          authModule = authModuleDAO.find("DefaultJDBCAuthModule");
76          assertNotNull(authModule);
77          assertTrue(authModule.getConf() instanceof JDBCAuthModuleConf);
78  
79          authModule = authModuleDAO.find("DefaultGoogleMfaAuthModule");
80          assertNotNull(authModule);
81          assertTrue(authModule.getConf() instanceof GoogleMfaAuthModuleConf);
82  
83          authModule = authModuleDAO.find("DefaultDuoMfaAuthModule");
84          assertNotNull(authModule);
85          assertTrue(authModule.getConf() instanceof DuoMfaAuthModuleConf);
86  
87          authModule = authModuleDAO.find("DefaultOIDCAuthModule");
88          assertNotNull(authModule);
89          assertTrue(authModule.getConf() instanceof OIDCAuthModuleConf);
90  
91          authModule = authModuleDAO.find("DefaultSAML2IdPAuthModule");
92          assertNotNull(authModule);
93          assertTrue(authModule.getConf() instanceof SAML2IdPAuthModuleConf);
94  
95          authModule = authModuleDAO.find("DefaultJaasAuthModule");
96          assertNotNull(authModule);
97          assertTrue(authModule.getConf() instanceof JaasAuthModuleConf);
98  
99          authModule = authModuleDAO.find("DefaultStaticAuthModule");
100         assertNotNull(authModule);
101         assertTrue(authModule.getConf() instanceof StaticAuthModuleConf);
102 
103         authModule = authModuleDAO.find("DefaultSyncopeAuthModule");
104         assertNotNull(authModule);
105         assertTrue(authModule.getConf() instanceof SyncopeAuthModuleConf);
106 
107         authModule = authModuleDAO.find("DefaultU2FAuthModule");
108         assertNotNull(authModule);
109         assertTrue(authModule.getConf() instanceof U2FAuthModuleConf);
110     }
111 
112     @Test
113     public void findByType() {
114         List<AuthModule> authModules = authModuleDAO.findAll();
115         assertTrue(authModules.stream().anyMatch(
116                 authModule -> isSpecificConf(authModule.getConf(), LDAPAuthModuleConf.class)
117                 && authModule.getKey().equals("DefaultLDAPAuthModule")));
118         assertTrue(authModules.stream().anyMatch(
119                 authModule -> isSpecificConf(authModule.getConf(), JDBCAuthModuleConf.class)
120                 && authModule.getKey().equals("DefaultJDBCAuthModule")));
121         assertTrue(authModules.stream().anyMatch(
122                 authModule -> isSpecificConf(authModule.getConf(), GoogleMfaAuthModuleConf.class)
123                 && authModule.getKey().equals("DefaultGoogleMfaAuthModule")));
124         assertTrue(authModules.stream().anyMatch(
125                 authModule -> isSpecificConf(authModule.getConf(), DuoMfaAuthModuleConf.class)
126                 && authModule.getKey().equals("DefaultDuoMfaAuthModule")));
127         assertTrue(authModules.stream().anyMatch(
128                 authModule -> isSpecificConf(authModule.getConf(), OIDCAuthModuleConf.class)
129                 && authModule.getKey().equals("DefaultOIDCAuthModule")));
130         assertTrue(authModules.stream().anyMatch(
131                 authModule -> isSpecificConf(authModule.getConf(), SAML2IdPAuthModuleConf.class)
132                 && authModule.getKey().equals("DefaultSAML2IdPAuthModule")));
133         assertTrue(authModules.stream().anyMatch(
134                 authModule -> isSpecificConf(authModule.getConf(), JaasAuthModuleConf.class)
135                 && authModule.getKey().equals("DefaultJaasAuthModule")));
136         assertTrue(authModules.stream().anyMatch(
137                 authModule -> isSpecificConf(authModule.getConf(), StaticAuthModuleConf.class)
138                 && authModule.getKey().equals("DefaultStaticAuthModule")));
139         assertTrue(authModules.stream().anyMatch(
140                 authModule -> isSpecificConf(authModule.getConf(), SyncopeAuthModuleConf.class)
141                 && authModule.getKey().equals("DefaultSyncopeAuthModule")));
142         assertTrue(authModules.stream().anyMatch(
143                 authModule -> isSpecificConf(authModule.getConf(), U2FAuthModuleConf.class)
144                 && authModule.getKey().equals("DefaultU2FAuthModule")));
145     }
146 
147     @Test
148     public void saveWithStaticModule() {
149         StaticAuthModuleConf conf = new StaticAuthModuleConf();
150         conf.getUsers().put("user1", UUID.randomUUID().toString());
151         conf.getUsers().put("user2", "user2Password123");
152 
153         saveAuthModule("StaticAuthModuleTest", conf);
154     }
155 
156     @Test
157     public void saveWithJaasModule() {
158         JaasAuthModuleConf conf = new JaasAuthModuleConf();
159         conf.setKerberosKdcSystemProperty("sample-value");
160         conf.setKerberosRealmSystemProperty("sample-value");
161         conf.setLoginConfigType("JavaLoginConfig");
162         conf.setRealm("SYNCOPE");
163         conf.setLoginConfigurationFile("/opt/jaas/login.conf");
164 
165         saveAuthModule("JaasAuthModuleTest", conf);
166     }
167 
168     @Test
169     public void saveWithLdapModule() {
170         LDAPAuthModuleConf conf = new LDAPAuthModuleConf();
171         conf.setBaseDn("dc=example,dc=org");
172         conf.setSearchFilter("cn={user}");
173         conf.setSubtreeSearch(true);
174         conf.setLdapUrl("ldap://localhost:1389");
175         conf.setPrincipalAttributeId("uid");
176         conf.setBindCredential("Password");
177 
178         saveAuthModule("LDAPAuthModuleTest", conf);
179     }
180 
181     @Test
182     public void saveWithGoogleAuthenticatorModule() {
183         GoogleMfaAuthModuleConf conf = new GoogleMfaAuthModuleConf();
184         conf.setCodeDigits(6);
185         conf.setIssuer("SyncopeTest");
186         conf.setLabel("Syncope");
187         conf.setTimeStepSize(30);
188         conf.setWindowSize(3);
189 
190         saveAuthModule("GoogleMfaAuthModuleTest", conf);
191     }
192 
193     @Test
194     public void saveWithDuoAuthenticatorModule() {
195         DuoMfaAuthModuleConf conf = new DuoMfaAuthModuleConf();
196         conf.setSecretKey("Q2IU2i6BFNd6VYflZT8Evl6lF7oPlj4PM15BmRU7");
197         conf.setIntegrationKey("DIOXVRZD1UMZ8XXMNFQ6");
198         conf.setApiHost("theapi.duosecurity.com");
199         conf.setApplicationKey("u4IHCaREMB7Cb0S6QMISAgHycpj6lPBkDGfWt99I");
200         saveAuthModule("DuoMfaAuthModuleTest", conf);
201     }
202 
203     @Test
204     public void saveWithOIDCAuthModule() {
205         OIDCAuthModuleConf conf = new OIDCAuthModuleConf();
206         conf.setClientId("OIDCTestId");
207         conf.setDiscoveryUri("www.testurl.com");
208         conf.setUserIdAttribute("username");
209         conf.setResponseType("code");
210         conf.setScope("openid email profile");
211 
212         saveAuthModule("OIDCAuthModuleTest", conf);
213     }
214 
215     @Test
216     public void saveWithJDBCModule() {
217         JDBCAuthModuleConf conf = new JDBCAuthModuleConf();
218         conf.setSql("SELECT * FROM table WHERE name=?");
219         conf.setFieldPassword("password");
220 
221         saveAuthModule("JDBCAuthModuleTest", conf);
222     }
223 
224     @Test
225     public void saveWithSyncopeModule() {
226         SyncopeAuthModuleConf conf = new SyncopeAuthModuleConf();
227         conf.setDomain("Master");
228 
229         saveAuthModule("SyncopeAuthModuleTest", conf);
230     }
231 
232     @Test
233     public void saveWithSAML2IdPModule() {
234         SAML2IdPAuthModuleConf conf = new SAML2IdPAuthModuleConf();
235         conf.setServiceProviderEntityId("testEntityId");
236         conf.setProviderName("testProviderName");
237         saveAuthModule("SAML2IdPAuthModuleTest", conf);
238     }
239 
240     @Test
241     public void saveWithSimpleMfaModule() {
242         SimpleMfaAuthModuleConf conf = new SimpleMfaAuthModuleConf();
243         conf.setTokenLength(9);
244         conf.setTimeToKillInSeconds(120);
245         saveAuthModule("SimpleMfaAuthModuleConf", conf);
246     }
247 
248     @Test
249     public void saveWithU2FModule() {
250         U2FAuthModuleConf conf = new U2FAuthModuleConf();
251         conf.setExpireDevices(50);
252 
253         saveAuthModule("U2FAuthModuleTest", conf);
254     }
255 
256     @Test
257     public void updateWithLDAPModule() {
258         AuthModule module = authModuleDAO.find("DefaultLDAPAuthModule");
259         assertNotNull(module);
260         AuthModuleConf conf = module.getConf();
261         LDAPAuthModuleConf.class.cast(conf).setBaseDn("dc=example2,dc=org");
262         LDAPAuthModuleConf.class.cast(conf).setSearchFilter("cn={user2}");
263         module.setConf(conf);
264 
265         module = authModuleDAO.save(module);
266         assertNotNull(module);
267         assertNotNull(module.getKey());
268 
269         AuthModule found = authModuleDAO.find(module.getKey());
270         assertNotNull(found);
271         assertEquals("dc=example2,dc=org", LDAPAuthModuleConf.class.cast(found.getConf()).getBaseDn());
272         assertEquals("cn={user2}", LDAPAuthModuleConf.class.cast(found.getConf()).getSearchFilter());
273     }
274 
275     @Test
276     public void updateWithJDBCModule() {
277         AuthModule module = authModuleDAO.find("DefaultJDBCAuthModule");
278         assertNotNull(module);
279         AuthModuleConf conf = module.getConf();
280         JDBCAuthModuleConf.class.cast(conf).setSql("SELECT * FROM otherTable WHERE name=?");
281         module.setConf(conf);
282 
283         module = authModuleDAO.save(module);
284         assertNotNull(module);
285         assertNotNull(module.getKey());
286         AuthModule found = authModuleDAO.find(module.getKey());
287         assertNotNull(found);
288         assertEquals("SELECT * FROM otherTable WHERE name=?", JDBCAuthModuleConf.class.cast(found.getConf()).getSql());
289     }
290 
291     @Test
292     public void updateWithGoogleMfaModule() {
293         AuthModule module = authModuleDAO.find("DefaultGoogleMfaAuthModule");
294         assertNotNull(module);
295         AuthModuleConf conf = module.getConf();
296         GoogleMfaAuthModuleConf.class.cast(conf).setLabel("newLabel");
297         module.setConf(conf);
298 
299         module = authModuleDAO.save(module);
300         assertNotNull(module);
301         assertNotNull(module.getKey());
302         AuthModule found = authModuleDAO.find(module.getKey());
303         assertNotNull(found);
304         assertEquals("newLabel", GoogleMfaAuthModuleConf.class.cast(found.getConf()).getLabel());
305     }
306 
307     @Test
308     public void updateWithDuoMfaModule() {
309         AuthModule module = authModuleDAO.find("DefaultDuoMfaAuthModule");
310         assertNotNull(module);
311         AuthModuleConf conf = module.getConf();
312         String secretKey = UUID.randomUUID().toString();
313         DuoMfaAuthModuleConf.class.cast(conf).setSecretKey(secretKey);
314         module.setConf(conf);
315 
316         module = authModuleDAO.save(module);
317         assertNotNull(module);
318         assertNotNull(module.getKey());
319         AuthModule found = authModuleDAO.find(module.getKey());
320         assertNotNull(found);
321         assertEquals(secretKey, DuoMfaAuthModuleConf.class.cast(found.getConf()).getSecretKey());
322     }
323 
324     @Test
325     public void updateWithSAML2IdPModule() {
326         AuthModule module = authModuleDAO.find("DefaultSAML2IdPAuthModule");
327         assertNotNull(module);
328         AuthModuleConf conf = module.getConf();
329         SAML2IdPAuthModuleConf.class.cast(conf).setServiceProviderEntityId("newEntityId");
330         module.setConf(conf);
331 
332         module = authModuleDAO.save(module);
333         assertNotNull(module);
334         assertNotNull(module.getKey());
335         AuthModule found = authModuleDAO.find(module.getKey());
336         assertNotNull(found);
337         assertEquals("newEntityId", SAML2IdPAuthModuleConf.class.cast(found.getConf()).getServiceProviderEntityId());
338     }
339 
340     @Test
341     public void updateWithOIDCModule() {
342         AuthModule module = authModuleDAO.find("DefaultOIDCAuthModule");
343         assertNotNull(module);
344         AuthModuleConf conf = module.getConf();
345         OIDCAuthModuleConf.class.cast(conf).setResponseType("newCode");
346         module.setConf(conf);
347 
348         module = authModuleDAO.save(module);
349         assertNotNull(module);
350         assertNotNull(module.getKey());
351         AuthModule found = authModuleDAO.find(module.getKey());
352         assertNotNull(found);
353         assertEquals("newCode", OIDCAuthModuleConf.class.cast(found.getConf()).getResponseType());
354     }
355 
356     @Test
357     public void updateWithJaasModule() {
358         AuthModule module = authModuleDAO.find("DefaultJaasAuthModule");
359         assertNotNull(module);
360         AuthModuleConf conf = module.getConf();
361         JaasAuthModuleConf.class.cast(conf).setRealm("SYNCOPE_NEW");
362         module.setConf(conf);
363 
364         module = authModuleDAO.save(module);
365         assertNotNull(module);
366         assertNotNull(module.getKey());
367         AuthModule found = authModuleDAO.find(module.getKey());
368         assertNotNull(found);
369         assertEquals("SYNCOPE_NEW", JaasAuthModuleConf.class.cast(found.getConf()).getRealm());
370     }
371 
372     @Test
373     public void updateWithStaticModule() {
374         AuthModule module = authModuleDAO.find("DefaultStaticAuthModule");
375         assertNotNull(module);
376         assertEquals(1, StaticAuthModuleConf.class.cast(module.getConf()).getUsers().size());
377         AuthModuleConf conf = module.getConf();
378         StaticAuthModuleConf.class.cast(conf).getUsers().put("user3", "user3Password123");
379         module.setConf(conf);
380 
381         module = authModuleDAO.save(module);
382         assertNotNull(module);
383         assertNotNull(module.getKey());
384         AuthModule found = authModuleDAO.find(module.getKey());
385         assertNotNull(found);
386         assertEquals(2, StaticAuthModuleConf.class.cast(found.getConf()).getUsers().size());
387     }
388 
389     @Test
390     public void updateWithU2fModule() {
391         AuthModule module = authModuleDAO.find("DefaultU2FAuthModule");
392         assertNotNull(module);
393         AuthModuleConf conf = module.getConf();
394         U2FAuthModuleConf.class.cast(conf).setExpireDevices(24);
395         module.setConf(conf);
396 
397         module = authModuleDAO.save(module);
398         assertNotNull(module);
399         assertNotNull(module.getKey());
400         AuthModule found = authModuleDAO.find(module.getKey());
401         assertNotNull(found);
402         assertEquals(24, U2FAuthModuleConf.class.cast(found.getConf()).getExpireDevices());
403     }
404 
405     @Test
406     public void updateWithSyncopeModule() {
407         AuthModule module = authModuleDAO.find("DefaultSyncopeAuthModule");
408         assertNotNull(module);
409 
410         AuthModuleConf conf = module.getConf();
411         SyncopeAuthModuleConf.class.cast(conf).setDomain("Two");
412         module.setConf(conf);
413 
414         module = authModuleDAO.save(module);
415         assertNotNull(module);
416         assertNotNull(module.getKey());
417         AuthModule found = authModuleDAO.find(module.getKey());
418         assertNotNull(found);
419         assertEquals("Two", SyncopeAuthModuleConf.class.cast(found.getConf()).getDomain());
420     }
421 
422     @Test
423     public void delete() {
424         AuthModule authModule = authModuleDAO.find("DefaultSyncopeAuthModule");
425         assertNotNull(authModule);
426 
427         authModuleDAO.delete("DefaultSyncopeAuthModule");
428 
429         authModule = authModuleDAO.find("DefaultSyncopeAuthModule");
430         assertNull(authModule);
431     }
432 
433     private void saveAuthModule(final String key, final AuthModuleConf conf) {
434         AuthModule module = entityFactory.newEntity(AuthModule.class);
435         module.setKey(key);
436         module.setDescription("An authentication module");
437         module.setState(AuthModuleState.ACTIVE);
438         module.setConf(conf);
439 
440         Item keyMapping = new Item();
441         keyMapping.setIntAttrName("uid");
442         keyMapping.setExtAttrName("username");
443         module.getItems().add(keyMapping);
444 
445         Item fullnameMapping = new Item();
446         fullnameMapping.setIntAttrName("cn");
447         fullnameMapping.setExtAttrName("fullname");
448         module.getItems().add(fullnameMapping);
449 
450         module = authModuleDAO.save(module);
451         entityManager().flush();
452 
453         assertNotNull(module);
454         assertNotNull(module.getKey());
455         assertEquals(module, authModuleDAO.find(module.getKey()));
456         assertEquals(2, module.getItems().size());
457     }
458 
459     private static boolean isSpecificConf(final AuthModuleConf conf, final Class<? extends AuthModuleConf> clazz) {
460         return ClassUtils.isAssignable(clazz, conf.getClass());
461     }
462 }