From 38a3f00c2df44379133dabbc08978548d5e5a955 Mon Sep 17 00:00:00 2001 From: madness-inc Date: Mon, 6 Apr 2020 11:57:23 +0200 Subject: [PATCH] MGR-102 show LDAP settings and users --- .../conf/datasources/ds-ldapusers.xml | 46 +++++++ application-home/conf/pages/pg-sites.xml | 4 +- application-home/conf/pages/pg-subjects.xml | 15 ++- .../dictionary/manager-messages.properties | 4 + .../manager/business/LdapUsers.java | 118 ++++++++++++++++++ .../application/manager/business/Sites.java | 3 + .../manager/business/LdapUsersTest.java | 59 +++++++++ .../xml/LdapUsersTest-testSettings.xml | 74 +++++++++++ .../resources/xml/LdapUsersTest-testUsers.xml | 24 ++++ 9 files changed, 342 insertions(+), 5 deletions(-) create mode 100644 application-home/conf/datasources/ds-ldapusers.xml create mode 100644 src/main/java/org/appng/application/manager/business/LdapUsers.java create mode 100644 src/test/java/org/appng/application/manager/business/LdapUsersTest.java create mode 100644 src/test/resources/xml/LdapUsersTest-testSettings.xml create mode 100644 src/test/resources/xml/LdapUsersTest-testUsers.xml diff --git a/application-home/conf/datasources/ds-ldapusers.xml b/application-home/conf/datasources/ds-ldapusers.xml new file mode 100644 index 0000000..cf6fba1 --- /dev/null +++ b/application-home/conf/datasources/ds-ldapusers.xml @@ -0,0 +1,46 @@ + + + + + + + <params /> + <meta-data bindClass="org.appng.application.manager.business.LdapUsers.LdapUser"> + <field name="name" type="text"> + <label id="name" /> + </field> + <field name="realname" type="text"> + <label id="realname" /> + </field> + <field name="type" type="text"> + <label id="type" /> + </field> + <field name="dn" type="text" displayLength="80"> + <label id="distinguishedName" /> + </field> + </meta-data> + </config> + <bean id="ldapUsers"> + </bean> + </datasource> + + <datasource id="ldapSettings"> + <config> + <title id="ldap.settings" /> + <meta-data bindClass="org.appng.api.model.SimpleProperty"> + <field name="name" type="text"> + <label id="name" /> + </field> + <field name="value" type="text"> + <label id="value" /> + </field> + </meta-data> + </config> + <bean id="ldapUsers"> + <option name="mode" value="settings" /> + </bean> + </datasource> + +</datasources> \ No newline at end of file diff --git a/application-home/conf/pages/pg-sites.xml b/application-home/conf/pages/pg-sites.xml index 82072d2..f00e549 100644 --- a/application-home/conf/pages/pg-sites.xml +++ b/application-home/conf/pages/pg-sites.xml @@ -84,7 +84,7 @@ </element> </section> - <!-- site properites --> + <!-- site properties --> <section> <!-- create --> <element passive="true"> @@ -269,6 +269,7 @@ </datasource> </element> </section> + <!-- cache --> <section> <title id="cache" /> <element folded="true"> @@ -290,6 +291,7 @@ </datasource> </element> </section> + <!-- sessions --> <section> <element folded="false"> <datasource id="sessions"> diff --git a/application-home/conf/pages/pg-subjects.xml b/application-home/conf/pages/pg-subjects.xml index b22e532..748a998 100644 --- a/application-home/conf/pages/pg-subjects.xml +++ b/application-home/conf/pages/pg-subjects.xml @@ -32,6 +32,7 @@ </url-schema> </config> <structure> + <!-- subjects --> <section> <!-- create --> <element passive="true"> @@ -62,7 +63,7 @@ </datasource> </element> </section> - + <!-- groups --> <section> <!-- create --> <element passive="true"> @@ -93,7 +94,15 @@ </datasource> </element> </section> - + <!-- LDAP --> + <section> + <element> + <datasource id="ldapSettings" /> + </element> + <element> + <datasource id="ldapUsers" /> + </element> + </section> <!-- hidden inline actions --> <section hidden="true"> @@ -105,8 +114,6 @@ </params> </action> </element> - </section> - <section hidden="true"> <element> <action eventId="groupEvent" id="deleteGroup" onSuccess="/users#tab_groups"> <params> diff --git a/application-home/dictionary/manager-messages.properties b/application-home/dictionary/manager-messages.properties index aafa2b3..f9de5d5 100644 --- a/application-home/dictionary/manager-messages.properties +++ b/application-home/dictionary/manager-messages.properties @@ -78,6 +78,7 @@ description=Description dictionary=Dictionary digest=Digest displayName=Display name +distinguishedName=Distinguished Name domain=Domain driverClass=Driver-Class edit=Edit @@ -134,6 +135,9 @@ lastLogin=Last login lastUpdated=Last updated latestRelease=Latest release latestSnapshot=Latest snapshot +ldap.users=LDAP Users +ldap.settings=LDAP Settings +ldap.not.working=Unable to connect to LDAP server at {0}, please check configuration! locked=Locked locked.filter.all=All locked.filter.true=Yes diff --git a/src/main/java/org/appng/application/manager/business/LdapUsers.java b/src/main/java/org/appng/application/manager/business/LdapUsers.java new file mode 100644 index 0000000..ee10dd3 --- /dev/null +++ b/src/main/java/org/appng/application/manager/business/LdapUsers.java @@ -0,0 +1,118 @@ +/* + * Copyright 2011-2020 the original author or authors. + * + * Licensed 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.appng.application.manager.business; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.appng.api.DataContainer; +import org.appng.api.DataProvider; +import org.appng.api.Environment; +import org.appng.api.FieldProcessor; +import org.appng.api.Options; +import org.appng.api.Request; +import org.appng.api.model.Application; +import org.appng.api.model.Properties; +import org.appng.api.model.Property; +import org.appng.api.model.SimpleProperty; +import org.appng.api.model.Site; +import org.appng.api.model.UserType; +import org.appng.application.manager.MessageConstants; +import org.appng.core.domain.SubjectImpl; +import org.appng.core.service.CoreService; +import org.appng.core.service.LdapService; +import org.springframework.stereotype.Component; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Component +public class LdapUsers implements DataProvider { + + private CoreService coreService; + + private LdapUsers(CoreService coreService) { + this.coreService = coreService; + } + + @Override + public DataContainer getData(Site site, Application application, Environment environment, Options options, + Request request, FieldProcessor fp) { + + DataContainer dataContainer = new DataContainer(fp); + String mode = options.getString("mode", "value"); + LdapService ldapService = new LdapService(); + + Properties siteProps = site.getProperties(); + if ("settings".equals(mode)) { + List<Property> ldapProps = new ArrayList<>(); + SimpleProperty ldapHost = getProperty(siteProps, LdapService.LDAP_HOST); + ldapProps.add(ldapHost); + ldapProps.add(getProperty(siteProps, LdapService.LDAP_DOMAIN)); + ldapProps.add(getProperty(siteProps, LdapService.LDAP_GROUP_BASE_DN)); + SimpleProperty ldapUser = getProperty(siteProps, LdapService.LDAP_USER); + ldapProps.add(ldapUser); + ldapProps.add(getProperty(siteProps, LdapService.LDAP_ID_ATTRIBUTE)); + ldapProps.add(getProperty(siteProps, LdapService.LDAP_PRINCIPAL_SCHEME)); + ldapProps.add(getProperty(siteProps, LdapService.LDAP_START_TLS)); + dataContainer.setItems(ldapProps); + char[] ldapPw = siteProps.getString(LdapService.LDAP_PASSWORD, StringUtils.EMPTY).toCharArray(); + boolean adminLoginOk = ldapService.loginUser(site, ldapUser.getString(), ldapPw); + if (!adminLoginOk) { + fp.addErrorMessage(request.getMessage(MessageConstants.LDAP_NOT_WORKING, ldapHost.getString())); + } + } else { + + List<LdapUser> users = new ArrayList<>(); + + List<SubjectImpl> globalGroups = coreService.getSubjectsByType(UserType.GLOBAL_GROUP); + for (SubjectImpl globalGroup : globalGroups) { + List<SubjectImpl> membersOfGroup = ldapService.getMembersOfGroup(site, globalGroup.getName()); + users.addAll(membersOfGroup.stream().map(s -> new LdapUser(s.getName(), s.getEmail(), s.getRealname(), + UserType.GLOBAL_GROUP, globalGroup.getName())).collect(Collectors.toList())); + } + List<SubjectImpl> globalUsers = coreService.getSubjectsByType(UserType.GLOBAL_USER); + String userDn = siteProps.getString(LdapService.LDAP_ID_ATTRIBUTE) + "=%s," + + siteProps.getString(LdapService.LDAP_USER_BASE_DN); + users.addAll(globalUsers.stream().map(s -> { + return new LdapUser(s.getName(), s.getEmail(), s.getRealname(), s.getUserType(), + String.format(userDn, s.getName())); + }).collect(Collectors.toList())); + + dataContainer.setPage(users, fp.getPageable(), true); + } + return dataContainer; + } + + private SimpleProperty getProperty(Properties siteProps, String propName) { + SimpleProperty prop = new SimpleProperty(propName, siteProps.getString(propName)); + prop.determineType(); + return prop; + } + + @Data + @AllArgsConstructor + public class LdapUser { + private String name; + private String email; + private String realname; + private UserType type; + private String groupOrDn; + } + +} diff --git a/src/main/java/org/appng/application/manager/business/Sites.java b/src/main/java/org/appng/application/manager/business/Sites.java index 8d483d0..202003d 100644 --- a/src/main/java/org/appng/application/manager/business/Sites.java +++ b/src/main/java/org/appng/application/manager/business/Sites.java @@ -24,10 +24,12 @@ import org.appng.api.InvalidConfigurationException; import org.appng.api.Options; import org.appng.api.Request; +import org.appng.api.Scope; import org.appng.api.model.Application; import org.appng.api.model.Site; import org.appng.application.manager.MessageConstants; import org.appng.application.manager.form.SiteForm; +import org.appng.application.manager.form.SubjectForm; import org.appng.application.manager.service.Service; import org.appng.application.manager.service.ServiceAware; import org.appng.core.domain.SiteImpl; @@ -92,6 +94,7 @@ public void perform(Site site, Application application, Environment environment, public DataContainer getData(Site site, Application application, Environment environment, Options options, Request request, FieldProcessor fp) { + environment.setAttribute(Scope.SESSION, "subjectForm", new SubjectForm()); Service service = getService(); Integer siteId = options.getInteger(SITE, ID); DataContainer data = null; diff --git a/src/test/java/org/appng/application/manager/business/LdapUsersTest.java b/src/test/java/org/appng/application/manager/business/LdapUsersTest.java new file mode 100644 index 0000000..5600eb2 --- /dev/null +++ b/src/test/java/org/appng/application/manager/business/LdapUsersTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2011-2020 the original author or authors. + * + * Licensed 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.appng.application.manager.business; + +import java.util.List; + +import org.appng.api.model.Property; +import org.appng.api.model.SimpleProperty; +import org.appng.api.support.CallableDataSource; +import org.appng.core.service.LdapService; +import org.appng.testsupport.validation.WritingXmlValidator; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LdapUsersTest extends AbstractTest { + + static { + WritingXmlValidator.writeXml = false; + } + + @Test + public void testUsers() throws Exception { + CallableDataSource ldapUsers = getDataSource("ldapUsers").getCallableDataSource(); + ldapUsers.perform(""); + validate(ldapUsers.getDatasource()); + } + + @Test + public void testSettings() throws Exception { + CallableDataSource ldapUsers = getDataSource("ldapSettings").getCallableDataSource(); + ldapUsers.perform(""); + validate(ldapUsers.getDatasource()); + } + + @Override + protected List<Property> getSiteProperties(String prefix) { + List<Property> siteProperties = super.getSiteProperties(prefix); + siteProperties.add(new SimpleProperty(prefix + LdapService.LDAP_START_TLS, "false")); + siteProperties.add(new SimpleProperty(prefix + LdapService.LDAP_HOST, "ldap://localhost:389")); + siteProperties.add(new SimpleProperty(prefix + LdapService.LDAP_PRINCIPAL_SCHEME, "DN")); + return siteProperties; + } + +} diff --git a/src/test/resources/xml/LdapUsersTest-testSettings.xml b/src/test/resources/xml/LdapUsersTest-testSettings.xml new file mode 100644 index 0000000..f67948f --- /dev/null +++ b/src/test/resources/xml/LdapUsersTest-testSettings.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<datasource xmlns="http://www.appng.org/schema/platform" id="ldapSettings"> + <config> + <title id="ldap.settings">LDAP Settings + + + + + + + + + + + + + + ldapHost + + + ldap://localhost:389 + + + + + ldapDomain + + + + + + + + ldapGroupBaseDn + + + + + + + + ldapUser + + + + + + + + ldapIdAttribute + + + + + + + + ldapPrincipalScheme + + + DN + + + + + ldapStartTls + + + false + + + + + diff --git a/src/test/resources/xml/LdapUsersTest-testUsers.xml b/src/test/resources/xml/LdapUsersTest-testUsers.xml new file mode 100644 index 0000000..9e32a06 --- /dev/null +++ b/src/test/resources/xml/LdapUsersTest-testUsers.xml @@ -0,0 +1,24 @@ + + + + LDAP Users + + + + + + + + + + + + + + + + + + + +