From fdd23036a224675ac82267698df52be133bc0217 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 12 Oct 2015 17:23:41 -0700 Subject: [PATCH] GUAC-1345: Add 'allowed-languages' property. Restrict loaded languages to keys explicitly listed, if any. --- .../net/basic/extension/ExtensionModule.java | 3 +- .../extension/LanguageResourceService.java | 70 +++++++++++++++++++ .../properties/BasicGuacamoleProperties.java | 14 ++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java index 3e8c70af3..b9f070412 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java @@ -100,7 +100,7 @@ public class ExtensionModule extends ServletModule { /** * Service for adding and retrieving language resources. */ - private final LanguageResourceService languageResourceService = new LanguageResourceService(); + private final LanguageResourceService languageResourceService; /** * Returns the classloader that should be used as the parent classloader @@ -139,6 +139,7 @@ public class ExtensionModule extends ServletModule { */ public ExtensionModule(Environment environment) { this.environment = environment; + this.languageResourceService = new LanguageResourceService(environment); } /** diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/LanguageResourceService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/LanguageResourceService.java index 9955b5bf6..dece975e6 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/LanguageResourceService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/LanguageResourceService.java @@ -36,6 +36,9 @@ import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.node.JsonNodeFactory; import org.codehaus.jackson.node.ObjectNode; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.environment.Environment; +import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties; import org.glyptodon.guacamole.net.basic.resource.ByteArrayResource; import org.glyptodon.guacamole.net.basic.resource.Resource; import org.glyptodon.guacamole.net.basic.resource.WebApplicationResource; @@ -76,6 +79,13 @@ public class LanguageResourceService { */ private static final Pattern LANGUAGE_KEY_PATTERN = Pattern.compile(".*/([a-z]+(_[A-Z]+)?)\\.json"); + /** + * The set of all language keys which are explicitly listed as allowed + * within guacamole.properties, or null if all defined languages should be + * allowed. + */ + private final Set allowedLanguages; + /** * Map of all language resources by language key. Language keys are * language and country code pairs, separated by an underscore, like @@ -86,6 +96,35 @@ public class LanguageResourceService { */ private final Map resources = new HashMap(); + /** + * Creates a new service for tracking and parsing available translations + * which reads its configuration from the given environment. + * + * @param environment + * The environment from which the configuration properties of this + * service should be read. + */ + public LanguageResourceService(Environment environment) { + + Set parsedAllowedLanguages; + + // Parse list of available languages from properties + try { + parsedAllowedLanguages = environment.getProperty(BasicGuacamoleProperties.ALLOWED_LANGUAGES); + logger.debug("Available languages will be restricted to: {}", parsedAllowedLanguages); + } + + // Warn of failure to parse + catch (GuacamoleException e) { + parsedAllowedLanguages = null; + logger.error("Unable to parse list of allowed languages: {}", e.getMessage()); + logger.debug("Error parsing list of allowed languages.", e); + } + + this.allowedLanguages = parsedAllowedLanguages; + + } + /** * Derives a language key from the filename within the given path, if * possible. If the filename is not a valid language key, null is returned. @@ -184,6 +223,31 @@ public class LanguageResourceService { } + /** + * Returns whether a language having the given key should be allowed to be + * loaded. If language availability restrictions are imposed through + * guacamole.properties, this may return false in some cases. By default, + * this function will always return true. Note that just because a language + * key is allowed to be loaded does not imply that the language key is + * valid. + * + * @param languageKey + * The language key of the language to test. + * + * @return + * true if the given language key should be allowed to be loaded, false + * otherwise. + */ + private boolean isLanguageAllowed(String languageKey) { + + // If no list is provided, all languages are implicitly available + if (allowedLanguages == null) + return true; + + return allowedLanguages.contains(languageKey); + + } + /** * Adds or overlays the given language resource, which need not exist in * the ServletContext. If a language resource is already defined for the @@ -202,6 +266,12 @@ public class LanguageResourceService { */ public void addLanguageResource(String key, Resource resource) { + // Skip loading of language if not allowed + if (!isLanguageAllowed(key)) { + logger.debug("OMITTING language: \"{}\"", key); + return; + } + // Merge language resources if already defined Resource existing = resources.get(key); if (existing != null) { diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/properties/BasicGuacamoleProperties.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/properties/BasicGuacamoleProperties.java index a1b2e1336..2bccfdb5e 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/properties/BasicGuacamoleProperties.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/properties/BasicGuacamoleProperties.java @@ -24,6 +24,7 @@ package org.glyptodon.guacamole.net.basic.properties; import org.glyptodon.guacamole.properties.FileGuacamoleProperty; import org.glyptodon.guacamole.properties.IntegerGuacamoleProperty; +import org.glyptodon.guacamole.properties.StringGuacamoleProperty; /** * Properties used by the default Guacamole web application. @@ -73,4 +74,17 @@ public class BasicGuacamoleProperties { }; + /** + * Comma-separated list of all allowed languages, where each language is + * represented by a language key, such as "en" or "en_US". If specified, + * only languages within this list will be listed as available by the REST + * service. + */ + public static final StringSetProperty ALLOWED_LANGUAGES = new StringSetProperty() { + + @Override + public String getName() { return "allowed-languages"; } + + }; + }