diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java index a9ebf2ac1..3d1ae40f7 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -1,6 +1,6 @@ /** - ************************************************************************************************* + * ************************************************************************************************ * This file is part of WebGoat, an Open Web Application Security Project utility. For details, * please see http://www.owasp.org/ *

@@ -25,28 +25,26 @@ *

* * @author WebGoat - * @since December 12, 2015 * @version $Id: $Id + * @since December 12, 2015 */ package org.owasp.webgoat; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.asciidoctor.Asciidoctor; +import org.owasp.webgoat.i18n.Language; +import org.springframework.util.StringUtils; import org.thymeleaf.TemplateProcessingParameters; import org.thymeleaf.resourceresolver.IResourceResolver; import org.thymeleaf.templateresolver.TemplateResolver; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import java.util.Optional; +import java.util.function.Predicate; import static org.asciidoctor.Asciidoctor.Factory.create; @@ -62,9 +60,12 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { private static final Asciidoctor asciidoctor = create(); private static final String PREFIX = "doc:"; private final File pluginTargetDirectory; + private final Language language; - public AsciiDoctorTemplateResolver(File pluginTargetDirectory) { + public AsciiDoctorTemplateResolver(File pluginTargetDirectory, Language language) { this.pluginTargetDirectory = pluginTargetDirectory; + this.language = language; + setResourceResolver(new AdocResourceResolver()); setResolvablePatterns(Sets.newHashSet(PREFIX + "*")); } @@ -80,7 +81,7 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { @Override public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) { try { - Optional adocFile = find(pluginTargetDirectory.toPath(), resourceName); + Optional adocFile = resolveAdocFile(resourceName); if (adocFile.isPresent()) { try (FileReader reader = new FileReader(adocFile.get().toFile())) { StringWriter writer = new StringWriter(); @@ -93,6 +94,18 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { //no html yet return new ByteArrayInputStream(new byte[0]); } + + } + + private Optional resolveAdocFile(String resourceName) throws IOException { + Optional path = Optional.empty(); + if (language.getLocale() != null) { + path = find(pluginTargetDirectory.toPath(), resourceName, language.getLocale().toString()); + } + if (!path.isPresent()) { + path = find(pluginTargetDirectory.toPath(), resourceName, null); + } + return path; } private Map createAttributes() { @@ -106,10 +119,12 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { return options; } - private Optional find(Path path, String resourceName) throws IOException { + private Optional find(Path path, String resourceName, String language) throws IOException { + Predicate languageFilter = p -> StringUtils.hasText(language) ? p.getParent().getFileName().toString().equals(language) : true; return Files.walk(path) .filter(Files::isRegularFile) - .filter(p -> p.toString().endsWith(resourceName)).findFirst(); + .filter(p -> p.toString().endsWith(resourceName)) + .filter(languageFilter).findFirst(); } @Override @@ -117,4 +132,5 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { return "adocResourceResolver"; } } + } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java index 13ff7139d..0ce4ca9e9 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java @@ -31,6 +31,7 @@ package org.owasp.webgoat; import com.google.common.collect.Sets; +import org.owasp.webgoat.i18n.Language; import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.session.Course; @@ -89,8 +90,8 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { } @Bean - public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver() { - AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(pluginTargetDirectory); + public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language) { + AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(pluginTargetDirectory, language); resolver.setCacheable(true); resolver.setOrder(3); return resolver; @@ -118,13 +119,18 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { } @Bean - public PluginMessages pluginMessages(Messages messages) { - return new PluginMessages(messages); + public PluginMessages pluginMessages(Messages messages, Language language) { + return new PluginMessages(messages, language); } @Bean - public Messages messageSource(LocaleResolver localeResolver) { - Messages messages = new Messages(localeResolver); + public Language language(LocaleResolver localeResolver) { + return new Language(localeResolver); + } + + @Bean + public Messages messageSource(Language language) { + Messages messages = new Messages(language); messages.setBasename("classpath:/i18n/messages"); return messages; } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Language.java b/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Language.java new file mode 100644 index 000000000..d2fe5bd95 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Language.java @@ -0,0 +1,51 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, + * please see http://www.owasp.org/ + *

+ * Copyright (c) 2002 - 2017 Bruce Mayhew + *

+ * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 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 + * General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + *

+ * Getting Source ============== + *

+ * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software + * projects. + *

+ */ + +package org.owasp.webgoat.i18n; + +import lombok.AllArgsConstructor; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.LocaleResolver; + +import java.util.Locale; + +/** + * Wrapper around the LocaleResolver from Spring so we do not need to bother with passing the HttpRequest object + * when asking for a Locale. + * + * @author nbaars + * @date 2/7/17 + */ +@AllArgsConstructor +public class Language { + + private final LocaleResolver localeResolver; + + public Locale getLocale() { + return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()); + } + +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Messages.java b/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Messages.java index 527a69b93..4f3312ddf 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Messages.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/i18n/Messages.java @@ -26,11 +26,7 @@ package org.owasp.webgoat.i18n; import lombok.AllArgsConstructor; import org.springframework.context.support.ReloadableResourceBundleMessageSource; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import org.springframework.web.servlet.LocaleResolver; -import java.util.Locale; import java.util.Properties; /** @@ -42,7 +38,7 @@ import java.util.Properties; @AllArgsConstructor public class Messages extends ReloadableResourceBundleMessageSource { - private final LocaleResolver localeResolver; + private final Language language; /** * Gets all messages for presented Locale. @@ -50,21 +46,14 @@ public class Messages extends ReloadableResourceBundleMessageSource { * @return all messages */ public Properties getMessages() { - return getMergedProperties(resolveLocale()).getProperties(); + return getMergedProperties(language.getLocale()).getProperties(); } public String getMessage(String code, Object... args) { - return getMessage(code, args, resolveLocale()); + return getMessage(code, args, language.getLocale()); } public String getMessage(String code, String defaultValue, Object... args) { - return super.getMessage(code, args, defaultValue, resolveLocale()); + return super.getMessage(code, args, defaultValue, language.getLocale()); } - - protected Locale resolveLocale() { - return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()); - } - - - } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/i18n/PluginMessages.java b/webgoat-container/src/main/java/org/owasp/webgoat/i18n/PluginMessages.java index 6db37dd0e..235669f68 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/i18n/PluginMessages.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/i18n/PluginMessages.java @@ -43,23 +43,23 @@ import java.util.Properties; */ public class PluginMessages extends ReloadableResourceBundleMessageSource { - private Messages messages; + private Language language; - public PluginMessages(Messages messages) { - this.messages = messages; + public PluginMessages(Messages messages, Language language) { + this.language = language; this.setParentMessageSource(messages); } public Properties getMessages() { - return getMergedProperties(messages.resolveLocale()).getProperties(); + return getMergedProperties(language.getLocale()).getProperties(); } public String getMessage(String code, Object... args) { - return getMessage(code, args, messages.resolveLocale()); + return getMessage(code, args, language.getLocale()); } public String getMessage(String code, String defaultValue, Object... args) { - return super.getMessage(code, args, defaultValue, messages.resolveLocale()); + return super.getMessage(code, args, defaultValue, language.getLocale()); } public void addPluginMessageBundles(final File i18nPluginDirectory) { diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 1814e2788..75cf3a5ed 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -14,6 +14,7 @@ security.enable-csrf=false spring.devtools.restart.enabled=false spring.resources.cache-period=0 +spring.thymeleaf.cache=false webgoat.user.directory=${user.home}/.webgoat/ webgoat.build.version=@project.version@ diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java index 3b4885db1..793104dbf 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java @@ -26,16 +26,15 @@ package org.owasp.webgoat.assignments; import org.mockito.Mock; +import org.owasp.webgoat.i18n.Language; import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.session.UserSessionData; import org.owasp.webgoat.session.UserTracker; import org.owasp.webgoat.session.WebSession; import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.i18n.FixedLocaleResolver; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.util.Locale; public class AssignmentEndpointTest { @@ -46,22 +45,14 @@ public class AssignmentEndpointTest { protected WebSession webSession; @Mock protected UserSessionData userSessionData; - protected Messages messages = new Messages(new LocaleResolver() { + private Language language = new Language(new FixedLocaleResolver()){ @Override - public Locale resolveLocale(HttpServletRequest request) { - return Locale.ENGLISH; - } - - @Override - public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { - - }}){ - @Override - protected Locale resolveLocale() { + public Locale getLocale() { return Locale.ENGLISH; } }; - protected PluginMessages pluginMessages = new PluginMessages(messages); + protected Messages messages = new Messages(language); + protected PluginMessages pluginMessages = new PluginMessages(messages, language); public void init(AssignmentEndpoint a) { messages.setBasenames("classpath:/i18n/messages", "classpath:/plugin/i18n/WebGoatLabels"); diff --git a/webgoat-lessons/http-basics/src/main/resources/plugin/HttpBasics/lessonPlans/nl/HttpBasics_content1.adoc b/webgoat-lessons/http-basics/src/main/resources/plugin/HttpBasics/lessonPlans/nl/HttpBasics_content1.adoc new file mode 100644 index 000000000..a4e516647 --- /dev/null +++ b/webgoat-lessons/http-basics/src/main/resources/plugin/HttpBasics/lessonPlans/nl/HttpBasics_content1.adoc @@ -0,0 +1,8 @@ + +Voer je naam in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request. + +The user should become familiar with the features of WebGoat by manipulating the above buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using OWASP ZAP Attack Proxy to see the HTTP data. + +== Try It! + +Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request. \ No newline at end of file diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index 16cb5d107..49fd19344 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -68,6 +68,12 @@ 4.1.3.RELEASE test + + + com.thoughtworks.xstream + xstream + 1.4.7 +