Skip to content

Commit

Permalink
Merge pull request WebGoat#289 from zupzup/feature/labelservice
Browse files Browse the repository at this point in the history
Issue WebGoat#265: Created LabelService to support UI localization
  • Loading branch information
misfir3 authored Nov 29, 2016
2 parents c7e46bf + 2b0b49c commit df29b36
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.owasp.webgoat.i18n;

import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import java.util.Locale;
import java.util.Properties;

/**
* <p>ExposedReloadableResourceMessageBundleSource class.</p>
* Extends the reloadable message source with a way to get all messages
*
* @author zupzup
*/

public class ExposedReloadableResourceMessageBundleSource extends ReloadableResourceBundleMessageSource {
/**
* Gets all messages for presented Locale.
* @param locale user request's locale
* @return all messages
*/
public Properties getMessages(Locale locale) {
return getMergedProperties(locale).getProperties();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@

import java.net.MalformedURLException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.*;


/**
Expand Down Expand Up @@ -52,8 +50,8 @@ public class LabelProvider {

private static final List<Locale> SUPPORTED = Arrays.asList(Locale.GERMAN, Locale.FRENCH, Locale.ENGLISH,
Locale.forLanguageTag("ru"));
private final ReloadableResourceBundleMessageSource labels = new ReloadableResourceBundleMessageSource();
private static final ReloadableResourceBundleMessageSource pluginLabels = new ReloadableResourceBundleMessageSource();
private final ExposedReloadableResourceMessageBundleSource labels = new ExposedReloadableResourceMessageBundleSource();
private static final ExposedReloadableResourceMessageBundleSource pluginLabels = new ExposedReloadableResourceMessageBundleSource();

/**
* <p>Constructor for LabelProvider.</p>
Expand Down Expand Up @@ -104,7 +102,27 @@ public String get(Locale locale, String strName) {
}

private Locale useLocaleOrFallbackToEnglish(Locale locale) {
return SUPPORTED.contains(locale) ? Locale.ENGLISH : locale;
return SUPPORTED.contains(locale) ? locale : Locale.ENGLISH;
}

/**
* <p>getLabels.</p>
* Returns a merged map of all the labels for a specified language or the
* default language, if the given language is not supported
*
* @param locale The Locale to get all the labels for
* @return A Map of all properties with their values
*/
public Map<String, String> getLabels(Locale locale) {
Properties messages = labels.getMessages(locale);
messages.putAll(pluginLabels.getMessages(useLocaleOrFallbackToEnglish(locale)));
Map<String,String> labelsMap = new HashMap<>();
for (Map.Entry<Object, Object> entry : messages.entrySet()) {
if (entry.getKey() != null && entry.getValue() != null) {
labelsMap.put(entry.getKey().toString(), entry.getValue().toString());
}
}
return labelsMap;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.owasp.webgoat.service;

import org.owasp.webgoat.i18n.LabelProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.Map;


/**
* <p>LabelService class.</p>
*
* @author zupzup
*/

@Controller
public class LabelService {

private static final String URL_LABELS_MVC = "/service/labels.mvc";

private static final Logger logger = LoggerFactory.getLogger(LabelService.class);

@Autowired
private LabelProvider labelProvider;

/**
* Fetches labels for given language
* If no language is provided, the language is determined from the request headers
* Otherwise, fall back to default language
*
* @param lang the language to fetch labels for (optional)
* @return a map of labels
* @throws Exception
*/
@RequestMapping(path = URL_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
ResponseEntity<Map<String, String>> fetchLabels(@RequestParam(value = "lang", required = false) String lang, HttpServletRequest request) throws Exception {
Locale locale;
if (StringUtils.isEmpty(lang)) {
logger.debug("No language provided, determining from request headers");
locale = request.getLocale();
if (locale != null) {
logger.debug("Locale set to {}", locale);
}
} else {
locale = Locale.forLanguageTag(lang);
logger.debug("Language provided: {} leads to Locale: {}", lang, locale);
}
return new ResponseEntity<>(labelProvider.getLabels(locale), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,18 @@ public void defaultLabelsShouldBePresent() {
"Congratulations. You have successfully completed this lesson."));
}

@Test
public void shouldFallBackToEnglishIfLanguageNotSupported() {
LabelProvider labelProvider = new LabelProvider();
assertThat(labelProvider.get(Locale.CHINESE, "LessonCompleted"), CoreMatchers.equalTo(
"Congratulations. You have successfully completed this lesson."));
}

@Test
public void shouldUseProvidedLanguageIfSupported() {
LabelProvider labelProvider = new LabelProvider();
assertThat(labelProvider.get(Locale.GERMAN, "RestartLesson"), CoreMatchers.equalTo(
"Lektion neu beginnen"));
}

}

0 comments on commit df29b36

Please sign in to comment.