Merge branch 'develop' of https://github.com/WebGoat/WebGoat into develop

This commit is contained in:
mayhew64
2017-02-06 09:19:29 -05:00
79 changed files with 1169 additions and 930 deletions

View File

@ -31,6 +31,8 @@
package org.owasp.webgoat;
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;
@ -38,13 +40,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.templatemode.StandardTemplateModeHandlers;
import org.thymeleaf.templateresolver.TemplateResolver;
import java.io.File;
@ -114,6 +117,24 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
registry.addResourceHandler("/plugin_lessons/**").addResourceLocations("file:///" + pluginTargetDirectory.toString() + "/");
}
@Bean
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;
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
return slr;
}
@Bean
public HammerHead hammerHead(Course course) {
return new HammerHead(course);

View File

@ -34,6 +34,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
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;
@ -91,8 +92,8 @@ public class WebGoat extends SpringBootServletInitializer {
}
@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

View File

@ -1,9 +1,8 @@
/**
* ************************************************************************************************
/*
* 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 - 20014 Bruce Mayhew
* 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
@ -23,19 +22,15 @@
* projects.
* <p>
*/
package org.owasp.webgoat.endpoints;
package org.owasp.webgoat.assignments;
import lombok.Getter;
import org.owasp.webgoat.i18n.LabelManager;
import org.owasp.webgoat.i18n.LabelProvider;
import org.owasp.webgoat.lessons.AttackResult;
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.beans.factory.annotation.Autowired;
import javax.ws.rs.Path;
/**
* Each lesson can define an endpoint which can support the lesson. So for example if you create a lesson which uses JavaScript and
* needs to call out to the server to fetch data you can define an endpoint in that lesson. WebGoat will pick up this endpoint and
@ -53,11 +48,10 @@ public abstract class AssignmentEndpoint extends Endpoint {
private WebSession webSession;
@Autowired
private UserSessionData userSessionData;
@Autowired
@Getter
private LabelManager labelProvider;
@Autowired
private PluginMessages messages;
//// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) {
if (attackResult.assignmentSolved()) {
@ -80,4 +74,32 @@ public abstract class AssignmentEndpoint extends Endpoint {
public final String getPath() {
return this.getClass().getAnnotationsByType(AssignmentPath.class)[0].value();
}
/**
* Convenience method for create a successful result:
*
* - Assignment is set to solved
* - Feedback message is set to 'assignment.solved'
*
* Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
*/
protected AttackResult.AttackResultBuilder success() {
return AttackResult.builder(messages).lessonCompleted(true).feedback("assignment.solved");
}
/**
* Convenience method for create a failed result:
*
* - Assignment is set to not solved
* - Feedback message is set to 'assignment.not.solved'
*
* Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
*/
protected AttackResult.AttackResultBuilder failed() {
return AttackResult.builder(messages).lessonCompleted(false).feedback("assignment.not.solved");
}
}

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.endpoints;
package org.owasp.webgoat.assignments;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

@ -1,6 +1,4 @@
package org.owasp.webgoat.endpoints;
import org.springframework.core.annotation.AliasFor;
package org.owasp.webgoat.assignments;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

@ -0,0 +1,94 @@
/*
* 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.assignments;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.i18n.PluginMessages;
@AllArgsConstructor
public class AttackResult {
public static class AttackResultBuilder {
private boolean lessonCompleted;
private PluginMessages messages;
private Object[] feedbackArgs;
private String feedbackResourceBundleKey;
private String output;
private Object[] outputArgs;
public AttackResultBuilder(PluginMessages messages) {
this.messages = messages;
}
public AttackResultBuilder lessonCompleted(boolean lessonCompleted) {
this.lessonCompleted = lessonCompleted;
this.feedbackResourceBundleKey = "lesson.completed";
return this;
}
public AttackResultBuilder feedbackArgs(Object... args) {
this.feedbackArgs = args;
return this;
}
public AttackResultBuilder feedback(String resourceBundleKey) {
this.feedbackResourceBundleKey = resourceBundleKey;
return this;
}
public AttackResultBuilder output(String output) {
this.output = output;
return this;
}
public AttackResultBuilder outputArgs(Object... args) {
this.outputArgs = args;
return this;
}
public AttackResult build() {
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs));
}
}
@Getter
private boolean lessonCompleted;
@Getter
private String feedback;
@Getter
private String output;
public static AttackResultBuilder builder(PluginMessages messages) {
return new AttackResultBuilder(messages);
}
public boolean assignmentSolved() {
return lessonCompleted;
}
}

View File

@ -1,17 +1,8 @@
package org.owasp.webgoat.endpoints;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import java.io.File;
/**
* ************************************************************************************************
/*
* 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 - 20014 Bruce Mayhew
* 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
@ -30,11 +21,16 @@ import java.io.File;
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author nbaars
* @version $Id: $Id
* @since November 13, 2016
*/
package org.owasp.webgoat.assignments;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import java.io.File;
public abstract class Endpoint implements MvcEndpoint {
@Autowired

View File

@ -1,24 +0,0 @@
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();
}
}

