diff --git a/extensions/guacamole-auth-json/src/main/java/org/apache/guacamole/auth/json/ConfigurationService.java b/extensions/guacamole-auth-json/src/main/java/org/apache/guacamole/auth/json/ConfigurationService.java index 1483f6fcbd..2705e61ed3 100644 --- a/extensions/guacamole-auth-json/src/main/java/org/apache/guacamole/auth/json/ConfigurationService.java +++ b/extensions/guacamole-auth-json/src/main/java/org/apache/guacamole/auth/json/ConfigurationService.java @@ -25,7 +25,7 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.properties.ByteArrayProperty; -import org.apache.guacamole.properties.StringListProperty; +import org.apache.guacamole.properties.StringGuacamoleProperty; /** * Service for retrieving configuration information regarding the JSON @@ -56,7 +56,7 @@ public String getName() { * be allowed to perform authentication. If not specified, ALL address will * be allowed. */ - private static final StringListProperty JSON_TRUSTED_NETWORKS = new StringListProperty() { + private static final StringGuacamoleProperty JSON_TRUSTED_NETWORKS = new StringGuacamoleProperty() { @Override public String getName() { @@ -95,7 +95,7 @@ public byte[] getSecretKey() throws GuacamoleException { * If guacamole.properties cannot be parsed. */ public Collection getTrustedNetworks() throws GuacamoleException { - return environment.getProperty(JSON_TRUSTED_NETWORKS, Collections.emptyList()); + return environment.getPropertyCollection(JSON_TRUSTED_NETWORKS, Collections.emptyList()); } } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java index 654b403c34..f84712c7ff 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java @@ -330,7 +330,7 @@ private Map getAttributeTokens(ConnectedLDAPConfiguration config throws GuacamoleException { // Get attributes from configuration information - List attrList = config.getAttributes(); + Collection attrList = config.getAttributes(); // If there are no attributes there is no reason to search LDAP if (attrList.isEmpty()) diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConnectedLDAPConfiguration.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConnectedLDAPConfiguration.java index 493cafcb7c..c41114c027 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConnectedLDAPConfiguration.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConnectedLDAPConfiguration.java @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.ldap; +import java.util.Collection; import java.util.List; import org.apache.directory.api.ldap.model.filter.ExprNode; import org.apache.directory.api.ldap.model.message.AliasDerefMode; @@ -124,7 +125,7 @@ public int getServerPort() throws GuacamoleException { } @Override - public List getUsernameAttributes() throws GuacamoleException { + public Collection getUsernameAttributes() throws GuacamoleException { return config.getUsernameAttributes(); } @@ -139,7 +140,7 @@ public Dn getConfigurationBaseDN() throws GuacamoleException { } @Override - public List getGroupNameAttributes() throws GuacamoleException { + public Collection getGroupNameAttributes() throws GuacamoleException { return config.getGroupNameAttributes(); } @@ -209,7 +210,7 @@ public int getNetworkTimeout() throws GuacamoleException { } @Override - public List getAttributes() throws GuacamoleException { + public Collection getAttributes() throws GuacamoleException { return config.getAttributes(); } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/EnvironmentLDAPConfiguration.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/EnvironmentLDAPConfiguration.java index 9fb44a1fad..5ffeb203b8 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/EnvironmentLDAPConfiguration.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/EnvironmentLDAPConfiguration.java @@ -19,7 +19,7 @@ package org.apache.guacamole.auth.ldap.conf; -import java.util.List; +import java.util.Collection; import org.apache.directory.api.ldap.model.filter.ExprNode; import org.apache.directory.api.ldap.model.message.AliasDerefMode; import org.apache.directory.api.ldap.model.name.Dn; @@ -75,8 +75,8 @@ public int getServerPort() throws GuacamoleException { } @Override - public List getUsernameAttributes() throws GuacamoleException { - return environment.getProperty( + public Collection getUsernameAttributes() throws GuacamoleException { + return environment.getPropertyCollection( LDAPGuacamoleProperties.LDAP_USERNAME_ATTRIBUTE, DEFAULT.getUsernameAttributes() ); @@ -98,8 +98,8 @@ public Dn getConfigurationBaseDN() throws GuacamoleException { } @Override - public List getGroupNameAttributes() throws GuacamoleException { - return environment.getProperty( + public Collection getGroupNameAttributes() throws GuacamoleException { + return environment.getPropertyCollection( LDAPGuacamoleProperties.LDAP_GROUP_NAME_ATTRIBUTE, DEFAULT.getGroupNameAttributes() ); @@ -210,8 +210,8 @@ public int getNetworkTimeout() throws GuacamoleException { } @Override - public List getAttributes() throws GuacamoleException { - return environment.getProperty( + public Collection getAttributes() throws GuacamoleException { + return environment.getPropertyCollection( LDAPGuacamoleProperties.LDAP_USER_ATTRIBUTES, DEFAULT.getAttributes() ); diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/JacksonLDAPConfiguration.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/JacksonLDAPConfiguration.java index 01d58a3e4b..bddccd871f 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/JacksonLDAPConfiguration.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/JacksonLDAPConfiguration.java @@ -22,6 +22,7 @@ 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.Collection; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -331,7 +332,7 @@ public int getServerPort() throws GuacamoleException { } @Override - public List getUsernameAttributes() throws GuacamoleException { + public Collection getUsernameAttributes() throws GuacamoleException { return withDefault(usernameAttributes, defaultConfig::getUsernameAttributes); } @@ -348,7 +349,7 @@ public Dn getConfigurationBaseDN() throws GuacamoleException { } @Override - public List getGroupNameAttributes() throws GuacamoleException { + public Collection getGroupNameAttributes() throws GuacamoleException { return withDefault(groupNameAttributes, defaultConfig::getGroupNameAttributes); } @@ -424,7 +425,7 @@ public int getNetworkTimeout() throws GuacamoleException { } @Override - public List getAttributes() throws GuacamoleException { + public Collection getAttributes() throws GuacamoleException { return withDefault(userAttributes, defaultConfig::getAttributes); } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPConfiguration.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPConfiguration.java index 975631d027..e57049b26f 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPConfiguration.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPConfiguration.java @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.ldap.conf; +import java.util.Collection; import java.util.List; import org.apache.directory.api.ldap.model.filter.ExprNode; import org.apache.directory.api.ldap.model.message.AliasDerefMode; @@ -84,7 +85,7 @@ public interface LDAPConfiguration { * @throws GuacamoleException * If the username attributes cannot be retrieved. */ - List getUsernameAttributes() throws GuacamoleException; + Collection getUsernameAttributes() throws GuacamoleException; /** * Returns the base DN under which all Guacamole users will be stored @@ -125,7 +126,7 @@ public interface LDAPConfiguration { * @throws GuacamoleException * If the group name attributes cannot be retrieved. */ - List getGroupNameAttributes() throws GuacamoleException; + Collection getGroupNameAttributes() throws GuacamoleException; /** * Returns the base DN under which all Guacamole role based access control @@ -305,7 +306,7 @@ public interface LDAPConfiguration { * If the names of the LDAP user attributes to be exposed as parameter * tokens cannot be retrieved. */ - List getAttributes() throws GuacamoleException; + Collection getAttributes() throws GuacamoleException; /** * Returns the name of the LDAP attribute used to enumerate members in a diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java index cd0b724c0d..7349356b94 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java @@ -84,8 +84,8 @@ private LDAPGuacamoleProperties() {} * one attribute, and the concatenation of that attribute and the value of * LDAP_USER_BASE_DN must equal the user's full DN. */ - public static final StringListProperty LDAP_USERNAME_ATTRIBUTE = - new StringListProperty() { + public static final StringGuacamoleProperty LDAP_USERNAME_ATTRIBUTE = + new StringGuacamoleProperty() { @Override public String getName() { return "ldap-username-attribute"; } @@ -97,8 +97,8 @@ private LDAPGuacamoleProperties() {} * attributes must be present within each Guacamole user group's record in * the LDAP directory for that group to be visible. */ - public static final StringListProperty LDAP_GROUP_NAME_ATTRIBUTE = - new StringListProperty() { + public static final StringGuacamoleProperty LDAP_GROUP_NAME_ATTRIBUTE = + new StringGuacamoleProperty() { @Override public String getName() { return "ldap-group-name-attribute"; } @@ -277,8 +277,8 @@ private LDAPGuacamoleProperties() {} * Custom attribute or attributes to query from Guacamole user's record in * the LDAP directory. */ - public static final StringListProperty LDAP_USER_ATTRIBUTES = - new StringListProperty() { + public static final StringGuacamoleProperty LDAP_USER_ATTRIBUTES = + new StringGuacamoleProperty() { @Override public String getName() { return "ldap-user-attributes"; } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/StringListProperty.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/StringListProperty.java deleted file mode 100644 index f7057e9f61..0000000000 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/StringListProperty.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.Arrays; -import java.util.List; -import java.util.regex.Pattern; -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.properties.GuacamoleProperty; - -/** - * A GuacamoleProperty whose value is a List of Strings. The string value - * parsed to produce this list is a comma-delimited list. Duplicate values are - * ignored, as is any whitespace following delimiters. To maintain - * compatibility with the behavior of Java properties in general, only - * whitespace at the beginning of each value is ignored; trailing whitespace - * becomes part of the value. - */ -public abstract class StringListProperty implements GuacamoleProperty> { - - /** - * A pattern which matches against the delimiters between values. This is - * currently simply a comma and any following whitespace. Parts of the - * input string which match this pattern will not be included in the parsed - * result. - */ - private static final Pattern DELIMITER_PATTERN = Pattern.compile(",\\s*"); - - @Override - public List parseValue(String values) throws GuacamoleException { - - // If no property provided, return null. - if (values == null) - return null; - - // Split string into a list of individual values - List stringValues = Arrays.asList(DELIMITER_PATTERN.split(values)); - if (stringValues.isEmpty()) - return null; - - return stringValues; - - } - -} diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java index fa9fe15222..38fa33e7e8 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java @@ -183,7 +183,7 @@ public Dn deriveUserDN(LDAPConfiguration config, String username) throws GuacamoleException { // Pull username attributes from properties - List usernameAttributes = config.getUsernameAttributes(); + List usernameAttributes = new ArrayList<>(config.getUsernameAttributes()); // We need exactly one base DN to derive the user DN if (usernameAttributes.size() != 1) { diff --git a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/conf/ConfigurationService.java b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/conf/ConfigurationService.java index 11f11f3f85..e8e8fd34dd 100644 --- a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/conf/ConfigurationService.java @@ -20,10 +20,11 @@ package org.apache.guacamole.auth.quickconnect.conf; import com.google.inject.Inject; +import java.util.Collection; import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; -import org.apache.guacamole.properties.StringListProperty; +import org.apache.guacamole.properties.StringGuacamoleProperty; /** * Configuration options to control the QuickConnect module. @@ -42,7 +43,7 @@ public class ConfigurationService { * the parameters defined in this list. Defaults to null (all parameters * are allowed). */ - public static final StringListProperty QUICKCONNECT_ALLOWED_PARAMETERS = new StringListProperty() { + public static final StringGuacamoleProperty QUICKCONNECT_ALLOWED_PARAMETERS = new StringGuacamoleProperty() { @Override public String getName() { return "quickconnect-allowed-parameters"; } @@ -55,7 +56,7 @@ public class ConfigurationService { * except the ones defined in this list. Defaults to null (all parameters * are allowed). */ - public static final StringListProperty QUICKCONNECT_DENIED_PARAMETERS = new StringListProperty() { + public static final StringGuacamoleProperty QUICKCONNECT_DENIED_PARAMETERS = new StringGuacamoleProperty() { @Override public String getName() { return "quickconnect-denied-parameters"; } @@ -74,8 +75,8 @@ public class ConfigurationService { * @throws GuacamoleException * If guacamole.properties cannot be parsed. */ - public List getAllowedParameters() throws GuacamoleException { - return environment.getProperty(QUICKCONNECT_ALLOWED_PARAMETERS); + public Collection getAllowedParameters() throws GuacamoleException { + return environment.getPropertyCollection(QUICKCONNECT_ALLOWED_PARAMETERS); } /** @@ -90,8 +91,8 @@ public List getAllowedParameters() throws GuacamoleException { * @throws GuacamoleException * If guacamole.properties cannot be parsed. */ - public List getDeniedParameters() throws GuacamoleException { - return environment.getProperty(QUICKCONNECT_DENIED_PARAMETERS); + public Collection getDeniedParameters() throws GuacamoleException { + return environment.getPropertyCollection(QUICKCONNECT_DENIED_PARAMETERS); } } diff --git a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java index 32df742977..e71988e631 100644 --- a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java +++ b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java @@ -25,6 +25,7 @@ import java.net.URISyntaxException; import java.net.URLDecoder; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; @@ -60,13 +61,13 @@ public class QCParser { * by this parser. If not defined, all parameters will be allowed unless * explicitly denied. */ - private final List allowedParams; + private final Collection allowedParams; /** * The list of parameters that are explicitly denied from being placed into * a configuration by this parser. */ - private final List deniedParams; + private final Collection deniedParams; /** * Create a new instance of the QCParser class, with the provided allowed @@ -81,7 +82,7 @@ public class QCParser { * A list of parameters, if any, that should be explicitly denied from * being placed into a connection configuration. */ - public QCParser(List allowedParams, List deniedParams) { + public QCParser(Collection allowedParams, Collection deniedParams) { this.allowedParams = allowedParams; this.deniedParams = deniedParams; } diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java index bbfdea17e8..444bd7706b 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java @@ -21,13 +21,13 @@ import com.google.inject.Inject; import java.net.URI; +import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.properties.IntegerGuacamoleProperty; import org.apache.guacamole.properties.StringGuacamoleProperty; -import org.apache.guacamole.properties.StringListProperty; import org.apache.guacamole.properties.URIGuacamoleProperty; /** @@ -138,8 +138,8 @@ public class ConfigurationService { * The claims within any valid JWT that should be mapped to * the authenticated user's tokens, as configured with guacamole.properties. */ - private static final StringListProperty OPENID_ATTRIBUTES_CLAIM_TYPE = - new StringListProperty() { + private static final StringGuacamoleProperty OPENID_ATTRIBUTES_CLAIM_TYPE = + new StringGuacamoleProperty() { @Override public String getName() { return "openid-attributes-claim-type"; } }; @@ -356,8 +356,8 @@ public String getGroupsClaimType() throws GuacamoleException { * @throws GuacamoleException * If guacamole.properties cannot be parsed. */ - public List getAttributesClaimType() throws GuacamoleException { - return environment.getProperty(OPENID_ATTRIBUTES_CLAIM_TYPE, DEFAULT_ATTRIBUTES_CLAIM_TYPE); + public Collection getAttributesClaimType() throws GuacamoleException { + return environment.getPropertyCollection(OPENID_ATTRIBUTES_CLAIM_TYPE, DEFAULT_ATTRIBUTES_CLAIM_TYPE); } /** diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java index 2fad48ce4a..139ab2021b 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java @@ -20,6 +20,7 @@ package org.apache.guacamole.auth.openid.token; import com.google.inject.Inject; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -229,7 +230,7 @@ public Set processGroups(JwtClaims claims) throws GuacamoleException { * If guacamole.properties could not be parsed. */ public Map processAttributes(JwtClaims claims) throws GuacamoleException { - List attributesClaim = confService.getAttributesClaimType(); + Collection attributesClaim = confService.getAttributesClaimType(); if (claims != null && !attributesClaim.isEmpty()) { try { diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java index 984a68f343..fd3230b7d1 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java @@ -26,6 +26,7 @@ import java.net.URI; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; @@ -214,7 +215,7 @@ public String getUsername(String name) throws GuacamoleException { // Verify that the username is specified with one of the allowed // attributes - List usernameAttributes = confService.getSubjectUsernameAttributes(); + Collection usernameAttributes = confService.getSubjectUsernameAttributes(); if (usernameAttributes != null && !usernameAttributes.stream().anyMatch(nameRdn.getType()::equalsIgnoreCase)) throw new GuacamoleClientException("Subject DN \"" + dn + "\" " + "does not contain an acceptable username attribute."); diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/conf/ConfigurationService.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/conf/ConfigurationService.java index 48fc86b654..7931c0dad0 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/conf/ConfigurationService.java @@ -22,7 +22,7 @@ import com.google.inject.Inject; import java.net.URI; import java.net.URISyntaxException; -import java.util.List; +import java.util.Collection; import javax.naming.ldap.LdapName; import javax.ws.rs.core.UriBuilder; import org.apache.guacamole.GuacamoleException; @@ -30,7 +30,6 @@ import org.apache.guacamole.environment.Environment; import org.apache.guacamole.properties.IntegerGuacamoleProperty; import org.apache.guacamole.properties.StringGuacamoleProperty; -import org.apache.guacamole.properties.StringListProperty; import org.apache.guacamole.properties.URIGuacamoleProperty; /** @@ -146,8 +145,8 @@ public class ConfigurationService { * one of these attributes, the certificate will be rejected. By default, * any attribute is accepted. */ - private static final StringListProperty SSL_SUBJECT_USERNAME_ATTRIBUTE = - new StringListProperty () { + private static final StringGuacamoleProperty SSL_SUBJECT_USERNAME_ATTRIBUTE = + new StringGuacamoleProperty () { @Override public String getName() { return "ssl-subject-username-attribute"; } @@ -433,8 +432,8 @@ public LdapName getSubjectBaseDN() throws GuacamoleException { * @throws GuacamoleException * If the configured set of username attributes cannot be read. */ - public List getSubjectUsernameAttributes() throws GuacamoleException { - return environment.getProperty(SSL_SUBJECT_USERNAME_ATTRIBUTE); + public Collection getSubjectUsernameAttributes() throws GuacamoleException { + return environment.getPropertyCollection(SSL_SUBJECT_USERNAME_ATTRIBUTE); } } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/environment/DelegatingEnvironment.java b/guacamole-ext/src/main/java/org/apache/guacamole/environment/DelegatingEnvironment.java index cdaa924ea8..936612a214 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/environment/DelegatingEnvironment.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/environment/DelegatingEnvironment.java @@ -20,6 +20,7 @@ package org.apache.guacamole.environment; import java.io.File; +import java.util.Collection; import java.util.Map; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration; @@ -73,11 +74,35 @@ public Type getProperty(GuacamoleProperty property) throws Guacamol public Type getProperty(GuacamoleProperty property, Type defaultValue) throws GuacamoleException { return environment.getProperty(property, defaultValue); } + + @Override + public Collection getPropertyCollection(GuacamoleProperty property) + throws GuacamoleException { + return environment.getPropertyCollection(property); + } + + @Override + public Collection getPropertyCollection(GuacamoleProperty property, + Type defaultValue) throws GuacamoleException { + return environment.getPropertyCollection(property, defaultValue); + } + + @Override + public Collection getPropertyCollection(GuacamoleProperty property, + Collection defaultValue) throws GuacamoleException { + return environment.getPropertyCollection(property, defaultValue); + } @Override public Type getRequiredProperty(GuacamoleProperty property) throws GuacamoleException { return environment.getRequiredProperty(property); } + + @Override + public Collection getRequiredPropertyCollection(GuacamoleProperty property) + throws GuacamoleException { + return environment.getRequiredPropertyCollection(property); + } @Override public GuacamoleProxyConfiguration getDefaultGuacamoleProxyConfiguration() throws GuacamoleException { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/environment/Environment.java b/guacamole-ext/src/main/java/org/apache/guacamole/environment/Environment.java index c36b953ac8..22b95149bc 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/environment/Environment.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/environment/Environment.java @@ -21,6 +21,8 @@ import org.apache.guacamole.properties.GuacamoleProperties; import java.io.File; +import java.util.Collection; +import java.util.Collections; import java.util.Map; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleUnsupportedException; @@ -102,13 +104,18 @@ public interface Environment { * Given a GuacamoleProperty, parses and returns the value set for that * property in guacamole.properties, if any. * - * @param The type that the given property is parsed into. - * @param property The property to read from guacamole.properties. - * @return The parsed value of the property as read from - * guacamole.properties. - * @throws GuacamoleException If an error occurs while parsing the value - * for the given property in - * guacamole.properties. + * @param + * The type that the given property is parsed into. + * + * @param property + * The property to read from guacamole.properties. + * + * @return + * The parsed value of the property as read from guacamole.properties. + * + * @throws GuacamoleException + * If an error occurs while parsing the value for the given property in + * guacamole.properties. */ public Type getProperty(GuacamoleProperty property) throws GuacamoleException; @@ -118,20 +125,161 @@ public Type getProperty(GuacamoleProperty property) * property in guacamole.properties, if any. If no value is found, the * provided default value is returned. * - * @param The type that the given property is parsed into. - * @param property The property to read from guacamole.properties. - * @param defaultValue The value to return if no value was given in - * guacamole.properties. - * @return The parsed value of the property as read from - * guacamole.properties, or the provided default value if no value - * was found. - * @throws GuacamoleException If an error occurs while parsing the value - * for the given property in - * guacamole.properties. + * @param + * The type that the given property is parsed into. + * + * @param property + * The property to read from guacamole.properties. + * + * @param defaultValue + * The value to return if no value was given in guacamole.properties. + * + * @return + * The parsed value of the property as read from guacamole.properties, + * or the provided default value if no value was found. + * + * @throws GuacamoleException + * If an error occurs while parsing the value for the given property in + * guacamole.properties. */ public Type getProperty(GuacamoleProperty property, Type defaultValue) throws GuacamoleException; + /** + * Given a GuacamoleProperty, parses and returns a sorted Collection of the + * value set for that property in guacamole.properties, if any. The + * implementation of parsing and returning a collection of multiple + * values is up to the individual property implementations, and not all + * implementations will support reading and returning multiple values. + * + * @param + * The type that the given property is parsed into. + * + * @param property + * The property to read from guacamole.properties. + * + * @return + * A sorted collection of the the parsed values of the property as read + * from guacamole.properties. + * + * @throws GuacamoleException + * If an error occurs while parsing the value for the given property in + * guacamole.properties. + */ + public default Collection getPropertyCollection( + GuacamoleProperty property) throws GuacamoleException { + + /* Pull the given property as a string. */ + StringGuacamoleProperty stringProperty = new StringGuacamoleProperty() { + + @Override + public String getName() { return property.getName(); } + + }; + + /* Parse the string to a Collection of the desired type. */ + return property.parseValueCollection(getProperty(stringProperty)); + + } + + /** + * Given a GuacamoleProperty, parses and returns the value set for that + * property in guacamole.properties, if any. If no value is found, a + * Collection is returned with the provided default value. The + * implementation of parsing and returning a collection of multiple + * values is up to the individual property implementations, and not all + * implementations will support reading and returning multiple values. + * + * @param + * The type that the given property is parsed into. + * + * @param property + * The property to read from guacamole.properties. + * + * @param defaultValue + * The single value to return in the Collection if no value was given + * in guacamole.properties. + * + * @return + * A sorted collection of the the parsed values of the property as read + * from guacamole.properties, or a Collection with the single default + * value provided. + * + * @throws GuacamoleException + * If an error occurs while parsing the value for the given property in + * guacamole.properties. + */ + public default Collection getPropertyCollection( + GuacamoleProperty property, Type defaultValue) + throws GuacamoleException { + + /* Pull the given property as a string. */ + StringGuacamoleProperty stringProperty = new StringGuacamoleProperty() { + + @Override + public String getName() { return property.getName(); } + + }; + + /* Check the value and return the default if null. */ + String stringValue = getProperty(stringProperty); + if (stringValue == null) + return Collections.singletonList(defaultValue); + + /* Parse the string and return the collection. */ + return property.parseValueCollection(stringValue); + + } + + /** + * Given a GuacamoleProperty, parses and returns the value set for that + * property in guacamole.properties, if any. If no value is found, the + * provided Collection of default values is returned. The + * implementation of parsing and returning a collection of multiple + * values is up to the individual property implementations, and not all + * implementations will support reading and returning multiple values. + * + * @param + * The type that the given property is parsed into. + * + * @param property + * The property to read from guacamole.properties. + * + * @param defaultValue + * The Collection of values to return in the Collection if no value was + * given in guacamole.properties. + * + * @return + * A sorted collection of the the parsed values of the property as read + * from guacamole.properties, or a Collection with the single default + * value provided. + * + * @throws GuacamoleException + * If an error occurs while parsing the value for the given property in + * guacamole.properties. + */ + public default Collection getPropertyCollection( + GuacamoleProperty property, Collection defaultValue) + throws GuacamoleException { + + /* Pull the given property as a string. */ + StringGuacamoleProperty stringProperty = new StringGuacamoleProperty() { + + @Override + public String getName() { return property.getName(); } + + }; + + /* Check the value and return the default if null. */ + String stringValue = getProperty(stringProperty); + if (stringValue == null) + return defaultValue; + + /* Parse the string and return the collection. */ + return property.parseValueCollection(stringValue); + + } + /** * Given a GuacamoleProperty, parses and returns the value set for that * property in guacamole.properties. An exception is thrown if the value @@ -148,6 +296,43 @@ public Type getProperty(GuacamoleProperty property, */ public Type getRequiredProperty(GuacamoleProperty property) throws GuacamoleException; + + /** + * Given a GuacamoleProperty, parses and returns a sorted Collection of + * values for that property in guacamole.properties. An exception is thrown + * if the value is not provided. The implementation of parsing and returning + * a collection of multiple values is up to the individual property + * implementations, and not all implementations will support reading and + * returning multiple values. + * + * @param + * The type that the given property is parsed into. + * + * @param property + * The property to read from guacamole.properties. + * + * @return + * A sorted Collection of the property as read from guacamole.properties. + * + * @throws GuacamoleException + * If an error occurs while parsing the value for the given property in + * guacamole.properties, or if the property is not specified. + */ + public default Collection getRequiredPropertyCollection( + GuacamoleProperty property) throws GuacamoleException { + + /* Pull the given property as a string. */ + StringGuacamoleProperty stringProperty = new StringGuacamoleProperty() { + + @Override + public String getName() { return property.getName(); } + + }; + + /* Parse the string to a Collection of the desired type. */ + return property.parseValueCollection(getRequiredProperty(stringProperty)); + + } /** * Returns the connection information which should be used, by default, to diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/environment/LocalEnvironment.java b/guacamole-ext/src/main/java/org/apache/guacamole/environment/LocalEnvironment.java index caf1c418e9..bd0f3f1529 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/environment/LocalEnvironment.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/environment/LocalEnvironment.java @@ -25,6 +25,8 @@ import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -353,6 +355,38 @@ public Type getProperty(GuacamoleProperty property, return value; } + + @Override + public Collection getPropertyCollection(GuacamoleProperty property) + throws GuacamoleException { + + return property.parseValueCollection(getPropertyValue(property.getName())); + + } + + @Override + public Collection getPropertyCollection(GuacamoleProperty property, + Type defaultValue) throws GuacamoleException { + + Collection value = getPropertyCollection(property); + if (value == null) + return Collections.singletonList(defaultValue); + + return value; + + } + + @Override + public Collection getPropertyCollection(GuacamoleProperty property, + Collection defaultValue) throws GuacamoleException { + + Collection value = getPropertyCollection(property); + if (value == null) + return defaultValue; + + return value; + + } @Override public Type getRequiredProperty(GuacamoleProperty property) @@ -365,6 +399,18 @@ public Type getRequiredProperty(GuacamoleProperty property) return value; } + + @Override + public Collection getRequiredPropertyCollection(GuacamoleProperty property) + throws GuacamoleException { + + Collection value = getPropertyCollection(property); + if (value == null) + throw new GuacamoleServerException("Property " + property.getName() + " is required."); + + return value; + + } @Override public Map getProtocols() { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/FileGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/FileGuacamoleProperty.java index ec380defb1..38e1dac99d 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/FileGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/FileGuacamoleProperty.java @@ -20,6 +20,9 @@ package org.apache.guacamole.properties; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.apache.guacamole.GuacamoleException; /** @@ -37,5 +40,27 @@ public File parseValue(String value) throws GuacamoleException { return new File(value); } + + @Override + public List parseValueCollection(String value) throws GuacamoleException { + + // If no property is provided, return null. + if (value == null) + return null; + + // Split string into a list of individual values + List stringValues = Arrays.asList(DELIMITER_PATTERN.split(value)); + if (stringValues.isEmpty()) + return null; + + // Translate values to Files and add to result array. + List fileValues = new ArrayList<>(); + for (String stringFile : stringValues) { + fileValues.add(new File(stringFile)); + } + + return fileValues; + + } } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/GuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/GuacamoleProperty.java index ed0c9f1a13..bcbea055ba 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/GuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/GuacamoleProperty.java @@ -19,6 +19,9 @@ package org.apache.guacamole.properties; +import java.util.Collection; +import java.util.Collections; +import java.util.regex.Pattern; import org.apache.guacamole.GuacamoleException; /** @@ -30,12 +33,21 @@ */ public interface GuacamoleProperty { + /** + * A pattern which matches against the delimiters between values. This is + * currently simply a semicolon and any following whitespace. Parts of the + * input string which match this pattern will not be included in the parsed + * result. + */ + static final Pattern DELIMITER_PATTERN = Pattern.compile(";\\s*"); + /** * Returns the name of the property in guacamole.properties that this * GuacamoleProperty will parse. * - * @return The name of the property in guacamole.properties that this - * GuacamoleProperty will parse. + * @return + * The name of the property in guacamole.properties that this + * GuacamoleProperty will parse. */ public String getName(); @@ -43,11 +55,37 @@ public interface GuacamoleProperty { * Parses the given string value into the type associated with this * GuacamoleProperty. * - * @param value The string value to parse. - * @return The parsed value. - * @throws GuacamoleException If an error occurs while parsing the - * provided value. + * @param value + * The string value to parse. + * + * @return + * The parsed value. + * + * @throws GuacamoleException + * If an error occurs while parsing the provided value. */ public Type parseValue(String value) throws GuacamoleException; + + /** + * Parses the given string value into a Collection of values of the type + * associated with this GuacamoleProperty. The default implementation + * simply returns a list containing a single item as parsed by the + * parseValue method. + * + * @param value + * The string value to parse. + * + * @return + * A sorted Collection of the parsed values. + * + * @throws GuacamoleException + * If an error occurs while parsing the provided value. + */ + default public Collection parseValueCollection(String value) + throws GuacamoleException { + + return Collections.singletonList(parseValue(value)); + + } } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/IntegerGuacamoleProperty.java index 2228e2ea29..8746f2774c 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/IntegerGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/IntegerGuacamoleProperty.java @@ -19,6 +19,9 @@ package org.apache.guacamole.properties; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; @@ -42,5 +45,26 @@ public Integer parseValue(String value) throws GuacamoleException { } } + + @Override + public List parseValueCollection(String value) throws GuacamoleException { + + if (value == null) + return null; + + // Split string into a list of individual values + List stringValues = Arrays.asList(DELIMITER_PATTERN.split(value)); + if (stringValues.isEmpty()) + return null; + + // Translate values to Integers, validating along the way. + List intValues = new ArrayList<>(); + for (String stringInt : stringValues) { + intValues.add(parseValue(stringInt)); + } + + return intValues; + + } } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/LongGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/LongGuacamoleProperty.java index 9c25d6f504..b118a6140f 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/LongGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/LongGuacamoleProperty.java @@ -19,6 +19,9 @@ package org.apache.guacamole.properties; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; @@ -42,5 +45,26 @@ public Long parseValue(String value) throws GuacamoleException { } } + + @Override + public List parseValueCollection(String value) throws GuacamoleException { + + if (value == null) + return null; + + // Split string into a list of individual values + List stringValues = Arrays.asList(DELIMITER_PATTERN.split(value)); + if (stringValues.isEmpty()) + return null; + + // Translate values to Longs, validating along the way. + List longValues = new ArrayList<>(); + for (String stringLong : stringValues) { + longValues.add(parseValue(stringLong)); + } + + return longValues; + + } } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringGuacamoleProperty.java index 0d3756ab10..abc2b15cb8 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringGuacamoleProperty.java @@ -19,6 +19,8 @@ package org.apache.guacamole.properties; +import java.util.Arrays; +import java.util.List; import org.apache.guacamole.GuacamoleException; /** @@ -30,5 +32,20 @@ public abstract class StringGuacamoleProperty implements GuacamoleProperty parseValueCollection(String value) throws GuacamoleException { + + if (value == null) + return null; + + // Split string into a list of individual values + List stringValues = Arrays.asList(DELIMITER_PATTERN.split(value)); + if (stringValues.isEmpty()) + return null; + + return stringValues; + + } } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringListProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringListProperty.java index 0bb81423c3..574a3d8ca7 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringListProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/StringListProperty.java @@ -31,17 +31,14 @@ * compatibility with the behavior of Java properties in general, only * whitespace at the beginning of each value is ignored; trailing whitespace * becomes part of the value. + * + * @deprecated + * This class is now deprecated in favor of using the StringGuacamoleProperty + * class with the parseValueCollection method. */ +@Deprecated public abstract class StringListProperty implements GuacamoleProperty> { - /** - * A pattern which matches against the delimiters between values. This is - * currently simply a comma and any following whitespace. Parts of the - * input string which match this pattern will not be included in the parsed - * result. - */ - private static final Pattern DELIMITER_PATTERN = Pattern.compile(",\\s*"); - @Override public List parseValue(String values) throws GuacamoleException { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/TimeZoneGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/TimeZoneGuacamoleProperty.java index a294bda670..d4a15f9779 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/TimeZoneGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/TimeZoneGuacamoleProperty.java @@ -19,6 +19,9 @@ package org.apache.guacamole.properties; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.TimeZone; import java.util.regex.Pattern; import org.apache.guacamole.GuacamoleException; @@ -57,4 +60,25 @@ public TimeZone parseValue(String value) throws GuacamoleException { } + @Override + public List parseValueCollection(String value) throws GuacamoleException { + + if (value == null) + return null; + + // Split string into a list of individual values + List stringValues = Arrays.asList(DELIMITER_PATTERN.split(value)); + if (stringValues.isEmpty()) + return null; + + // Translate values to Integers, validating along the way. + List tzValues = new ArrayList<>(); + for (String stringTz : stringValues) { + tzValues.add(parseValue(stringTz)); + } + + return tzValues; + + } + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/URIGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/URIGuacamoleProperty.java index 7f53bf834c..ae6077c7b3 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/URIGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/URIGuacamoleProperty.java @@ -21,6 +21,9 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; @@ -46,4 +49,26 @@ public URI parseValue(String value) throws GuacamoleException { } + @Override + public List parseValueCollection(String value) throws GuacamoleException { + + // Nothing provided, return nothing. + if (value == null) + return null; + + // Split string into a list of individual values + List stringValues = Arrays.asList(DELIMITER_PATTERN.split(value)); + if (stringValues.isEmpty()) + return null; + + // Translate values to URIs, validating along the way. + List uriValues = new ArrayList<>(); + for (String stringUri : stringValues) { + uriValues.add(parseValue(stringUri)); + } + + return uriValues; + + } + }