Skip to content

Commit

Permalink
Fixed issue with loading messages in different language. As a standal…
Browse files Browse the repository at this point in the history
…one jar you can write properties back to messages.properties, this approach worked when you run with exploded classpath (target/classes etc). However failed when running inside Docker container.
  • Loading branch information
nbaars committed Feb 5, 2017
1 parent d257004 commit ae82df3
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import com.google.common.collect.Sets;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.LabelDebugger;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -117,8 +118,13 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
}

@Bean
public Messages messageSource() {
Messages messages = new Messages(localeResolver());
public PluginMessages pluginMessages(Messages messages) {
return new PluginMessages(messages);
}

@Bean
public Messages messageSource(LocaleResolver localeResolver) {
Messages messages = new Messages(localeResolver);
messages.setBasename("classpath:/i18n/messages");
return messages;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Context;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.plugins.PluginClassLoader;
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
import org.owasp.webgoat.plugins.PluginsExtractor;
Expand Down Expand Up @@ -91,8 +92,8 @@ public PluginClassLoader pluginClassLoader() {
}

@Bean
public PluginsExtractor pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader) {
return new PluginsExtractor(pluginTargetDirectory, classLoader);
public PluginsExtractor pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader, PluginMessages messages) {
return new PluginsExtractor(pluginTargetDirectory, classLoader, messages);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
package org.owasp.webgoat.assignments;

import lombok.Getter;
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;
Expand All @@ -50,7 +50,7 @@ public abstract class AssignmentEndpoint extends Endpoint {
private UserSessionData userSessionData;
@Getter
@Autowired
private Messages messages;
private PluginMessages messages;

//// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;

@AllArgsConstructor
public class AttackResult {

public static class AttackResultBuilder {

private boolean lessonCompleted;
private Messages messages;
private PluginMessages messages;
private Object[] feedbackArgs;
private String feedbackResourceBundleKey;
private String output;
private Object[] outputArgs;

public AttackResultBuilder(Messages messages) {
public AttackResultBuilder(PluginMessages messages) {
this.messages = messages;
}

Expand Down Expand Up @@ -84,7 +84,7 @@ public AttackResult build() {
private String output;


public static AttackResultBuilder builder(Messages messages) {
public static AttackResultBuilder builder(PluginMessages messages) {
return new AttackResultBuilder(messages);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class Messages extends ReloadableResourceBundleMessageSource {

/**
* Gets all messages for presented Locale.
*
* @return all messages
*/
public Properties getMessages() {
Expand All @@ -64,4 +65,6 @@ protected Locale resolveLocale() {
return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/

package org.owasp.webgoat.i18n;

import lombok.SneakyThrows;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;

import java.io.File;
import java.util.Properties;

/**
* Message resource bundle for plugins. The files is created after startup during the init of the plugins so we
* need to load this file through a ResourceLoader instead of location on the classpath.
*
* @author nbaars
* @date 2/4/17
*/
public class PluginMessages extends ReloadableResourceBundleMessageSource {

private Messages messages;

public PluginMessages(Messages messages) {
this.messages = messages;
this.setParentMessageSource(messages);
}

public Properties getMessages() {
return getMergedProperties(messages.resolveLocale()).getProperties();
}

public String getMessage(String code, Object... args) {
return getMessage(code, args, messages.resolveLocale());
}

public String getMessage(String code, String defaultValue, Object... args) {
return super.getMessage(code, args, defaultValue, messages.resolveLocale());
}

public void addPluginMessageBundles(final File i18nPluginDirectory) {
this.setBasename("WebGoatLabels");
this.setResourceLoader(new ResourceLoader() {
@Override
@SneakyThrows
public Resource getResource(String location) {
return new UrlResource(new File(i18nPluginDirectory, location).toURI());
}

@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,49 @@
*/
package org.owasp.webgoat.plugins;

import com.google.common.primitives.Bytes;
import lombok.SneakyThrows;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.io.InputStream;
import java.util.Properties;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static com.google.common.io.Files.createParentDirs;

/**
* Merges the main message.properties with the plugins WebGoatLabels
*/
public class MessagePropertiesMerger {
public class MessagePropertyMerger {

private final File targetDirectory;

public MessagePropertiesMerger(File targetDirectory) {
public MessagePropertyMerger(File targetDirectory) {
this.targetDirectory = targetDirectory;
}

@SneakyThrows
public void mergeAllLanguage() {
try(Stream<Path> paths = Files.walk(new File(targetDirectory, "plugin/i18n/").toPath())) {
paths.filter(Files::isRegularFile).forEach(filePath -> merge(filePath));
public void merge(ZipFile zipFile, ZipEntry zipEntry) {
Properties messageProperties = new Properties();
try (InputStream zis = zipFile.getInputStream(zipEntry)) {
messageProperties.load(zis);
}
}

@SneakyThrows
public void merge(Path propertyFile) {
Properties messageProperties = new Properties();
String messagePropertyFileName = propertyFile.getFileName().toString().replace("WebGoatLabels", "messages");
messageProperties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("i18n/" + messagePropertyFileName));
preparePropertyFile(propertyFile);
messageProperties.load(new FileInputStream(propertyFile.toFile()));
messageProperties.store(new FileOutputStream(new File(Thread.currentThread().getContextClassLoader().getResource("i18n/" + messagePropertyFileName).toURI())), "WebGoat message properties");
}
Properties messagesFromHome = new Properties();
File pluginMessageFiles = new File(targetDirectory, zipEntry.getName());
if (pluginMessageFiles.exists()) {
try (FileInputStream fis = new FileInputStream(pluginMessageFiles)) {
messagesFromHome.load(fis);
}
}

@SneakyThrows
private void preparePropertyFile(Path propertyFile) {
byte[] lines = Files.readAllBytes(propertyFile);
lines = Bytes.concat(lines, System.lineSeparator().getBytes());
Files.write(propertyFile, lines);
messageProperties.putAll(messagesFromHome);

createParentDirs(pluginMessageFiles);
try (FileOutputStream fos = new FileOutputStream(pluginMessageFiles)) {
messageProperties.store(fos, "Plugin message properties");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ private boolean processPropertyFile(ZipFile zipFile, ZipEntry zipEntry, File tar
throws IOException {
if (zipEntry.getName().endsWith(".properties")) {
final File targetFile = new File(targetDirectory, zipEntry.getName());
if ("WebGoatLabels.properties".equals(targetFile.getName())) {
new MessagePropertyMerger(targetDirectory).merge(zipFile, zipEntry);
}
copyFile(zipFile, zipEntry, targetFile, true);
return true;
}
Expand Down Expand Up @@ -99,6 +102,7 @@ private File copyFile(ZipFile zipFile, ZipEntry zipEntry, File targetFile, boole
return targetFile;
}


/**
* <p>Getter for the field <code>classes</code>.</p>
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.i18n.PluginMessages;
import org.springframework.util.ResourceUtils;

import java.io.*;
Expand All @@ -28,10 +29,12 @@ public class PluginsExtractor {
private static final int BUFFER_SIZE = 32 * 1024;
private final File pluginTargetDirectory;
private final PluginClassLoader classLoader;
private final PluginMessages messages;

public PluginsExtractor(File pluginTargetDirectory, PluginClassLoader pluginClassLoader) {
public PluginsExtractor(File pluginTargetDirectory, PluginClassLoader pluginClassLoader, PluginMessages messages) {
this.classLoader = pluginClassLoader;
this.pluginTargetDirectory = pluginTargetDirectory;
this.messages = messages;
}

/**
Expand Down Expand Up @@ -137,7 +140,7 @@ private List<Plugin> processPlugins(List<URL> jars) throws Exception {
plugin.getOriginationJar());
}
}
new MessagePropertiesMerger(pluginTargetDirectory).mergeAllLanguage();
messages.addPluginMessageBundles(new File(pluginTargetDirectory, "plugin/i18n"));
return plugins;
} finally {
executorService.shutdown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -60,6 +61,7 @@ public class LabelService {
public static final String URL_LABELS_MVC = "/service/labels.mvc";
private LocaleResolver localeResolver;
private Messages messages;
private PluginMessages pluginMessages;

/**
* We use Springs session locale resolver which also gives us the option to change the local later on. For
Expand All @@ -82,6 +84,9 @@ public ResponseEntity<Properties> fetchLabels(@RequestParam(value = "lang", requ
((SessionLocaleResolver)localeResolver).setDefaultLocale(locale);
log.debug("Language provided: {} leads to Locale: {}", lang, locale);
}
return new ResponseEntity<>(messages.getMessages(), HttpStatus.OK);
Properties allProperties = new Properties();
allProperties.putAll(messages.getMessages());
allProperties.putAll(pluginMessages.getMessages());
return new ResponseEntity<>(allProperties, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<!--<i class="fa fa-users"></i>-->
<!--</button>-->
</div>
<button type="button" id="about-button" class="btn btn-default right_nav_button" title="#{about}"
<button type="button" id="about-button" class="btn btn-default right_nav_button" th:title="#{about}"
data-toggle="modal" data-target="#about-modal">
<i class="fa fa-info"></i>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import org.mockito.Mock;
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;
Expand Down Expand Up @@ -60,13 +61,14 @@ protected Locale resolveLocale() {
return Locale.ENGLISH;
}
};
protected PluginMessages pluginMessages = new PluginMessages(messages);

public void init(AssignmentEndpoint a) {
messages.setBasenames("classpath:/i18n/messages", "classpath:/plugin/i18n/WebGoatLabels");
ReflectionTestUtils.setField(a, "userTracker", userTracker);
ReflectionTestUtils.setField(a, "userSessionData", userSessionData);
ReflectionTestUtils.setField(a, "webSession", webSession);
ReflectionTestUtils.setField(a, "messages", messages);
ReflectionTestUtils.setField(a, "messages", pluginMessages);
}

}

0 comments on commit ae82df3

Please sign in to comment.