View File

@ -1,78 +0,0 @@
package org.owasp.webgoat.i18n;
import org.owasp.webgoat.session.LabelDebugger;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.Locale;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 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.
*
* @version $Id: $Id
* @author dm
*/
@Component
public class LabelManager
{
private static final long serialVersionUID = 1L;
private LabelProvider labelProvider;
private LabelDebugger labelDebugger;
private Locale locale = new Locale(LabelProvider.DEFAULT_LANGUAGE);
/**
* <p>Constructor for LabelManagerImpl.</p>
*
* @param labelProvider a {@link LabelProvider} object.
*/
protected LabelManager(LabelProvider labelProvider, LabelDebugger labelDebugger) {
this.labelDebugger = labelDebugger;
this.labelProvider = labelProvider;
}
/** {@inheritDoc} */
public void setLocale(Locale locale)
{
if (locale != null)
{
this.locale = locale;
}
}
/** {@inheritDoc} */
public String get(String labelKey, Object... params)
{
String label = labelProvider.get(locale, labelKey, params);
if (labelDebugger.isEnabled()) {
label = "<font color=\"#00CD00\">" + label + "</font>";
}
return label;
}
}

View File

@ -1,128 +0,0 @@
package org.owasp.webgoat.i18n;
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 org.springframework.stereotype.Component;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.util.*;
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 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.
*
* @version $Id: $Id
* @author dm
*/
@Component
public class LabelProvider {
/** Constant <code>DEFAULT_LANGUAGE="Locale.ENGLISH.getLanguage()"</code> */
public final static String DEFAULT_LANGUAGE = Locale.ENGLISH.getLanguage();
private static final List<Locale> SUPPORTED = Arrays.asList(Locale.GERMAN, Locale.FRENCH, Locale.ENGLISH,
Locale.forLanguageTag("ru"));
private final ExposedReloadableResourceMessageBundleSource labels = new ExposedReloadableResourceMessageBundleSource();
private static final ExposedReloadableResourceMessageBundleSource pluginLabels = new ExposedReloadableResourceMessageBundleSource();
/**
* <p>Constructor for LabelProvider.</p>
*/
public LabelProvider() {
labels.setBasename("classpath:/i18n/WebGoatLabels");
labels.setFallbackToSystemLocale(false);
labels.setUseCodeAsDefaultMessage(true);
pluginLabels.setParentMessageSource(labels);
}
/**
* <p>updatePluginResources.</p>
*
* @param propertyFile a {@link java.nio.file.Path} object.
*/
public static void updatePluginResources(final Path propertyFile) {
pluginLabels.setBasename("WebGoatLabels");
pluginLabels.setFallbackToSystemLocale(false);
pluginLabels.setUseCodeAsDefaultMessage(true);
pluginLabels.setResourceLoader(new ResourceLoader() {
@Override
public Resource getResource(String location) {
try {
return new UrlResource(propertyFile.toUri());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
});
pluginLabels.clearCache();
}
/**
* <p>get.</p>
*
* @param locale a {@link java.util.Locale} object.
* @param strName a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
public String get(Locale locale, String strName, Object... params) {
return pluginLabels.getMessage(strName, params, useLocaleOrFallbackToEnglish(locale));
}
private Locale useLocaleOrFallbackToEnglish(Locale 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;
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.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;
/**
* <p>ExposedReloadableResourceMessageBundleSource class.</p>
* Extends the reloadable message source with a way to get all messages
*
* @author zupzup
*/
@AllArgsConstructor
public class Messages extends ReloadableResourceBundleMessageSource {
private final LocaleResolver localeResolver;
/**
* Gets all messages for presented Locale.
*
* @return all messages
*/
public Properties getMessages() {
return getMergedProperties(resolveLocale()).getProperties();
}
public String getMessage(String code, Object... args) {
return getMessage(code, args, resolveLocale());
}
public String getMessage(String code, String defaultValue, Object... args) {
return super.getMessage(code, args, defaultValue, resolveLocale());
}
protected Locale resolveLocale() {
return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
}
}

View File

@ -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();
}
});
}
}

