This is an automated email from the ASF dual-hosted git repository. solomax pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/openmeetings.git
The following commit(s) were added to refs/heads/master by this push: new 523a676 [OPENMEETINGS-1856] first LDAP tests are added new 031c014 Merge branch 'master' of github.com:apache/openmeetings 523a676 is described below commit 523a67675cb020c4c0a8558daf3bb8f9beec9cc9 Author: Maxim Solodovnik <solomax...@gmail.com> AuthorDate: Tue Oct 30 13:23:59 2018 +0700 [OPENMEETINGS-1856] first LDAP tests are added --- .../openmeetings/core/ldap/LdapLoginManager.java | 22 +--- .../apache/openmeetings/core/ldap/LdapOptions.java | 14 +-- .../org/apache/openmeetings/util/OmFileHelper.java | 25 +++- openmeetings-web/pom.xml | 12 ++ .../org/apache/openmeetings/ldap/TestLdap.java | 135 +++++++++++++++++++++ .../src/test/resources/schema/users.ldif | 46 +++++++ 6 files changed, 226 insertions(+), 28 deletions(-) diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java index 6abbf36..1221960 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java @@ -18,21 +18,16 @@ */ package org.apache.openmeetings.core.ldap; -import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.openmeetings.db.dao.user.UserDao.getNewUserInstance; import static org.apache.openmeetings.db.util.LocaleHelper.validateCountry; import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone; import static org.apache.openmeetings.util.OmException.BAD_CREDENTIALS; import static org.apache.openmeetings.util.OmException.UNKNOWN; +import static org.apache.openmeetings.util.OmFileHelper.loadLdapConf; import static org.apache.openmeetings.util.OpenmeetingsVariables.getDefaultGroup; import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; import java.util.AbstractMap; import java.util.ArrayList; import java.util.List; @@ -66,7 +61,6 @@ import org.apache.openmeetings.db.entity.user.User; import org.apache.openmeetings.db.entity.user.User.Right; import org.apache.openmeetings.db.entity.user.User.Type; import org.apache.openmeetings.util.OmException; -import org.apache.openmeetings.util.OmFileHelper; import org.apache.wicket.util.string.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -332,18 +326,8 @@ public class LdapLoginManager { public LdapWorker(Long domainId) throws Exception { this.domainId = domainId; ldapCfg = ldapConfigDao.get(domainId); - try (InputStream is = new FileInputStream(new File(OmFileHelper.getConfDir(), ldapCfg.getConfigFileName())); - Reader r = new InputStreamReader(is, UTF_8)) - { - config.load(r); - if (config.isEmpty()) { - throw new RuntimeException("Error on LdapLogin : Configurationdata couldnt be retrieved!"); - } - options = new LdapOptions(config); - } catch (Exception e) { - log.error("Error on LdapLogin : Configurationdata couldn't be retrieved!"); - throw e; - } + loadLdapConf(ldapCfg.getConfigFileName(), config); + options = new LdapOptions(config); conn = new LdapNetworkConnection(options.host, options.port, options.secure); } diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java index fa5ea2a..a2d7f8d 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java @@ -33,20 +33,20 @@ import org.slf4j.LoggerFactory; public class LdapOptions { private static final Logger log = LoggerFactory.getLogger(LdapOptions.class); private static final String EMPTY_FORMAT = "%s"; - private static final String CONFIGKEY_LDAP_HOST = "ldap_conn_host"; - private static final String CONFIGKEY_LDAP_PORT = "ldap_conn_port"; + public static final String CONFIGKEY_LDAP_HOST = "ldap_conn_host"; + public static final String CONFIGKEY_LDAP_PORT = "ldap_conn_port"; private static final String CONFIGKEY_LDAP_SECURE = "ldap_conn_secure"; - private static final String CONFIGKEY_LDAP_ADMIN_DN = "ldap_admin_dn"; - private static final String CONFIGKEY_LDAP_ADMIN_PASSWD = "ldap_passwd"; - private static final String CONFIGKEY_LDAP_AUTH_TYPE = "ldap_auth_type"; + public static final String CONFIGKEY_LDAP_ADMIN_DN = "ldap_admin_dn"; + public static final String CONFIGKEY_LDAP_ADMIN_PASSWD = "ldap_passwd"; + public static final String CONFIGKEY_LDAP_AUTH_TYPE = "ldap_auth_type"; private static final String CONFIGKEY_LDAP_PROV_TYPE = "ldap_provisionning"; private static final String CONFIGKEY_LDAP_USE_LOWER_CASE = "ldap_use_lower_case"; private static final String CONFIGKEY_LDAP_USE_ADMIN_4ATTRS = "ldap_use_admin_to_get_attrs"; private static final String CONFIGKEY_LDAP_DEREF_MODE = "ldap_deref_mode"; private static final String CONFIGKEY_LDAP_GROUP_MODE = "ldap_group_mode"; - private static final String CONFIGKEY_LDAP_SEARCH_BASE = "ldap_search_base"; + public static final String CONFIGKEY_LDAP_SEARCH_BASE = "ldap_search_base"; private static final String CONFIGKEY_LDAP_SEARCH_QUERY = "ldap_search_query"; - private static final String CONFIGKEY_LDAP_SEARCH_SCOPE = "ldap_search_scope"; + public static final String CONFIGKEY_LDAP_SEARCH_SCOPE = "ldap_search_scope"; private static final String CONFIGKEY_LDAP_SYNC_PASSWD_OM = "ldap_sync_password_to_om"; // 'true' or 'false' static final String CONFIGKEY_LDAP_TIMEZONE_NAME = "ldap_user_timezone"; private static final String CONFIGKEY_LDAP_USERDN_FORMAT = "ldap_userdn_format"; diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java index f4ecb4c..4a99152 100644 --- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java +++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java @@ -18,9 +18,16 @@ */ package org.apache.openmeetings.util; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.text.DecimalFormat; +import java.util.Properties; import org.apache.openmeetings.util.ConnectionProperties.DbType; import org.slf4j.Logger; @@ -254,8 +261,22 @@ public class OmFileHelper { return new File(OmFileHelper.getWebinfDir(), dbType == null ? PERSISTENCE_NAME : String.format(DB_PERSISTENCE_NAME, dbType)); } - public static File getConfDir() { - return new File(OmFileHelper.omHome, CONF_DIR); + public static File getLdapConf(String name) { + return new File(new File(OmFileHelper.omHome, CONF_DIR), name); + } + + public static void loadLdapConf(String name, Properties config) { + try (InputStream is = new FileInputStream(getLdapConf(name)); + Reader r = new InputStreamReader(is, UTF_8)) + { + config.load(r); + if (config.isEmpty()) { + throw new RuntimeException("Error on LdapLogin : Configurationdata couldnt be retrieved!"); + } + } catch (IOException e) { + log.error("Error on LdapLogin : Configurationdata couldn't be retrieved!"); + throw new RuntimeException(e); + } } public static File getScreenSharingDir() { diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml index 1737b6d..6185131 100644 --- a/openmeetings-web/pom.xml +++ b/openmeetings-web/pom.xml @@ -721,5 +721,17 @@ <version>${tomcat.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.directory.server</groupId> + <artifactId>apacheds-test-framework</artifactId> + <version>2.0.0.AM25</version> + <exclusions> + <exclusion> + <groupId>org.apache.directory.api</groupId> + <artifactId>api-ldap-schema-data</artifactId> + </exclusion> + </exclusions> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java b/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java new file mode 100644 index 0000000..9bd01a0 --- /dev/null +++ b/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License") + you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openmeetings.ldap; + +import static org.apache.directory.server.constants.ServerDNConstants.ADMIN_SYSTEM_DN; +import static org.apache.directory.server.core.api.partition.PartitionNexus.ADMIN_PASSWORD_BYTES; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_ADMIN_DN; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_ADMIN_PASSWD; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_AUTH_TYPE; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_HOST; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_PORT; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_SEARCH_BASE; +import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_SEARCH_SCOPE; +import static org.apache.openmeetings.util.OmFileHelper.getLdapConf; +import static org.apache.openmeetings.util.OmFileHelper.loadLdapConf; +import static org.junit.Assert.assertTrue; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifFiles; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.annotations.CreatePartition; +import org.apache.directory.server.core.integ.CreateLdapServerRule; +import org.apache.directory.server.protocol.shared.transport.Transport; +import org.apache.openmeetings.AbstractWicketTester; +import org.apache.openmeetings.core.ldap.LdapLoginManager; +import org.apache.openmeetings.db.dao.server.LdapConfigDao; +import org.apache.openmeetings.db.entity.server.LdapConfig; +import org.apache.openmeetings.db.entity.user.User; +import org.apache.openmeetings.util.OmException; +import org.apache.openmeetings.web.app.WebSession; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +@CreateDS(name = "omDS", + partitions = { + @CreatePartition(name = "test", suffix = "dc=test,dc=openmeetings,dc=apache,dc=org") + }) +@CreateLdapServer(transports = { @CreateTransport(protocol = "LDAP", address = "localhost")}) +@ApplyLdifFiles({"schema/users.ldif"}) +public class TestLdap extends AbstractWicketTester { + private static final String CFG_SEARCH_BIND = UUID.randomUUID().toString(); + private static final String BAD_PASSWORD = "bad password"; + private static final String USER1 = "ldaptest1"; + private static final Map<String, LdapConfig> CFG_MAP = new HashMap<>(); + private static final Properties PROPS = new Properties(); + @Autowired + private LdapConfigDao ldapDao; + + @ClassRule + public static CreateLdapServerRule serverRule = new CreateLdapServerRule(); + + @BeforeClass + public static void prepare() { + loadLdapConf("om_ldap.cfg", PROPS); + Transport t = serverRule.getLdapServer().getTransports()[0]; + PROPS.put(CONFIGKEY_LDAP_HOST, t.getAddress()); + PROPS.put(CONFIGKEY_LDAP_PORT, String.valueOf(t.getPort())); + PROPS.put(CONFIGKEY_LDAP_ADMIN_DN, ADMIN_SYSTEM_DN); + PROPS.put(CONFIGKEY_LDAP_ADMIN_PASSWD, new String(ADMIN_PASSWORD_BYTES)); + PROPS.put(CONFIGKEY_LDAP_SEARCH_BASE, "dc=test,dc=openmeetings,dc=apache,dc=org"); + PROPS.put(CONFIGKEY_LDAP_SEARCH_SCOPE, SearchScope.SUBTREE.name()); + } + + private void createSbnd() throws FileNotFoundException, IOException { + Properties pp = new Properties(); + pp.putAll(PROPS); + pp.put(CONFIGKEY_LDAP_AUTH_TYPE, LdapLoginManager.AuthType.SEARCHANDBIND.name()); + try (OutputStream out = new FileOutputStream(getLdapConf(CFG_SEARCH_BIND))) { + pp.store(out, ""); + } + LdapConfig cfg = new LdapConfig(); + cfg.setName(CFG_SEARCH_BIND); + cfg.setActive(true); + cfg.setConfigFileName(CFG_SEARCH_BIND); + ldapDao.update(cfg, null); + CFG_MAP.put(CFG_SEARCH_BIND, cfg); + } + + @Before + public void clean() throws FileNotFoundException, IOException { + if (CFG_MAP.isEmpty()) { + createSbnd(); + } + for (LdapConfig cfg : ldapDao.getActive()) { + if (!CFG_MAP.containsKey(cfg.getName())) { + cfg.setActive(false); + ldapDao.update(cfg, null); + } else { + CFG_MAP.put(cfg.getName(), cfg); + } + } + } + + @Test + public void testSbndSessionLogin() throws OmException { + LdapConfig cfg = CFG_MAP.get(CFG_SEARCH_BIND); + assertTrue("Login should be successful", WebSession.get().signIn(USER1, userpass, User.Type.ldap, cfg.getId())); + } + + @Test(expected = OmException.class) + public void testSbndSessionLoginBadPassword() throws OmException { + LdapConfig cfg = CFG_MAP.get(CFG_SEARCH_BIND); + WebSession.get().signIn(USER1, BAD_PASSWORD, User.Type.ldap, cfg.getId()); + } +} diff --git a/openmeetings-web/src/test/resources/schema/users.ldif b/openmeetings-web/src/test/resources/schema/users.ldif new file mode 100644 index 0000000..af54bf6 --- /dev/null +++ b/openmeetings-web/src/test/resources/schema/users.ldif @@ -0,0 +1,46 @@ +# Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 +version: 1 +dn: dc=test,dc=openmeetings,dc=apache,dc=org +objectClass: domain +objectClass: top +dc: test + +dn: ou=Users,dc=test,dc=openmeetings,dc=apache,dc=org +objectClass: organizationalUnit +objectClass: top +ou: Users + +dn: ou=Groups,dc=test,dc=openmeetings,dc=apache,dc=org +objectClass: organizationalUnit +objectClass: top +ou: Groups + +dn: cn=Test1 Ldap,ou=Users,dc=test,dc=openmeetings,dc=apache,dc=org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: Test1 Ldap +sn: Ldap +uid: ldaptest1 +userPassword: Q!w2e3r4t5 + +dn: cn=Test2 Ldap,ou=Users,dc=test,dc=openmeetings,dc=apache,dc=org +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: Test2 Ldap +sn: Ldap +uid: ldaptest2 +userPassword: Q!w2e3r4t5 + +dn: cn=Test3 Ldap,ou=Users,dc=test,dc=openmeetings,dc=apache,dc=org +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: Test3 Ldap +sn: Ldap +uid: ldaptest3 +userPassword: Q!w2e3r4t5