Lang switch (#1297)

* language selector first steps

* language german intro added

* ascii doc lang attribute as additional option

* removed some commented code

* changed adoc resource loader to take into account the selected language

* added readme

* added lang test cases
This commit is contained in:
René Zubcevic
2022-07-20 10:52:48 +02:00
committed by GitHub
parent 24fcc8f321
commit 20dd3ffb95
19 changed files with 853 additions and 21 deletions

View File

@ -31,26 +31,28 @@
package org.owasp.webgoat.container;
import io.undertow.util.Headers;
import lombok.extern.slf4j.Slf4j;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.extension.JavaExtensionRegistry;
import org.owasp.webgoat.container.asciidoc.OperatingSystemMacro;
import org.owasp.webgoat.container.asciidoc.UsernameMacro;
import org.owasp.webgoat.container.asciidoc.WebGoatTmpDirMacro;
import org.owasp.webgoat.container.asciidoc.WebGoatVersionMacro;
import org.owasp.webgoat.container.asciidoc.WebWolfMacro;
import org.owasp.webgoat.container.asciidoc.WebWolfRootMacro;
import org.owasp.webgoat.container.asciidoc.*;
import org.owasp.webgoat.container.i18n.Language;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.templateresolver.FileTemplateResolver;
import org.thymeleaf.templateresource.ITemplateResource;
import org.thymeleaf.templateresource.StringTemplateResource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@ -68,10 +70,13 @@ public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
private static final Asciidoctor asciidoctor = create();
private static final String PREFIX = "doc:";
private final Language language;
private final ResourceLoader resourceLoader;
public AsciiDoctorTemplateResolver(ResourceLoader resourceLoader) {
public AsciiDoctorTemplateResolver(Language language, ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
this.language = language;
setResolvablePatterns(Set.of(PREFIX + "*"));
}
@ -79,7 +84,7 @@ public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
var templateName = resourceName.substring(PREFIX.length());
try (InputStream is = resourceLoader.getResource("classpath:/" + templateName).getInputStream()) {
try (InputStream is = getInputStream(templateName)) {
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
@ -96,10 +101,26 @@ public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
}
}
private InputStream getInputStream(String templateName) throws IOException {
if (resourceLoader.getResource("classpath:/" + computeResourceName(templateName, language.getLocale().getLanguage())).isFile()) {
return resourceLoader.getResource("classpath:/" + computeResourceName(templateName, language.getLocale().getLanguage())).getInputStream();
} else {
return resourceLoader.getResource("classpath:/" + templateName).getInputStream();
}
}
private String computeResourceName(String resourceName, String language) {
if (language.equals("en")) {
return resourceName;
} else {
return resourceName.replace(".adoc", "_".concat(language).concat(".adoc"));
}
}
private Map<String, Object> createAttributes() {
Map<String, Object> attributes = new HashMap<>();
attributes.put("source-highlighter", "coderay");
attributes.put("backend", "xhtml");
attributes.put("lang", determineLanguage());
attributes.put("icons", org.asciidoctor.Attributes.FONT_ICONS);
Map<String, Object> options = new HashMap<>();
@ -107,4 +128,20 @@ public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
return options;
}
private String determineLanguage() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
Locale browserLocale = (Locale) request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
if (null != browserLocale) {
return browserLocale.getLanguage();
} else {
String langHeader = request.getHeader(Headers.ACCEPT_LANGUAGE_STRING);
if (null != langHeader) {
return langHeader.substring(0,2);
} else {
return "en";
}
}
}
}

View File

@ -44,9 +44,11 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
@ -143,8 +145,8 @@ public class MvcConfiguration implements WebMvcConfigurer {
* Loads the lesson asciidoc.
*/
@Bean
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(ResourceLoader resourceLoader) {
AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(resourceLoader);
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language, ResourceLoader resourceLoader) {
AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language, resourceLoader);
resolver.setCacheable(false);
resolver.setOrder(1);
resolver.setCharacterEncoding(UTF8);
@ -196,6 +198,24 @@ public class MvcConfiguration implements WebMvcConfigurer {
return new Language(localeResolver);
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
return localeResolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
@Bean
public Messages messageSource(Language language) {
Messages messages = new Messages(language);
@ -205,11 +225,6 @@ public class MvcConfiguration implements WebMvcConfigurer {
return messages;
}
@Bean
public LocaleResolver localeResolver() {
return new SessionLocaleResolver();
}
@Bean
public LabelDebugger labelDebugger() {
return new LabelDebugger();

View File

@ -31,6 +31,7 @@
package org.owasp.webgoat.container;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.container.i18n.Language;
import org.owasp.webgoat.container.users.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -43,6 +44,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
/**
* Security configuration for WebGoat.

View File

@ -29,7 +29,6 @@ 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;
/**
@ -47,5 +46,4 @@ public class Language {
public Locale getLocale() {
return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
}
}