GUACAMOLE-957: Define all default LDAP configuration values in central location.

This commit is contained in:
Michael Jumper
2021-10-21 15:59:00 -07:00
parent f322dc3f3e
commit 160d29df95
4 changed files with 276 additions and 108 deletions

View File

@@ -0,0 +1,144 @@
/*
* 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.guacamole.auth.ldap.conf;
import java.util.Collections;
import java.util.List;
import org.apache.directory.api.ldap.model.filter.ExprNode;
import org.apache.directory.api.ldap.model.filter.PresenceNode;
import org.apache.directory.api.ldap.model.message.AliasDerefMode;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleServerException;
/**
* LDAPConfiguration implementation that returns the default values for all
* configuration parameters. For any configuration parameters that are
* required (such as {@link #getUserBaseDN()}), an exception is thrown.
*/
public class DefaultLDAPConfiguration implements LDAPConfiguration {
@Override
public String appliesTo(String username) {
return null;
}
@Override
public String getServerHostname() {
return "localhost";
}
@Override
public int getServerPort() {
return getEncryptionMethod().DEFAULT_PORT;
}
@Override
public List<String> getUsernameAttributes() {
return Collections.singletonList("uid");
}
@Override
public Dn getUserBaseDN() throws GuacamoleException {
throw new GuacamoleServerException("All LDAP servers must have a defined user base DN.");
}
@Override
public Dn getConfigurationBaseDN() {
return null;
}
@Override
public List<String> getGroupNameAttributes() {
return Collections.singletonList("cn");
}
@Override
public Dn getGroupBaseDN() {
return null;
}
@Override
public String getSearchBindDN() {
return null;
}
@Override
public String getSearchBindPassword() {
return null;
}
@Override
public EncryptionMethod getEncryptionMethod() {
return EncryptionMethod.NONE;
}
@Override
public int getMaxResults() {
return 1000;
}
@Override
public AliasDerefMode getDereferenceAliases() {
return AliasDerefMode.NEVER_DEREF_ALIASES;
}
@Override
public boolean getFollowReferrals() {
return false;
}
@Override
public int getMaxReferralHops() {
return 5;
}
@Override
public ExprNode getUserSearchFilter() {
return new PresenceNode("objectClass");
}
@Override
public ExprNode getGroupSearchFilter() {
return new PresenceNode("objectClass");
}
@Override
public int getOperationTimeout() {
return 30;
}
@Override
public List<String> getAttributes() {
return Collections.<String>emptyList();
}
@Override
public String getMemberAttribute() {
return "member";
}
@Override
public MemberAttributeType getMemberAttributeType()
throws GuacamoleException {
return MemberAttributeType.DN;
}
}

View File

