LibrePlan - LDAP role matching

FEA: ItEr74S09LdapAuhentication
This commit is contained in:
Ignacio Diaz Teijido 2011-06-22 11:11:11 +02:00 committed by Manuel Rego Casasnovas
parent 36eaa4014c
commit cb1e604dc6
9 changed files with 546 additions and 82 deletions

View file

@ -33,6 +33,7 @@ import org.navalplanner.business.common.BaseEntity;
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Cristina Alvarino Perez <cristina.alvarino@comtecsf.es>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*/
public class Configuration extends BaseEntity {
@ -381,5 +382,4 @@ public class Configuration extends BaseEntity {
public void setLdapConfiguration(LDAPConfiguration ldapConfiguration) {
this.ldapConfiguration = ldapConfiguration;
}
}

View file

@ -0,0 +1,58 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 ComtecSF, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.common.entities;
import org.hibernate.validator.NotEmpty;
/**
* A class which is used to store the configuration of the matching between the
* LDAP roles and LibrePlan roles this will be used in LDAP configuration tab of
* the Configuration screen.
*
* This class is a component of LdapConfiguration class
*
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
* @author Cristina Alvarino Perez <cristina.alvarino@comtecsf.es>
*/
public class ConfigurationRolesLDAP {
private String roleLdap;
private String roleLibreplan;
@NotEmpty(message = "role ldap not specified")
public String getRoleLdap() {
return roleLdap;
}
public void setRoleLdap(String roleLdap) {
this.roleLdap = roleLdap;
}
@NotEmpty(message = "role libreplan not specified")
public String getRoleLibreplan() {
return roleLibreplan;
}
public void setRoleLibreplan(String roleLibreplan) {
this.roleLibreplan = roleLibreplan;
}
}

View file

@ -19,15 +19,21 @@
package org.navalplanner.business.common.entities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.users.entities.UserRole;
/**
*
* This entity will be used to store the LDAP connection properties for
* authentication
*
* @author Ignacio Diaz <ignacio.diaz@comtecsf.es>
* @author Cristina Alvarino <cristina.alvarino@comtecsf.es>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
* @author Cristina Alvarino Perez<cristina.alvarino@comtecsf.es>
*
*/
public class LDAPConfiguration extends BaseEntity {
@ -49,12 +55,24 @@ public class LDAPConfiguration extends BaseEntity {
private String ldapPassword;
private String ldapGroupPath;
private String ldapRoleProperty;
// LDAP passwords will be imported to DB or not
private Boolean ldapSavePasswordsDB = true;
// LDAP Authentication will be used or not
private Boolean ldapAuthEnabled = false;
// LDAP roles will be used or not
private Boolean ldapSaveRolesDB = false;
// A list which stores the matching between LDAP roles and LibrePlan roles
private List<ConfigurationRolesLDAP> configurationRolesLdap = new ArrayList<ConfigurationRolesLDAP>();
private Map<String, List<String>> mapMatchingRoles = new HashMap<String, List<String>>();
public String getLdapUserId() {
return ldapUserId;
}
@ -119,4 +137,64 @@ public class LDAPConfiguration extends BaseEntity {
this.ldapAuthEnabled = ldapAuthEnabled;
}
public Boolean getLdapSaveRolesDB() {
return ldapSaveRolesDB;
}
public void setLdapSaveRolesDB(Boolean ldapSaveRolesDB) {
this.ldapSaveRolesDB = ldapSaveRolesDB;
}
public Boolean getLdapSavePasswordsDB() {
return ldapSavePasswordsDB;
}
public String getLdapGroupPath() {
return ldapGroupPath;
}
public void setLdapGroupPath(String ldapGroupPath) {
this.ldapGroupPath = ldapGroupPath;
}
public String getLdapRoleProperty() {
return ldapRoleProperty;
}
public void setLdapRoleProperty(String ldapRoleProperty) {
this.ldapRoleProperty = ldapRoleProperty;
}
public List<ConfigurationRolesLDAP> getConfigurationRolesLdap() {
return configurationRolesLdap;
}
public void setConfigurationRolesLdap(
List<ConfigurationRolesLDAP> configurationRolesLdap) {
this.configurationRolesLdap = configurationRolesLdap;
}
public Map<String, List<String>> getMapMatchingRoles() {
for (UserRole role : UserRole.values()) {
List<String> listRolesLdap = new ArrayList<String>();
for (ConfigurationRolesLDAP roleLdap : this.configurationRolesLdap) {
// if the role of librePlan is equals to role stored in
// configurationLdap, it is added to list
if (roleLdap != null
&& role.name().equals(roleLdap.getRoleLibreplan())) {
listRolesLdap.add(roleLdap.getRoleLdap());
}
}
mapMatchingRoles.put(role.name(), listRolesLdap);
}
return mapMatchingRoles;
}
public void setMapMatchingRoles(Map<String, List<String>> mapMatchingRoles) {
this.mapMatchingRoles = mapMatchingRoles;
}
}

View file

@ -9,36 +9,42 @@
<column name="ldap_host" type="VARCHAR(255)" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-port" author="calvarinop">
<comment>Add new column to store ldap port</comment>
<addColumn tableName="configuration">
<column name="ldap_port" type="VARCHAR(5)" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-base" author="calvarinop">
<comment>Add new column to store ldap base</comment>
<addColumn tableName="configuration">
<column name="ldap_base" type="VARCHAR(255)" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-userdn" author="calvarinop">
<comment>Add new column to store ldap userdn</comment>
<addColumn tableName="configuration">
<column name="ldap_userdn" type="VARCHAR(255)" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-password" author="calvarinop">
<comment>Add new column to store ldap password</comment>
<addColumn tableName="configuration">
<column name="ldap_password" type="VARCHAR(255)" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-userid" author="calvarinop">
<comment>Add new column to store ldap userid</comment>
<addColumn tableName="configuration">
<column name="ldap_userid" type="VARCHAR(255)" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-save-password-db"
author="calvarinop">
<comment>Add new column to store ldap passwords in database</comment>
@ -46,6 +52,7 @@
<column name="ldap_save_password_db" type="BOOLEAN" />
</addColumn>
</changeSet>
<changeSet id="add-new-column-ldap-auth-enabled" author="calvarinop">
<comment>Add new column to store ldap authentication enabled</comment>
<addColumn tableName="configuration">
@ -60,12 +67,14 @@
<column name="navalplan_user" type="BOOLEAN" />
</addColumn>
</changeSet>
<changeSet id="delete-constraint-not-null-user-password"
author="idiazt">
<comment>Delete constraint not null for user password</comment>
<dropNotNullConstraint tableName="user_table"
columnName="password" columnDataType="VARCHAR(255)" />
</changeSet>
<changeSet id="set-default-value-navalplan-user" author="idiazt">
<addDefaultValue tableName="user_table"
columnName="navalplan_user"
@ -75,6 +84,7 @@
defaultNullValue="TRUE"
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="set-default-value-ldap-save-password-db" author="idiazt">
<addDefaultValue tableName="configuration"
columnName="ldap_save_password_db"
@ -84,6 +94,7 @@
defaultNullValue="TRUE"
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="set-default-value-ldap-auth-enabled" author="idiazt">
<addDefaultValue tableName="configuration"
columnName="ldap_auth_enabled"
@ -93,4 +104,49 @@
defaultNullValue="FALSE"
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="add-new-column-ldap-save-roles-db" author="calvarinop">
<comment>Add new column to store ldap roles in database</comment>
<addColumn tableName="configuration">
<column name="ldap_save_roles_db" type="BOOLEAN" />
</addColumn>
<addDefaultValue tableName="configuration"
columnName="ldap_save_roles_db"
defaultValueBoolean="FALSE" />
<addNotNullConstraint tableName="configuration"
columnName="ldap_save_roles_db"
defaultNullValue="FALSE"
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="create-new-table-matching-roles" author="calvarinop">
<comment>Add table to store the matching between LDAP roles and LibrePlan roles</comment>
<createTable tableName="configuration_roles_ldap">
<column name="role_libreplan" type="VARCHAR(255)">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="role_ldap" type="VARCHAR(255)">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="id_configuration" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="role_matching_id" type="INTEGER">
<constraints nullable="false"/>
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="id_configuration" baseTableName="configuration_roles_ldap" constraintName="id_configuration_fkey" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="configuration" referencesUniqueColumn="false"/>
<comment>Add new column to store ldap group path</comment>
<addColumn tableName="configuration">
<column name="ldap_group_path" type="VARCHAR(255)" />
</addColumn>
<comment>Add new column to store ldap role property</comment>
<addColumn tableName="configuration">
<column name="ldap_role_property" type="VARCHAR(255)" />
</addColumn>
</changeSet>
</databaseChangeLog>

View file

@ -65,6 +65,7 @@
<property name="scenariosVisible" not-null="true"
column="scenarios_visible" />
<component name="ldapConfiguration" class="org.navalplanner.business.common.entities.LDAPConfiguration">
<property name="ldapHost" column="ldap_Host"/>
<property name="ldapPort" column="ldap_port"/>
@ -72,9 +73,25 @@
<property name="ldapUserDn" column="ldap_userdn"/>
<property name="ldapPassword" column="ldap_password"/>
<property name="ldapUserId" column="ldap_userid"/>
<property name="ldapGroupPath" column="ldap_group_path"/>
<property name="ldapRoleProperty" column="ldap_role_property"/>
<property name="ldapSavePasswordsDB" column="ldap_save_password_db" not-null="true"/>
<property name="ldapAuthEnabled" column="ldap_auth_enabled" not-null="true"/>
<property name="ldapSaveRolesDB" column="ldap_save_roles_db" not-null="true"/>
<list name="configurationRolesLdap" table="configuration_roles_ldap" lazy="false">
<key column="id_configuration" />
<list-index column="role_matching_id" />
<composite-element class="ConfigurationRolesLDAP">
<property name="roleLdap" column="role_ldap"
not-null="true" />
<property name="roleLibreplan" column="role_libreplan"
not-null="true" />
</composite-element>
</list>
</component>
</class>
</hibernate-mapping>
</hibernate-mapping>

View file

@ -27,7 +27,7 @@
<property name="navalplanUser" column="navalplan_user" not-null="true"/>
<!-- Index created in a database-object section -->
<set name="roles" table="roles_table">
<set name="roles" table="roles_table" lazy="false">
<key column="user_id"/>
<element>
<type name="org.hibernate.type.EnumType">

View file

@ -24,6 +24,7 @@ package org.navalplanner.web.common;
import static org.navalplanner.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
@ -31,15 +32,18 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.common.entities.Configuration;
import org.navalplanner.business.common.entities.ConfigurationRolesLDAP;
import org.navalplanner.business.common.entities.EntityNameEnum;
import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.entities.LDAPConfiguration;
import org.navalplanner.business.common.entities.ProgressType;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.users.entities.UserRole;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
@ -78,7 +82,8 @@ import org.zkoss.zul.api.Window;
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Cristina Alavrino Perez <cristina.alvarino@comtecsf.es>
* @author Cristina Alavarino Perez <cristina.alvarino@comtecsf.es>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*/
public class ConfigurationController extends GenericForwardComposer {
@ -111,6 +116,12 @@ public class ConfigurationController extends GenericForwardComposer {
private Map<EntityNameEnum, Boolean> mapOpenedGroups = new HashMap<EntityNameEnum, Boolean>();
private Component ldapRoles;
private UserRole roles;
private Grid configurationRoles;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
@ -137,6 +148,7 @@ public class ConfigurationController extends GenericForwardComposer {
scenariosVisible
.setTooltiptext(_("Scenarios must be enabled as more elements than master exist"));
}
showLdapRoles();
}
private void initializeProgressTypeList() {
@ -801,4 +813,84 @@ public class ConfigurationController extends GenericForwardComposer {
public void setLdapConfiguration(LDAPConfiguration ldapConfiguration) {
configurationModel.setLdapConfiguration(ldapConfiguration);
}
public void showLdapRoles() {
ldapRoles.setVisible(configurationModel.getLdapConfiguration()
.getLdapSaveRolesDB());
}
public RowRenderer getAllUserRolesRenderer() {
return new RowRenderer() {
@Override
public void render(Row row, Object data) throws Exception {
final UserRole role = (UserRole) data;
row.appendChild(new Label(role.getDisplayName()));
final Textbox tempTextbox = new Textbox();
Textbox textbox = Util.bind(tempTextbox, new Util.Getter<String>() {
@Override
public String get() {
List<String> listRoles = configurationModel.
getLdapConfiguration().getMapMatchingRoles().get(role.name());
return StringUtils.join(listRoles, ";");
}
}, new Util.Setter<String>() {
@Override
public void set(String value) {
Map<String, List<String>> mapRoles = configurationModel
.getLdapConfiguration()
.getMapMatchingRoles();
mapRoles.put(role.name(),
Arrays
.asList(StringUtils.split(value)));
// Add the list of roles to the configuration
// getting the values from map
List<ConfigurationRolesLDAP> oldRoles = configurationModel
.getLdapConfiguration()
.getConfigurationRolesLdap();
List<ConfigurationRolesLDAP> newRoles = new ArrayList<ConfigurationRolesLDAP>();
for (String roleLdap : mapRoles.get(role.name())) {
ConfigurationRolesLDAP configurationRoleLdap = new ConfigurationRolesLDAP();
configurationRoleLdap.setRoleLdap(roleLdap);
configurationRoleLdap.setRoleLibreplan(role
.name());
newRoles.add(configurationRoleLdap);
}
for (ConfigurationRolesLDAP oldRole : oldRoles) {
boolean isRoleAdded = false;
if (oldRole.getRoleLibreplan().equals(
role.name()))
isRoleAdded = true;
for (ConfigurationRolesLDAP addedRole : newRoles) {
if (addedRole.getRoleLibreplan()
.equals(oldRole
.getRoleLibreplan())
&& addedRole.getRoleLdap()
.equals(oldRole
.getRoleLdap())) {
isRoleAdded = true;
}
}
if (!isRoleAdded)
newRoles.add(oldRole);
}
configurationModel.getLdapConfiguration()
.setConfigurationRolesLdap(newRoles);
}
});
textbox.setWidth("300px");
row.appendChild(textbox);
}
};
}
public UserRole[] getRoles() {
return roles.values();
}
public void setRoles(UserRole roles) {
this.roles = roles;
}
}

View file

@ -18,15 +18,27 @@
*/
package org.navalplanner.web.users.services;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.daos.IConfigurationDAO;
import org.navalplanner.business.common.entities.ConfigurationRolesLDAP;
import org.navalplanner.business.common.entities.LDAPConfiguration;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.users.daos.IUserDAO;
import org.navalplanner.business.users.entities.User;
import org.navalplanner.business.users.entities.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.EqualsFilter;
@ -180,40 +192,66 @@ public class LDAPCustomAuthenticationProvider extends
userNavalplan.setPassword(encodedPassword);
userNavalplan.setNavalplanUser(false);
userNavalplan.setDisabled(false);
userNavalplan.addRole(UserRole.ROLE_ADMINISTRATION);
List<String> roles = getMatchedRoles(
configuration, ldapTemplate, username);
for (String role : roles) {
userNavalplan.addRole(UserRole.valueOf(
UserRole.class, role));
}
transactionService
.runOnTransaction(new IOnTransaction() {
.runOnTransaction(new IOnTransaction<Void>() {
@Override
public Object execute() {
public Void execute() {
userDAO.save(userNavalplan);
return true;
return null;
}
});
} else {
// user exists in NavalPlan
// We must match the LDAPRoles with
// LibrePlanRoles
// The user must have the roles from LDAP
if (configuration.getLdapSaveRolesDB()) {
List<String> roles = getMatchedRoles(
configuration, ldapTemplate, username);
for (String role : roles) {
if (!user.getRoles().contains(
UserRole.valueOf(UserRole.class,
role))) {
user.addRole(UserRole.valueOf(
UserRole.class, role));
}
}
Set<UserRole> oldRoles = new HashSet<UserRole>();
oldRoles.addAll(user.getRoles());
for (UserRole role : oldRoles) {
if (!roles.contains(role.name())) {
user.removeRole(role);
}
}
}
if (configuration.isLdapSavePasswordsDB()) {
// We must test if user had password in
// database,
// because the configuration
// database, because the configuration
// of importing passwords could be changed after
// the
// import of the user
// so the password could be null in database.
// the import of the user so the password could
// be null in database.
if (null == user.getPassword()
|| !(user.getPassword()
.equals(encodedPassword))) {
user.setPassword(encodedPassword);
final User userNavalplan = user;
transactionService
.runOnTransaction(new IOnTransaction() {
@Override
public Object execute() {
userDAO.save(userNavalplan);
return true;
}
});
}
}
final User userNavalplan = user;
transactionService
.runOnTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
userDAO.save(userNavalplan);
return null;
}
});
}
// Gets and returns user from DB once authenticated
// against
@ -259,6 +297,62 @@ public class LDAPCustomAuthenticationProvider extends
.getPassword()));
}
private List<String> getMatchedRoles(LDAPConfiguration configuration,
LdapTemplate ldapTemplate, String username) {
final LDAPConfiguration ldapConfig = configuration;
String groupsPath = configuration.getLdapGroupPath();
String roleProperty = configuration.getLdapRoleProperty();
List<ConfigurationRolesLDAP> rolesLdap = configuration
.getConfigurationRolesLdap();
List<String> rolesReturn = new ArrayList<String>();
if (null == groupsPath || groupsPath.isEmpty()) {
// The LDAP has a node strategy for groups,
// we must check the roleProperty in user node.
for (ConfigurationRolesLDAP roleLDAP : rolesLdap) {
// We must make a search for each role-matching in nodes
List resultsSearch = ldapTemplate.search(
DistinguishedName.EMPTY_PATH,
new EqualsFilter(
roleProperty, roleLDAP.getRoleLdap())
.toString(), new AttributesMapper() {
@Override
public Object mapFromAttributes(
Attributes attributes)
throws NamingException {
return attributes.get(ldapConfig
.getLdapUserId());
}
});
for (Object resultsIter : resultsSearch) {
Attribute atrib = (Attribute) resultsIter;
if (atrib.contains(username)) {
rolesReturn.add(roleLDAP.getRoleLibreplan());
}
}
}
} else {
// The LDAP has a branch strategy for groups
// we must check if the user is in one of the groups.
for (ConfigurationRolesLDAP roleLdap : rolesLdap) {
// We must make a search for each role matching
DirContextAdapter adapter = (DirContextAdapter) ldapTemplate
.lookup(roleLdap.getRoleLdap() + "," + groupsPath);
if (adapter.attributeExists(roleProperty)) {
Attributes atrs = adapter.getAttributes();
if (atrs.get(roleProperty).contains(username)) {
rolesReturn.add(roleLdap.getRoleLibreplan());
}
}
}
}
return rolesReturn;
}
public DBPasswordEncoderService getPasswordEncoderService() {
return passwordEncoderService;
}