View File

@ -1,72 +0,0 @@
package org.owasp.webgoat.lessons;
import lombok.Getter;
/**
* ************************************************************************************************
* 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 - 20014 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>
*
* @author WebGoat
* @version $Id: $Id
* @since August 13, 2016
*/
@Getter
public class AttackResult {
private boolean assignmentCompleted;
private String feedback;
private String output;
public static AttackResult success() {
return AttackResult.success("Congratulations");
}
public static AttackResult success(String feedback) {
return success(feedback, "");
}
public static AttackResult success(String feedback, String output) {
AttackResult attackResult = new AttackResult();
attackResult.assignmentCompleted = true;
attackResult.feedback = feedback;
attackResult.output = output;
return attackResult;
}
public static AttackResult failed(String feedback) {
return failed(feedback, "");
}
public static AttackResult failed(String feedback, String output) {
AttackResult attackResult = new AttackResult();
attackResult.assignmentCompleted = false;
attackResult.feedback = feedback;
attackResult.output = output;
return attackResult;
}
public boolean assignmentSolved() {
return assignmentCompleted;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.plugins;
import lombok.SneakyThrows;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Properties;
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 MessagePropertyMerger {
private final File targetDirectory;
public MessagePropertyMerger(File targetDirectory) {
this.targetDirectory = targetDirectory;
}
@SneakyThrows
public void merge(ZipFile zipFile, ZipEntry zipEntry) {
Properties messageProperties = new Properties();
try (InputStream zis = zipFile.getInputStream(zipEntry)) {
messageProperties.load(zis);
}
Properties messagesFromHome = new Properties();
File pluginMessageFiles = new File(targetDirectory, zipEntry.getName());
if (pluginMessageFiles.exists()) {
try (FileInputStream fis = new FileInputStream(pluginMessageFiles)) {
messagesFromHome.load(fis);
}
}
messageProperties.putAll(messagesFromHome);
createParentDirs(pluginMessageFiles);
try (FileOutputStream fos = new FileOutputStream(pluginMessageFiles)) {
messageProperties.store(fos, "Plugin message properties");
}
}
}

View File

@ -3,10 +3,10 @@ package org.owasp.webgoat.plugins;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import lombok.Getter;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.endpoints.AssignmentHints;
import org.owasp.webgoat.endpoints.AssignmentPath;
import org.owasp.webgoat.endpoints.Endpoint;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.NewLesson;

View File

@ -71,6 +71,9 @@ public class PluginExtractor {
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;
}
@ -99,6 +102,7 @@ public class PluginExtractor {
return targetFile;
}
/**
* <p>Getter for the field <code>classes</code>.</p>
*

View File

@ -3,28 +3,16 @@ package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.i18n.LabelProvider;
import org.owasp.webgoat.i18n.PluginMessages;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.*;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -41,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;
}
/**
@ -150,8 +140,7 @@ public class PluginsExtractor {
plugin.getOriginationJar());
}
}
LabelProvider.updatePluginResources(
pluginTargetDirectory.toPath().resolve("plugin/i18n/WebGoatLabels.properties"));
messages.addPluginMessageBundles(new File(pluginTargetDirectory, "plugin/i18n"));
return plugins;
} finally {
executorService.shutdown();

View File

@ -6,7 +6,6 @@
package org.owasp.webgoat.service;
import com.google.common.collect.Lists;
import org.owasp.webgoat.i18n.LabelManager;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.Hint;

View File

@ -30,7 +30,8 @@ package org.owasp.webgoat.service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.i18n.LabelProvider;
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;
@ -39,10 +40,12 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
/**
@ -50,19 +53,24 @@ import java.util.Map;
*
* @author zupzup
*/
@RestController
@Slf4j
@AllArgsConstructor
public class LabelService {
public static final String URL_LABELS_MVC = "/service/labels.mvc";
private final LabelProvider labelProvider;
private LocaleResolver localeResolver;
private Messages messages;
private PluginMessages pluginMessages;
/**
* Fetches labels for given language
* If no language is provided, the language is determined from the request headers
* Otherwise, fall back to default language
* We use Springs session locale resolver which also gives us the option to change the local later on. For
* now it uses the accept-language from the HttpRequest. If this language is not found it will default back
* to messages.properties.
*
* Note although it is possible to use Spring language interceptor we for now opt for this solution, the UI
* will always need to fetch the labels with the new language set by the user. So we don't need to intercept each
* and every request to see if the language param has been set in the request.
*
* @param lang the language to fetch labels for (optional)
* @return a map of labels
@ -70,18 +78,15 @@ public class LabelService {
*/
@GetMapping(path = URL_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Map<String, String>> fetchLabels(@RequestParam(value = "lang", required = false) String lang, HttpServletRequest request) {
Locale locale;
if (StringUtils.isEmpty(lang)) {
log.debug("No language provided, determining from request headers");
locale = request.getLocale();
if (locale != null) {
log.debug("Locale set to {}", locale);
}
} else {
locale = Locale.forLanguageTag(lang);
public ResponseEntity<Properties> fetchLabels(@RequestParam(value = "lang", required = false) String lang, HttpServletRequest request) {
if (!StringUtils.isEmpty(lang)) {
Locale locale = Locale.forLanguageTag(lang);
((SessionLocaleResolver)localeResolver).setDefaultLocale(locale);
log.debug("Language provided: {} leads to Locale: {}", lang, locale);
}
return new ResponseEntity<>(labelProvider.getLabels(locale), HttpStatus.OK);
Properties allProperties = new Properties();
allProperties.putAll(messages.getMessages());
allProperties.putAll(pluginMessages.getMessages());
return new ResponseEntity<>(allProperties, HttpStatus.OK);
}
}

View File

@ -1,10 +1,9 @@
package org.owasp.webgoat.service;
import org.owasp.webgoat.i18n.LabelManager;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@ -17,15 +16,10 @@ import org.springframework.web.bind.annotation.RestController;
* @version $Id: $Id
*/
@RestController
@AllArgsConstructor
public class LessonInfoService {
private final WebSession webSession;
private final LabelManager labelManager;
public LessonInfoService(WebSession webSession, LabelManager labelManager) {
this.webSession = webSession;
this.labelManager = labelManager;
}
/**
* <p>getLessonInfo.</p>
@ -36,7 +30,7 @@ public class LessonInfoService {
public @ResponseBody
LessonInfoModel getLessonInfo() {
AbstractLesson lesson = webSession.getCurrentLesson();
return new LessonInfoModel(labelManager.get(lesson.getTitle()), false, false, false);
return new LessonInfoModel(lesson.getTitle(), false, false, false);
}
}

View File

@ -4,7 +4,6 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.i18n.LabelManager;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.LessonInfoModel;
@ -29,7 +28,6 @@ import java.util.Map;
@AllArgsConstructor
public class LessonProgressService {
private LabelManager labelManager;
private UserTracker userTracker;
private WebSession webSession;
@ -47,7 +45,7 @@ public class LessonProgressService {
boolean lessonCompleted = false;
if (lessonTracker != null) {
lessonCompleted = lessonTracker.isLessonSolved();
successMessage = labelManager.get("LessonCompleted");
successMessage = "LessonCompleted"; //@todo we still use this??
}
json.put("lessonCompleted", lessonCompleted);
json.put("successMessage", successMessage);