@@ -19,10 +19,8 @@
package org.apache.guacamole.auth.ldap.conf;
import java.util.Collections;
import java.util.List;
import org.apache.directory.api.ldap.model.filter.ExprNode;
import org.apache.directory.api.ldap.model.filter.PresenceNode;
import org.apache.directory.api.ldap.model.message.AliasDerefMode;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.guacamole.GuacamoleException;
@@ -39,6 +37,11 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
*/
private final Environment environment;
/**
* The default configuration options for all parameters.
*/
private static final LDAPConfiguration DEFAULT = new DefaultLDAPConfiguration();
/**
* Creates a new EnvironmentLDAPConfiguration that reads its configuration
* details from guacamole.properties, as exposed by the given Environment.
@@ -59,7 +62,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public String getServerHostname() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_HOSTNAME,
"localhost"
DEFAULT.getServerHostname()
);
}
@@ -75,7 +78,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public List<String> getUsernameAttributes() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_USERNAME_ATTRIBUTE,
Collections.singletonList("uid")
DEFAULT.getUsernameAttributes()
);
}
@@ -89,7 +92,8 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
@Override
public Dn getConfigurationBaseDN() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_CONFIG_BASE_DN
LDAPGuacamoleProperties.LDAP_CONFIG_BASE_DN,
DEFAULT.getConfigurationBaseDN()
);
}
@@ -97,28 +101,31 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public List<String> getGroupNameAttributes() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_GROUP_NAME_ATTRIBUTE,
Collections.singletonList("cn")
DEFAULT.getGroupNameAttributes()
);
}
@Override
public Dn getGroupBaseDN() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_GROUP_BASE_DN
LDAPGuacamoleProperties.LDAP_GROUP_BASE_DN,
DEFAULT.getGroupBaseDN()
);
}
@Override
public String getSearchBindDN() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_SEARCH_BIND_DN
LDAPGuacamoleProperties.LDAP_SEARCH_BIND_DN,
DEFAULT.getSearchBindDN()
);
}
@Override
public String getSearchBindPassword() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_SEARCH_BIND_PASSWORD
LDAPGuacamoleProperties.LDAP_SEARCH_BIND_PASSWORD,
DEFAULT.getSearchBindPassword()
);
}
@@ -126,7 +133,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public EncryptionMethod getEncryptionMethod() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_ENCRYPTION_METHOD,
EncryptionMethod.NONE
DEFAULT.getEncryptionMethod()
);
}
@@ -134,7 +141,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public int getMaxResults() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_MAX_SEARCH_RESULTS,
1000
DEFAULT.getMaxResults()
);
}
@@ -142,7 +149,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public AliasDerefMode getDereferenceAliases() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_DEREFERENCE_ALIASES,
AliasDerefMode.NEVER_DEREF_ALIASES
DEFAULT.getDereferenceAliases()
);
}
@@ -150,7 +157,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public boolean getFollowReferrals() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_FOLLOW_REFERRALS,
false
DEFAULT.getFollowReferrals()
);
}
@@ -158,7 +165,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public int getMaxReferralHops() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_MAX_REFERRAL_HOPS,
5
DEFAULT.getMaxReferralHops()
);
}
@@ -166,7 +173,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public ExprNode getUserSearchFilter() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_USER_SEARCH_FILTER,
new PresenceNode("objectClass")
DEFAULT.getUserSearchFilter()
);
}
@@ -174,7 +181,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public ExprNode getGroupSearchFilter() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_GROUP_SEARCH_FILTER,
new PresenceNode("objectClass")
DEFAULT.getGroupSearchFilter()
);
}
@@ -182,7 +189,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public int getOperationTimeout() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_OPERATION_TIMEOUT,
30
DEFAULT.getOperationTimeout()
);
}
@@ -190,7 +197,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public List<String> getAttributes() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_USER_ATTRIBUTES,
Collections.<String>emptyList()
DEFAULT.getAttributes()
);
}
@@ -198,7 +205,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
public String getMemberAttribute() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_MEMBER_ATTRIBUTE,
"member"
DEFAULT.getMemberAttribute()
);
}
@@ -207,7 +214,7 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_MEMBER_ATTRIBUTE_TYPE,
MemberAttributeType.DN
DEFAULT.getMemberAttributeType()
);
}

View File

@@ -22,16 +22,13 @@ package org.apache.guacamole.auth.ldap.conf;
import com.fasterxml.jackson.annotation.JsonFormat;
import static com.fasterxml.jackson.annotation.JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.directory.api.ldap.model.filter.ExprNode;
import org.apache.directory.api.ldap.model.filter.PresenceNode;
import org.apache.directory.api.ldap.model.message.AliasDerefMode;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleServerException;
/**
* LDAPConfiguration implementation that is annotated for deserialization by
@@ -190,6 +187,72 @@ public class JacksonLDAPConfiguration implements LDAPConfiguration {
@JsonProperty("member-attribute-type")
private String memberAttributeType;
/**
* The default configuration options for all parameters.
*/
private static final LDAPConfiguration DEFAULT = new DefaultLDAPConfiguration();
/**
* Returns the given value, if non-null. If null, the given default value
* is returned.
*
* @param <T>
* The type of value accepted and returned.
*
* @param value
* The possibly null value to return if non-null.
*
* @param defaultValue
* The value to return if the provided value is null.
*
* @return
* The provided value, if non-null, otherwise the provided default
* value.
*/
private <T> T withDefault(T value, T defaultValue) {
return value != null ? value : defaultValue;
}
/**
* Returns the given Integer value as an int, if non-null. If null, the
* given int default value is returned. This function is an Integer-specific
* variant of {@link #withDefault(java.lang.Object, java.lang.Object)}
* which avoids unnecessary boxing/unboxing.
*
* @param value
* The possibly null value to return if non-null.
*
* @param defaultValue
* The value to return if the provided value is null.
*
* @return
* The provided value, if non-null, otherwise the provided default
* value.
*/
private int withDefault(Integer value, int defaultValue) {
return value != null ? value : defaultValue;
}
/**
* Returns the given Boolean value as an boolean, if non-null. If null, the
* given boolean default value is returned. This function is a Boolean-
* specific variant of {@link #withDefault(java.lang.Object, java.lang.Object)}
* which avoids unnecessary boxing/unboxing.
*
* @param value
* The possibly null value to return if non-null.
*
* @param defaultValue
* The value to return if the provided value is null.
*
* @return
* The provided value, if non-null, otherwise the provided default
* value.
*/
private boolean withDefault(Boolean value, boolean defaultValue) {
return value != null ? value : defaultValue;
}
@Override
public String appliesTo(String username) throws GuacamoleException {
@@ -204,140 +267,104 @@ public class JacksonLDAPConfiguration implements LDAPConfiguration {
}
@Override
public String getServerHostname() {
return hostname != null ? hostname : "localhost";
public String getServerHostname() throws GuacamoleException {
return withDefault(hostname, DEFAULT.getServerHostname());
}
@Override
public int getServerPort() throws GuacamoleException {
return port != null ? port : getEncryptionMethod().DEFAULT_PORT;
return withDefault(port, getEncryptionMethod().DEFAULT_PORT);
}
@Override
public List<String> getUsernameAttributes() {
return usernameAttributes != null ? usernameAttributes : Collections.singletonList("uid");
public List<String> getUsernameAttributes() throws GuacamoleException {
return withDefault(usernameAttributes, DEFAULT.getUsernameAttributes());
}
@Override
public Dn getUserBaseDN() throws GuacamoleException {
Dn parsedDn = LDAPGuacamoleProperties.LDAP_USER_BASE_DN.parseValue(userBaseDn);
if (parsedDn == null)
throw new GuacamoleServerException("The \"user-base-dn\" property is required for all LDAP servers.");
return parsedDn;
return withDefault(LDAPGuacamoleProperties.LDAP_USER_BASE_DN.parseValue(userBaseDn), DEFAULT.getUserBaseDN());
}
@Override
public Dn getConfigurationBaseDN() throws GuacamoleException {
return LDAPGuacamoleProperties.LDAP_CONFIG_BASE_DN.parseValue(configBaseDn);
return withDefault(LDAPGuacamoleProperties.LDAP_CONFIG_BASE_DN.parseValue(configBaseDn), DEFAULT.getConfigurationBaseDN());
}
@Override
public List<String> getGroupNameAttributes() throws GuacamoleException {
return groupNameAttributes != null ? groupNameAttributes : Collections.singletonList("cn");
return withDefault(groupNameAttributes, DEFAULT.getGroupNameAttributes());
}
@Override
public Dn getGroupBaseDN() throws GuacamoleException {
return LDAPGuacamoleProperties.LDAP_GROUP_BASE_DN.parseValue(groupBaseDn);
return withDefault(LDAPGuacamoleProperties.LDAP_GROUP_BASE_DN.parseValue(groupBaseDn), DEFAULT.getGroupBaseDN());
}
@Override
public String getSearchBindDN() throws GuacamoleException {
return searchBindDn;
return withDefault(searchBindDn, DEFAULT.getSearchBindDN());
}
@Override
public String getSearchBindPassword() throws GuacamoleException {
return searchBindPassword;
return withDefault(searchBindPassword, DEFAULT.getSearchBindDN());
}
@Override
public EncryptionMethod getEncryptionMethod() throws GuacamoleException {
EncryptionMethod parsedMethod = LDAPGuacamoleProperties.LDAP_ENCRYPTION_METHOD.parseValue(encryptionMethod);
if (parsedMethod == null)
return EncryptionMethod.NONE;
return parsedMethod;
return withDefault(LDAPGuacamoleProperties.LDAP_ENCRYPTION_METHOD.parseValue(encryptionMethod), DEFAULT.getEncryptionMethod());
}
@Override
public int getMaxResults() throws GuacamoleException {
return maxSearchResults != null ? maxSearchResults : 1000;
return withDefault(maxSearchResults, DEFAULT.getMaxResults());
}
@Override
public AliasDerefMode getDereferenceAliases() throws GuacamoleException {
AliasDerefMode parsedMode = LDAPGuacamoleProperties.LDAP_DEREFERENCE_ALIASES.parseValue(dereferenceAliases);
if (parsedMode == null)
return AliasDerefMode.NEVER_DEREF_ALIASES;
return parsedMode;
return withDefault(LDAPGuacamoleProperties.LDAP_DEREFERENCE_ALIASES.parseValue(dereferenceAliases), DEFAULT.getDereferenceAliases());
}
@Override
public boolean getFollowReferrals() throws GuacamoleException {
return followReferrals != null ? followReferrals : false;
return withDefault(followReferrals, DEFAULT.getFollowReferrals());
}
@Override
public int getMaxReferralHops() throws GuacamoleException {
return maxReferralHops != null ? maxReferralHops : 5;
return withDefault(maxReferralHops, DEFAULT.getMaxReferralHops());
}
@Override
public ExprNode getUserSearchFilter() throws GuacamoleException {
ExprNode parsedFilter = LDAPGuacamoleProperties.LDAP_USER_SEARCH_FILTER.parseValue(userSearchFilter);
if (parsedFilter == null)
return new PresenceNode("objectClass");
return parsedFilter;
return withDefault(LDAPGuacamoleProperties.LDAP_USER_SEARCH_FILTER.parseValue(userSearchFilter), DEFAULT.getUserSearchFilter());
}
@Override
public ExprNode getGroupSearchFilter() throws GuacamoleException {
ExprNode parsedFilter = LDAPGuacamoleProperties.LDAP_GROUP_SEARCH_FILTER.parseValue(groupSearchFilter);
if (parsedFilter == null)
return new PresenceNode("objectClass");
return parsedFilter;
return withDefault(LDAPGuacamoleProperties.LDAP_GROUP_SEARCH_FILTER.parseValue(groupSearchFilter), DEFAULT.getGroupSearchFilter());
}
@Override
public int getOperationTimeout() throws GuacamoleException {
return operationTimeout != null ? operationTimeout : 30;
return withDefault(operationTimeout, DEFAULT.getOperationTimeout());
}
@Override
public List<String> getAttributes() throws GuacamoleException {
return userAttributes != null ? userAttributes : Collections.<String>emptyList();
return withDefault(userAttributes, DEFAULT.getAttributes());
}
@Override
public String getMemberAttribute() throws GuacamoleException {
return memberAttribute != null ? memberAttribute : "member";
return withDefault(memberAttribute, DEFAULT.getMemberAttribute());
}
@Override
public MemberAttributeType getMemberAttributeType()
throws GuacamoleException {
MemberAttributeType parsedType = LDAPGuacamoleProperties.LDAP_MEMBER_ATTRIBUTE_TYPE.parseValue(memberAttributeType);
if (parsedType == null)
return MemberAttributeType.DN;
return parsedType;
return withDefault(LDAPGuacamoleProperties.LDAP_MEMBER_ATTRIBUTE_TYPE.parseValue(memberAttributeType), DEFAULT.getMemberAttributeType());
}
}

View File

@@ -49,8 +49,7 @@ public interface LDAPConfiguration {
String appliesTo(String username) throws GuacamoleException;
/**
* Returns the hostname or IP address of the LDAP server. By default, this
* will be "localhost".
* Returns the hostname or IP address of the LDAP server.
*
* @return
* The hostname or IP address of the LDAP server.
@@ -76,8 +75,7 @@ public interface LDAPConfiguration {
/**
* Returns all username attributes which should be used to query and bind
* users using the LDAP directory. By default, this will be "uid" - a
* common attribute used for this purpose.
* users using the LDAP directory.
*
* @return
* The username attributes which should be used to query and bind users
@@ -118,7 +116,7 @@ public interface LDAPConfiguration {
/**
* Returns all attributes which should be used to determine the unique
* identifier of each user group. By default, this will be "cn".
* identifier of each user group.
*
* @return
* The attributes which should be used to determine the unique
@@ -175,7 +173,7 @@ public interface LDAPConfiguration {
/**
* Returns the encryption method that should be used when connecting to the
* LDAP server. By default, no encryption is used.
* LDAP server.
*
* @return
* The encryption method that should be used when connecting to the
@@ -187,8 +185,7 @@ public interface LDAPConfiguration {
EncryptionMethod getEncryptionMethod() throws GuacamoleException;
/**
* Returns maximum number of results a LDAP query can return. By default,
* this will be 1000.
* Returns maximum number of results a LDAP query can return.
*
* @return
* The maximum number of results a LDAP query can return.
@@ -199,8 +196,7 @@ public interface LDAPConfiguration {
int getMaxResults() throws GuacamoleException;
/**
* Returns whether or not LDAP aliases will be dereferenced. By default,
* aliases are never dereferenced.
* Returns whether or not LDAP aliases will be dereferenced.
*
* @return
* The LDAP alias dereferencing mode.
@@ -211,8 +207,7 @@ public interface LDAPConfiguration {
AliasDerefMode getDereferenceAliases() throws GuacamoleException;
/**
* Returns whether referrals should be automatically followed. By default,
* referrals are not followed.
* Returns whether referrals should be automatically followed.
*
* @return
* Whether referrals should be followed.
@@ -224,8 +219,7 @@ public interface LDAPConfiguration {
boolean getFollowReferrals() throws GuacamoleException;
/**
* Returns the maximum number of referral hops to follow. By default
* a maximum of 5 hops is allowed.
* Returns the maximum number of referral hops to follow.
*
* @return
* The maximum number of referral hops to follow.
@@ -237,13 +231,11 @@ public interface LDAPConfiguration {
/**
* Returns the search filter that should be used when querying the
* LDAP server for Guacamole users. If no filter is specified,
* a default of "(objectClass=user)" is returned.
* LDAP server for Guacamole users.
*
* @return
* The search filter that should be used when querying the
* LDAP server for users that are valid in Guacamole, or
* "(objectClass=user)" if not specified.
* LDAP server for users that are valid in Guacamole.
*
* @throws GuacamoleException
* If the user search filter cannot be retrieved.
@@ -252,13 +244,11 @@ public interface LDAPConfiguration {
/**
* Returns the search filter that should be used when querying the
* LDAP server for Guacamole groups. If no filter is specified,
* a default of "(objectClass=*)" is used.
* LDAP server for Guacamole groups.
*
* @return
* The search filter that should be used when querying the
* LDAP server for groups that are valid in Guacamole, or
* "(objectClass=*)" if not specified.
* LDAP server for groups that are valid in Guacamole.
*
* @throws GuacamoleException
* If the group search filter cannot be retrieved.
@@ -277,22 +267,22 @@ public interface LDAPConfiguration {
int getOperationTimeout() throws GuacamoleException;
/**
* Returns names for custom LDAP user attributes that should be made
* available as parameter tokens. By default, no additional LDAP attributes
* will be exposed as parameter tokens.
* Returns names of any LDAP user attributes that should be made available
* as parameter tokens.
*
* @return
* A list of all LDAP user attributes that should be made available as
* parameter tokens.
*
* @throws GuacamoleException
* If the names of custom LDAP user attributes cannot be retrieved.
* If the names of the LDAP user attributes to be exposed as parameter
* tokens cannot be retrieved.
*/
List<String> getAttributes() throws GuacamoleException;
/**
* Returns the name of the LDAP attribute used to enumerate members in a
* group. By default, this will be "member".
* group.
*
* @return
* The name of the LDAP attribute to use to enumerate