View file

@ -250,64 +250,133 @@
</tabpanel>
<tabpanel id="panelLDAPConfiguration">
<grid>
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label value="${i18n:_('Host:')}" />
<hbox>
<textbox id="ldapHost" value="@{configurationController.ldapConfiguration.ldapHost}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'ldap://localhost')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Port:')}" />
<hbox>
<textbox id="ldapPort" value="@{configurationController.ldapConfiguration.ldapPort}" width="300px"/>
<label value="${i18n:__('Example: {0}', '389')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Base:')}" />
<hbox>
<textbox id="ldapBase" value="@{configurationController.ldapConfiguration.ldapBase}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'dc=example,dc=org')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('UserDn:')}" />
<hbox>
<textbox id="ldapUserDn" value="@{configurationController.ldapConfiguration.ldapUserDn}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'cn=admin,dc=example,dc=org')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('UserId:')}" />
<hbox>
<textbox id="ldapUserId" value="@{configurationController.ldapConfiguration.ldapUserId}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'uid')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Password:')}" />
<textbox id="ldapPassword" value="@{configurationController.ldapConfiguration.ldapPassword}" type="password" width="300px"/>
</row>
<row>
<label value="${i18n:_('Save passwords in database')}" />
<checkbox id="ldapSavePasswordsDB" checked="@{configurationController.ldapConfiguration.ldapSavePasswordsDB}" />
</row>
<row>
<label value="${i18n:_('LDAP Authentication enabled')}" />
<checkbox id="ldapAuthEnabled" checked="@{configurationController.ldapConfiguration.ldapAuthEnabled}" />
</row>
</rows>
</grid>
<separator />
<button label="${i18n:_('Test LDAP connection')}"
onClick="configurationController.testLDAPConnection()" />
<!-- Activation -->
<groupbox style="margin-top: 5px" closable="false">
<caption label="${i18n:_('Activation')}" />
<label value="${i18n:_('LDAP Authentication enabled')}" />
<checkbox id="ldapAuthEnabled" checked="@{configurationController.ldapConfiguration.ldapAuthEnabled}" />
</groupbox>
<!-- Configuration -->
<groupbox style="margin-top: 5px" closable="false">
<caption label="${i18n:_('Configuration')}" />
<grid>
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label value="${i18n:_('Host:')}" />
<hbox>
<textbox id="ldapHost" value="@{configurationController.ldapConfiguration.ldapHost}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'ldap://localhost')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Port:')}" />
<hbox>
<textbox id="ldapPort" value="@{configurationController.ldapConfiguration.ldapPort}" width="300px"/>
<label value="${i18n:__('Example: {0}', '389')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Base:')}" />
<hbox>
<textbox id="ldapBase" value="@{configurationController.ldapConfiguration.ldapBase}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'dc=example,dc=org')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('UserDn:')}" />
<hbox>
<textbox id="ldapUserDn" value="@{configurationController.ldapConfiguration.ldapUserDn}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'cn=admin,dc=example,dc=org')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Password:')}" />
<textbox id="ldapPassword" value="@{configurationController.ldapConfiguration.ldapPassword}" type="password" width="300px"/>
</row>
</rows>
</grid>
<separator />
<button label="${i18n:_('Test LDAP connection')}"
onClick="configurationController.testLDAPConnection()" />
<separator />
</groupbox>
<!-- Authentication -->
<groupbox style="margin-top: 5px" closable="false">
<caption label="${i18n:_('Authentication')}" />
<grid>
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label value="${i18n:_('UserId:')}" />
<hbox>
<textbox id="ldapUserId" value="@{configurationController.ldapConfiguration.ldapUserId}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'uid')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Save passwords in database')}" />
<checkbox id="ldapSavePasswordsDB" checked="@{configurationController.ldapConfiguration.ldapSavePasswordsDB}" />
</row>
<row>
</row>
</rows>
</grid>
</groupbox>
<!-- Authorization -->
<groupbox style="margin-top: 5px" closable="false">
<caption label="${i18n:_('Authorization')}" />
<grid>
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label value="${i18n:_('Import LDAP roles')}" />
<checkbox id="ldapSaveRolesDB" checked="@{configurationController.ldapConfiguration.ldapSaveRolesDB}" onCheck="configurationController.showLdapRoles()"/>
</row>
<row>
<label value="${i18n:_('Group path:')}" />
<hbox>
<textbox id="ldapGroupPath" value="@{configurationController.ldapConfiguration.ldapGroupPath}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'ou=devel,ou=groups (If it is empty, a node strategy is used.)')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Role property:')}" />
<hbox>
<textbox id="ldapRoleProperty" value="@{configurationController.ldapConfiguration.ldapRoleProperty}" width="300px"/>
<label value="${i18n:__('Example: {0}', 'memberUid')}" />
</hbox>
</row>
</rows>
</grid>
<separator />
<separator />
<vbox id="ldapRoles" visible="false">
<grid id="configurationRoles"
model="@{configurationController.roles}"
rowRenderer="@{configurationController.allUserRolesRenderer}"
mold="paging" pageSize="10" fixedLayout="true">
<columns>
<column label="${i18n:_('Role DB')}" width="200px" />
<column label="${i18n:_('LDAP Roles')}" />
</columns>
</grid>
</vbox>
</groupbox>
</tabpanel>
</tabpanels>
</tabbox>