diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java index edaf68ce5..0e0934b14 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java @@ -32,9 +32,9 @@ package org.owasp.webgoat; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.owasp.webgoat.plugins.Plugin; import org.owasp.webgoat.plugins.PluginClassLoader; import org.owasp.webgoat.plugins.PluginEndpointPublisher; +import org.owasp.webgoat.plugins.PluginsExtractor; import org.owasp.webgoat.plugins.PluginsLoader; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.UserTracker; @@ -51,7 +51,6 @@ import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import java.io.File; -import java.util.List; @SpringBootApplication @Slf4j @@ -77,8 +76,8 @@ public class WebGoat extends SpringBootServletInitializer { } @Bean - public PluginsLoader pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader) { - return new PluginsLoader(pluginTargetDirectory, classLoader); + public PluginsExtractor pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader) { + return new PluginsExtractor(pluginTargetDirectory, classLoader); } @Bean @@ -88,27 +87,16 @@ public class WebGoat extends SpringBootServletInitializer { } @Bean - public Course course(PluginsLoader pluginsLoader, PluginEndpointPublisher pluginEndpointPublisher) { - Course course = new Course(); - List plugins = pluginsLoader.loadPlugins(); - if (plugins.isEmpty()) { - log.error("No lessons found if you downloaded an official release of WebGoat please take the time to"); - log.error("create a new issue at https://github.com/WebGoat/WebGoat/issues/new"); - log.error("For developers run 'mvn package' first from the root directory."); - log.error("Stopping WebGoat..."); - System.exit(1); //we always run standalone - } - course.createLessonsFromPlugins(plugins); - plugins.forEach(p -> pluginEndpointPublisher.publish(p)); - - return course; + public Course course(PluginsExtractor extractor, PluginEndpointPublisher pluginEndpointPublisher) { + return new PluginsLoader(extractor, pluginEndpointPublisher).loadPlugins(); } @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) @SneakyThrows - public UserTracker userTracker(@Value("${webgoat.user.directory}") final String webgoatHome, WebSession webSession) { - UserTracker userTracker = new UserTracker(webgoatHome, webSession.getUserName()); + public UserTracker userTracker(@Value("${webgoat.user.directory}") final String webgoatHome, + @Value("${webgoat.tracker.overwrite:false}") final boolean overwrite, WebSession webSession) { + UserTracker userTracker = new UserTracker(webgoatHome, webSession.getUserName(), overwrite); userTracker.load(); return userTracker; } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/endpoints/AssignmentEndpoint.java b/webgoat-container/src/main/java/org/owasp/webgoat/endpoints/AssignmentEndpoint.java new file mode 100644 index 000000000..e279b1814 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/endpoints/AssignmentEndpoint.java @@ -0,0 +1,65 @@ +/** + * ************************************************************************************************ + * 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. + *

+ */ +package org.owasp.webgoat.endpoints; + +import org.owasp.webgoat.lessons.AttackResult; +import org.owasp.webgoat.session.UserTracker; +import org.owasp.webgoat.session.WebSession; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * 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 + * Spring will publish it. + *

+ * Extend this class and implement the met + *

+ * Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint. + */ +public abstract class AssignmentEndpoint extends Endpoint { + + @Autowired + private UserTracker userTracker; + @Autowired + private WebSession webSession; + + + //// TODO: 11/13/2016 events better fit? + protected AttackResult trackProgress(AttackResult attackResult) { + if (attackResult.assignmentSolved()) { + userTracker.assignmentSolved(webSession.getCurrentLesson(), this.getClass().getSimpleName()); + } else { + userTracker.assignmentFailed(webSession.getCurrentLesson()); + } + return attackResult; + } + + protected WebSession getWebSession() { + return webSession; + } + + +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Endpoint.java b/webgoat-container/src/main/java/org/owasp/webgoat/endpoints/Endpoint.java similarity index 98% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/Endpoint.java rename to webgoat-container/src/main/java/org/owasp/webgoat/endpoints/Endpoint.java index 18e33f4ef..20e824c14 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Endpoint.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/endpoints/Endpoint.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.lessons; +package org.owasp.webgoat.endpoints; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java index 4648c0335..728e23b22 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java @@ -44,9 +44,9 @@ public abstract class AbstractLesson extends Screen implements Comparable> assignments; + @Setter + private List assignments; /** * Constructor for the Lesson object diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java index 0189a7884..704a40189 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java @@ -1,3 +1,10 @@ +package org.owasp.webgoat.lessons; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.Serializable; + /** * ************************************************************************************************ * This file is part of WebGoat, an Open Web Application Security Project utility. For details, @@ -22,44 +29,16 @@ * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software * projects. *

+ * + * @author nbaars + * @version $Id: $Id + * @since November 25, 2016 */ -package org.owasp.webgoat.lessons; +@AllArgsConstructor +@Getter +public class Assignment implements Serializable { -import org.owasp.webgoat.lessons.model.AttackResult; -import org.owasp.webgoat.session.UserTracker; -import org.owasp.webgoat.session.WebSession; -import org.springframework.beans.factory.annotation.Autowired; + private final String name; -/** - * 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 - * Spring will publish it. - *

- * Extend this class and implement the met - *

- * Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint. - */ -public abstract class Assignment extends Endpoint { - @Autowired - private UserTracker userTracker; - @Autowired - private WebSession webSession; - - - //// TODO: 11/13/2016 events better fit? - protected AttackResult trackProgress(AttackResult attackResult) { - if (attackResult.assignmentSolved()) { - userTracker.assignmentSolved(webSession.getCurrentLesson(), this); - } else { - userTracker.assignmentFailed(webSession.getCurrentLesson()); - } - return attackResult; - } - - protected WebSession getWebSession() { - return webSession; - } - - } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/AttackResult.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AttackResult.java similarity index 98% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/AttackResult.java rename to webgoat-container/src/main/java/org/owasp/webgoat/lessons/AttackResult.java index bfcc34c68..dcd2204b5 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/AttackResult.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AttackResult.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.lessons.model; +package org.owasp.webgoat.lessons; import lombok.Getter; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/Hint.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Hint.java similarity index 98% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/Hint.java rename to webgoat-container/src/main/java/org/owasp/webgoat/lessons/Hint.java index e33ddfe50..680be7f57 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/Hint.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Hint.java @@ -24,7 +24,7 @@ * projects. * */ -package org.owasp.webgoat.lessons.model; +package org.owasp.webgoat.lessons; /** *

Hint class.

diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonInfoModel.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java similarity index 92% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonInfoModel.java rename to webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java index 427a7f57c..c889abc8f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonInfoModel.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java @@ -1,7 +1,6 @@ -package org.owasp.webgoat.lessons.model; +package org.owasp.webgoat.lessons; import lombok.Getter; -import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.session.WebSession; /** diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonMenuItem.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonMenuItem.java similarity index 96% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonMenuItem.java rename to webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonMenuItem.java index a5866850d..9313a4c7f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonMenuItem.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonMenuItem.java @@ -27,7 +27,7 @@ * https://github.com/WebGoat/WebGoat, a repository for free software projects. * */ -package org.owasp.webgoat.lessons.model; +package org.owasp.webgoat.lessons; import java.util.ArrayList; import java.util.List; @@ -105,7 +105,7 @@ public class LessonMenuItem { /** *

addChild.

* - * @param child a {@link org.owasp.webgoat.lessons.model.LessonMenuItem} object. + * @param child a {@link LessonMenuItem} object. */ public void addChild(LessonMenuItem child) { children.add(child); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonMenuItemType.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonMenuItemType.java similarity index 97% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonMenuItemType.java rename to webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonMenuItemType.java index cc774fec2..0d7aad4d9 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/LessonMenuItemType.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonMenuItemType.java @@ -25,7 +25,7 @@ * */ -package org.owasp.webgoat.lessons.model; +package org.owasp.webgoat.lessons; /** *

LessonMenuItemType class.

diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/RequestParameter.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/RequestParameter.java similarity index 98% rename from webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/RequestParameter.java rename to webgoat-container/src/main/java/org/owasp/webgoat/lessons/RequestParameter.java index 13bc3395f..5d2716920 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/model/RequestParameter.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/RequestParameter.java @@ -27,7 +27,7 @@ * for free software projects. * */ -package org.owasp.webgoat.lessons.model; +package org.owasp.webgoat.lessons; /** *

RequestParameter class.

diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java index 4c4d36bb7..9ebee50e0 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java @@ -3,9 +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.Endpoint; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.Endpoint; import org.owasp.webgoat.lessons.NewLesson; import org.springframework.util.StringUtils; @@ -13,6 +14,7 @@ import java.io.File; import java.nio.file.Path; import java.util.List; +import static java.util.stream.Collectors.toList; import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith; /** @@ -27,7 +29,9 @@ public class Plugin { private final String originationJar; private PluginClassLoader classLoader; private Class newLesson; - private List> assignments = Lists.newArrayList(); + @Getter + private List> assignments = Lists.newArrayList(); + @Getter private List> endpoints = Lists.newArrayList(); private List pluginFiles = Lists.newArrayList(); @@ -36,14 +40,6 @@ public class Plugin { this.originationJar = originatingJar; } - public List> getAssignments() { - return this.assignments; - } - - public List> getEndpoints() { - return this.endpoints; - } - /** *

findLesson.

* @@ -75,11 +71,12 @@ public class Plugin { try { Class clazz = classLoader.loadClass(realClassName); - if (Assignment.class.isAssignableFrom(clazz)) { + if (AssignmentEndpoint.class.isAssignableFrom(clazz)) { this.assignments.add(clazz); - } else if (Endpoint.class.isAssignableFrom(clazz)) { - this.endpoints.add(clazz); - } + } else + if (Endpoint.class.isAssignableFrom(clazz)) { + this.endpoints.add(clazz); + } } catch (ClassNotFoundException ce) { throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.", ce); } @@ -106,8 +103,8 @@ public class Plugin { try { if (newLesson != null) { AbstractLesson lesson = newLesson.newInstance(); - lesson.setAssignments(this.assignments); - return Optional.of(newLesson.newInstance()); + lesson.setAssignments(createAssignment(assignments)); + return Optional.of(lesson); } } catch (IllegalAccessException | InstantiationException e) { throw new PluginLoadingFailure("Unable to instantiate the lesson " + newLesson.getName(), e); @@ -116,4 +113,9 @@ public class Plugin { } + private List createAssignment(List> endpoints) { + return endpoints.stream().map(e -> new Assignment(e.getSimpleName())).collect(toList()); + } + + } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsExtractor.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsExtractor.java new file mode 100644 index 000000000..933294333 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsExtractor.java @@ -0,0 +1,173 @@ +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.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.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.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.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + *

PluginsLoader class.

+ * + * @author dm + * @version $Id: $Id + */ +@Slf4j +public class PluginsExtractor { + + private static final String WEBGOAT_PLUGIN_EXTENSION = "jar"; + private static final int BUFFER_SIZE = 32 * 1024; + private final File pluginTargetDirectory; + private final PluginClassLoader classLoader; + + public PluginsExtractor(File pluginTargetDirectory, PluginClassLoader pluginClassLoader) { + this.classLoader = pluginClassLoader; + this.pluginTargetDirectory = pluginTargetDirectory; + } + + /** + *

loadPlugins.

+ * + * @return a {@link java.util.List} object. + */ + public List loadPlugins() { + List plugins = Lists.newArrayList(); + try { + URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation(); + log.trace("Determining whether we run as standalone jar or as directory..."); + if (ResourceUtils.isFileURL(location)) { + log.trace("Running from directory, copying lessons from {}", location.toString()); + extractToTargetDirectoryFromExplodedDirectory(ResourceUtils.getFile(location)); + } else { + log.trace("Running from standalone jar, extracting lessons from {}", location.toString()); + extractToTargetDirectoryFromJarFile(ResourceUtils.getFile(ResourceUtils.extractJarFileURL(location))); + } + List jars = listJars(); + plugins = processPlugins(jars); + } catch (Exception e) { + log.error("Loading plugins failed", e); + } + return plugins; + } + + private void extractToTargetDirectoryFromJarFile(File jarFile) throws IOException { + ZipFile jar = new ZipFile(jarFile); + Enumeration entries = jar.entries(); + while (entries.hasMoreElements()) { + ZipEntry zipEntry = entries.nextElement(); + if (zipEntry.getName().contains("plugin_lessons") && zipEntry.getName().endsWith(".jar")) { + unpack(jar, zipEntry); + } + } + } + + private void unpack(ZipFile jar, ZipEntry zipEntry) throws IOException { + try (InputStream inputStream = jar.getInputStream(zipEntry)) { + String name = zipEntry.getName(); + if (name.lastIndexOf("/") != -1) { + name = name.substring(name.lastIndexOf("/") + 1); + } + try (OutputStream outputStream = new FileOutputStream(new File(pluginTargetDirectory, name))) { + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead = -1; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.flush(); + } + } + log.trace("Extracting {} to {}", jar.getName(), pluginTargetDirectory); + } + + private void extractToTargetDirectoryFromExplodedDirectory(File directory) throws IOException { + Files.walkFileTree(directory.toPath(), new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (dir.endsWith("plugin_lessons")) { + log.trace("Copying {} to {}", dir.toString(), pluginTargetDirectory); + FileUtils.copyDirectory(dir.toFile(), pluginTargetDirectory); + } + return FileVisitResult.CONTINUE; + } + }); + } + + private List listJars() throws Exception { + final List jars = Lists.newArrayList(); + Files.walkFileTree(Paths.get(pluginTargetDirectory.toURI()), new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) { + jars.add(file.toUri().toURL()); + log.trace("Found jar file at location: {}", file.toString()); + } + return FileVisitResult.CONTINUE; + } + }); + return jars; + } + + private List processPlugins(List jars) throws Exception { + final ExecutorService executorService = Executors.newFixedThreadPool(10); + try { + final List plugins = Lists.newArrayList(); + final CompletionService completionService = new ExecutorCompletionService<>(executorService); + final List> callables = extractJars(jars); + + callables.forEach(s -> completionService.submit(s)); + int n = callables.size(); + + for (int i = 0; i < n; i++) { + Plugin plugin = completionService.take().get(); + if (plugin.getLesson().isPresent()) { + log.trace("Plugin jar '{}' contains a lesson, loading into WebGoat...", plugin.getOriginationJar()); + plugins.add(plugin); + } else { + log.trace("Plugin jar: '{}' does not contain a lesson not processing as a plugin (can be a utility jar)", + plugin.getOriginationJar()); + } + } + LabelProvider.updatePluginResources( + pluginTargetDirectory.toPath().resolve("plugin/i18n/WebGoatLabels.properties")); + return plugins; + } finally { + executorService.shutdown(); + } + } + + private List> extractJars(List jars) { + List> extractorCallables = Lists.newArrayList(); + + for (final URL jar : jars) { + classLoader.addURL(jar); + extractorCallables.add(() -> { + PluginExtractor extractor = new PluginExtractor(); + return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTargetDirectory, classLoader); + }); + } + return extractorCallables; + } +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java index 35e2677fb..6806f6cc6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java @@ -1,173 +1,72 @@ package org.owasp.webgoat.plugins; import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; -import org.owasp.webgoat.i18n.LabelProvider; -import org.springframework.util.ResourceUtils; +import org.owasp.webgoat.lessons.AbstractLesson; +import org.owasp.webgoat.lessons.NewLesson; +import org.owasp.webgoat.session.Course; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -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.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.zip.ZipEntry; -import java.util.zip.ZipFile; /** - *

PluginsLoader class.

+ * ************************************************************************************************ + * 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. + *

* - * @author dm + * @author nbaars * @version $Id: $Id + * @since November 25, 2016 */ +@AllArgsConstructor @Slf4j public class PluginsLoader { - private static final String WEBGOAT_PLUGIN_EXTENSION = "jar"; - private static final int BUFFER_SIZE = 32 * 1024; - private final File pluginTargetDirectory; - private final PluginClassLoader classLoader; - - public PluginsLoader(File pluginTargetDirectory, PluginClassLoader pluginClassLoader) { - this.classLoader = pluginClassLoader; - this.pluginTargetDirectory = pluginTargetDirectory; - } + private final PluginsExtractor extractor; + private final PluginEndpointPublisher pluginEndpointPublisher; /** - *

loadPlugins.

- * - * @return a {@link java.util.List} object. + *

createLessonsFromPlugins.

*/ - public List loadPlugins() { - List plugins = Lists.newArrayList(); - try { - URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation(); - log.trace("Determining whether we run as standalone jar or as directory..."); - if (ResourceUtils.isFileURL(location)) { - log.trace("Running from directory, copying lessons from {}", location.toString()); - extractToTargetDirectoryFromExplodedDirectory(ResourceUtils.getFile(location)); - } else { - log.trace("Running from standalone jar, extracting lessons from {}", location.toString()); - extractToTargetDirectoryFromJarFile(ResourceUtils.getFile(ResourceUtils.extractJarFileURL(location))); - } - List jars = listJars(); - plugins = processPlugins(jars); - } catch (Exception e) { - log.error("Loading plugins failed", e); - } - return plugins; - } - - private void extractToTargetDirectoryFromJarFile(File jarFile) throws IOException { - ZipFile jar = new ZipFile(jarFile); - Enumeration entries = jar.entries(); - while (entries.hasMoreElements()) { - ZipEntry zipEntry = entries.nextElement(); - if (zipEntry.getName().contains("plugin_lessons") && zipEntry.getName().endsWith(".jar")) { - unpack(jar, zipEntry); + public Course loadPlugins() { + List lessons = Lists.newArrayList(); + for (Plugin plugin : extractor.loadPlugins()) { + try { + NewLesson lesson = (NewLesson) plugin.getLesson().get(); + lessons.add(lesson); + pluginEndpointPublisher.publish(plugin); + } catch (Exception e) { + log.error("Error in loadLessons: ", e); } } - } - - private void unpack(ZipFile jar, ZipEntry zipEntry) throws IOException { - try (InputStream inputStream = jar.getInputStream(zipEntry)) { - String name = zipEntry.getName(); - if (name.lastIndexOf("/") != -1) { - name = name.substring(name.lastIndexOf("/") + 1); - } - try (OutputStream outputStream = new FileOutputStream(new File(pluginTargetDirectory, name))) { - byte[] buffer = new byte[BUFFER_SIZE]; - int bytesRead = -1; - while ((bytesRead = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - outputStream.flush(); - } + if (lessons.isEmpty()) { + log.error("No lessons found if you downloaded an official release of WebGoat please take the time to"); + log.error("create a new issue at https://github.com/WebGoat/WebGoat/issues/new"); + log.error("For developers run 'mvn package' first from the root directory."); + log.error("Stopping WebGoat..."); + System.exit(1); //we always run standalone } - log.trace("Extracting {} to {}", jar.getName(), pluginTargetDirectory); + return new Course(lessons); } - private void extractToTargetDirectoryFromExplodedDirectory(File directory) throws IOException { - Files.walkFileTree(directory.toPath(), new SimpleFileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - if (dir.endsWith("plugin_lessons")) { - log.trace("Copying {} to {}", dir.toString(), pluginTargetDirectory); - FileUtils.copyDirectory(dir.toFile(), pluginTargetDirectory); - } - return FileVisitResult.CONTINUE; - } - }); - } - - private List listJars() throws Exception { - final List jars = Lists.newArrayList(); - Files.walkFileTree(Paths.get(pluginTargetDirectory.toURI()), new SimpleFileVisitor() { - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) { - jars.add(file.toUri().toURL()); - log.trace("Found jar file at location: {}", file.toString()); - } - return FileVisitResult.CONTINUE; - } - }); - return jars; - } - - private List processPlugins(List jars) throws Exception { - final ExecutorService executorService = Executors.newFixedThreadPool(10); - try { - final List plugins = Lists.newArrayList(); - final CompletionService completionService = new ExecutorCompletionService<>(executorService); - final List> callables = extractJars(jars); - - callables.forEach(s -> completionService.submit(s)); - int n = callables.size(); - - for (int i = 0; i < n; i++) { - Plugin plugin = completionService.take().get(); - if (plugin.getLesson().isPresent()) { - log.trace("Plugin jar '{}' contains a lesson, loading into WebGoat...", plugin.getOriginationJar()); - plugins.add(plugin); - } else { - log.trace("Plugin jar: '{}' does not contain a lesson not processing as a plugin (can be a utility jar)", - plugin.getOriginationJar()); - } - } - LabelProvider.updatePluginResources( - pluginTargetDirectory.toPath().resolve("plugin/i18n/WebGoatLabels.properties")); - return plugins; - } finally { - executorService.shutdown(); - } - } - - private List> extractJars(List jars) { - List> extractorCallables = Lists.newArrayList(); - - for (final URL jar : jars) { - classLoader.addURL(jar); - extractorCallables.add(() -> { - PluginExtractor extractor = new PluginExtractor(); - return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTargetDirectory, classLoader); - }); - } - return extractorCallables; - } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java index 8ec3fa8df..970bc4831 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java @@ -6,7 +6,7 @@ package org.owasp.webgoat.service; import org.owasp.webgoat.lessons.AbstractLesson; -import org.owasp.webgoat.lessons.model.Hint; +import org.owasp.webgoat.lessons.Hint; import org.owasp.webgoat.session.WebSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java index f249336b4..78b9f43dc 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java @@ -1,6 +1,6 @@ package org.owasp.webgoat.service; -import org.owasp.webgoat.lessons.model.LessonInfoModel; +import org.owasp.webgoat.lessons.LessonInfoModel; import org.owasp.webgoat.session.WebSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -24,7 +24,7 @@ public class LessonInfoService { /** *

getLessonInfo.

* - * @return a {@link org.owasp.webgoat.lessons.model.LessonInfoModel} object. + * @return a {@link LessonInfoModel} object. */ @RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json") public @ResponseBody diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java index a8c3aca7f..8f343d6d2 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java @@ -31,8 +31,8 @@ package org.owasp.webgoat.service; import lombok.AllArgsConstructor; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Category; -import org.owasp.webgoat.lessons.model.LessonMenuItem; -import org.owasp.webgoat.lessons.model.LessonMenuItemType; +import org.owasp.webgoat.lessons.LessonMenuItem; +import org.owasp.webgoat.lessons.LessonMenuItemType; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.LessonTracker; import org.owasp.webgoat.session.UserTracker; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java index aeb4375f2..0583bcd76 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java @@ -1,9 +1,13 @@ package org.owasp.webgoat.service; +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.model.LessonInfoModel; +import org.owasp.webgoat.lessons.AbstractLesson; +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.LessonInfoModel; import org.owasp.webgoat.session.LessonTracker; import org.owasp.webgoat.session.UserTracker; import org.owasp.webgoat.session.WebSession; @@ -11,6 +15,8 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.ArrayList; +import java.util.List; import java.util.Map; @@ -47,4 +53,38 @@ public class LessonProgressService { json.put("successMessage", successMessage); return json; } + + /** + * Endpoint for fetching the complete lesson overview which informs the user about whether all the assignments are solved. + * Used as the last page of the lesson to generate a lesson overview. + * + * @return list of assignments + */ + @RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json") + @ResponseBody + public List lessonOverview() { + AbstractLesson currentLesson = webSession.getCurrentLesson(); + LessonTracker lessonTracker = userTracker.getLessonTracker(currentLesson); + return toJson(lessonTracker.getLessonOverview()); + } + + private List toJson(Map map) { + ArrayList result = Lists.newArrayList(); + for (Map.Entry entry : map.entrySet()) { + result.add(new LessonOverview(entry.getKey(), entry.getValue())); + } + return result; + } + + + @AllArgsConstructor + @Getter + //Jackson does not really like returning a map of directly, see http://stackoverflow.com/questions/11628698/can-we-make-object-as-key-in-map-when-using-json + //so creating intermediate object is the easiest solution + private static class LessonOverview { + + private Assignment assignment; + private Boolean solved; + + } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java index f4bce560a..8ba3738af 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java @@ -30,7 +30,7 @@ package org.owasp.webgoat.service; import com.google.common.collect.Lists; -import org.owasp.webgoat.lessons.model.RequestParameter; +import org.owasp.webgoat.lessons.RequestParameter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java index d2272bfe0..73f263114 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java @@ -1,10 +1,9 @@ package org.owasp.webgoat.session; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Category; -import org.owasp.webgoat.lessons.NewLesson; -import org.owasp.webgoat.plugins.Plugin; import java.util.LinkedList; import java.util.List; @@ -42,6 +41,7 @@ import static java.util.stream.Collectors.toList; * @since October 28, 2003 */ @Slf4j +@AllArgsConstructor public class Course { private List lessons = new LinkedList<>(); @@ -89,18 +89,5 @@ public class Course { this.lessons = lessons; } - /** - *

createLessonsFromPlugins.

- */ - public void createLessonsFromPlugins(List plugins) { - for (Plugin plugin : plugins) { - try { - NewLesson lesson = (NewLesson) plugin.getLesson().get(); - lesson.setAssignments(plugin.getAssignments()); - lessons.add(lesson); - } catch (Exception e) { - log.error("Error in loadLessons: ", e); - } - } - } + } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/LessonTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/LessonTracker.java index ccfe3b0cc..edd0d1483 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/LessonTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/LessonTracker.java @@ -1,11 +1,16 @@ package org.owasp.webgoat.session; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import lombok.Getter; import org.owasp.webgoat.lessons.AbstractLesson; +import org.owasp.webgoat.lessons.Assignment; import java.io.Serializable; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -42,12 +47,17 @@ import java.util.stream.Collectors; */ public class LessonTracker implements Serializable { private static final long serialVersionUID = 5410058267505412928L; - private final List assignments; - private final Set solvedAssignments = Sets.newHashSet(); + private final Set solvedAssignments = Sets.newHashSet(); + private final List allAssignments = Lists.newArrayList(); + @Getter private int numberOfAttempts = 0; public LessonTracker(AbstractLesson lesson) { - this.assignments = lesson.getAssignments().stream().map(a -> a.getSimpleName()).collect(Collectors.toList()); + allAssignments.addAll(lesson.getAssignments()); + } + + public Optional getAssignment(String name) { + return allAssignments.stream().filter(a -> a.getName().equals(name)).findFirst(); } /** @@ -56,14 +66,14 @@ public class LessonTracker implements Serializable { * @param solvedAssignment the assignment which the user solved */ public void assignmentSolved(String solvedAssignment) { - solvedAssignments.add(solvedAssignment); + getAssignment(solvedAssignment).ifPresent(a -> solvedAssignments.add(a)); } /** - * @return did they user solved all assignments for the lesson? + * @return did they user solved all solvedAssignments for the lesson? */ public boolean isLessonSolved() { - return solvedAssignments.size() == assignments.size(); + return allAssignments.size() == solvedAssignments.size(); } /** @@ -79,4 +89,16 @@ public class LessonTracker implements Serializable { void reset() { solvedAssignments.clear(); } + + /** + * @return list containing all the assignments solved or not + */ + public Map getLessonOverview() { + List notSolved = allAssignments.stream() + .filter(i -> !solvedAssignments.contains(i)) + .collect(Collectors.toList()); + Map overview = notSolved.stream().collect(Collectors.toMap(a -> a, b -> false)); + overview.putAll(solvedAssignments.stream().collect(Collectors.toMap(a -> a, b -> true))); + return overview; + } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/UserTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/UserTracker.java index cc5f76681..b05512113 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/UserTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/UserTracker.java @@ -1,10 +1,9 @@ package org.owasp.webgoat.session; +import com.google.common.collect.Maps; import lombok.SneakyThrows; import org.owasp.webgoat.lessons.AbstractLesson; -import org.owasp.webgoat.lessons.Assignment; -import org.springframework.beans.factory.annotation.Value; import org.springframework.util.FileCopyUtils; import org.springframework.util.SerializationUtils; @@ -47,11 +46,13 @@ public class UserTracker { private final String webgoatHome; private final String user; + private final boolean overwrite; private Map storage = new HashMap<>(); - public UserTracker(@Value("${webgoat.user.directory}") final String webgoatHome, final String user) { + public UserTracker(final String webgoatHome, final String user, final boolean overwrite) { this.webgoatHome = webgoatHome; this.user = user; + this.overwrite = overwrite; } /** @@ -69,10 +70,10 @@ public class UserTracker { return lessonTracker; } - public void assignmentSolved(AbstractLesson lesson, Assignment assignment) { + public void assignmentSolved(AbstractLesson lesson, String assignmentName) { LessonTracker lessonTracker = getLessonTracker(lesson); lessonTracker.incrementAttempts(); - lessonTracker.assignmentSolved(assignment.getClass().getSimpleName()); + lessonTracker.assignmentSolved(assignmentName); save(); } @@ -85,7 +86,9 @@ public class UserTracker { @SneakyThrows public void load() { File file = new File(webgoatHome, user + ".progress"); - if (file.exists() && file.isFile()) { + if (overwrite) { + this.storage = Maps.newHashMap(); + } else if (file.exists() && file.isFile()) { this.storage = (Map) SerializationUtils.deserialize(FileCopyUtils.copyToByteArray(file)); } } diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 57bb003a6..b274e88e4 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -6,7 +6,7 @@ server.port=8080 logging.level.org.springframework=WARN -logging.level.org.springframework.boot.devtools=DEBUG +logging.level.org.springframework.boot.devtools=WARN logging.level.org.owasp=DEBUG logging.level.org.owasp.webgoat=TRACE @@ -14,9 +14,10 @@ spring.thymeleaf.cache=false spring.thymeleaf.content-type=text/html security.enable-csrf=false -spring.devtools.restart.enabled=true +spring.devtools.restart.enabled=false +webgoat.tracker.overwrite=true webgoat.user.directory=${user.home}/.webgoat/ webgoat.build.version=@project.version@ webgoat.build.number=@build.number@ diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java new file mode 100644 index 000000000..6cb02465a --- /dev/null +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java @@ -0,0 +1,89 @@ +package org.owasp.webgoat.service; + +import org.assertj.core.util.Maps; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.owasp.webgoat.i18n.LabelManager; +import org.owasp.webgoat.lessons.AbstractLesson; +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.session.LessonTracker; +import org.owasp.webgoat.session.UserTracker; +import org.owasp.webgoat.session.WebSession; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import static org.hamcrest.CoreMatchers.is; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * ************************************************************************************************ + * 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. + *

+ * + * @author nbaars + * @version $Id: $Id + * @since November 25, 2016 + */ +@RunWith(MockitoJUnitRunner.class) +public class LessonProgressServiceTest { + + private MockMvc mockMvc; + + @Mock + private AbstractLesson lesson; + @Mock + private UserTracker userTracker; + @Mock + private LessonTracker lessonTracker; + @Mock + private WebSession websession; + @Mock + private LabelManager labelManager; + + + @Before + public void setup() { + Assignment assignment = new Assignment("test"); + when(userTracker.getLessonTracker(any())).thenReturn(lessonTracker); + when(websession.getCurrentLesson()).thenReturn(lesson); + when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true)); + this.mockMvc = MockMvcBuilders.standaloneSetup(new LessonProgressService(labelManager, userTracker, websession)).build(); + } + + @Test + public void jsonLessonOverview() throws Exception { + this.mockMvc.perform(MockMvcRequestBuilders.get("/service/lessonoverview.mvc").accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].assignment.name", is("test"))) + .andExpect(jsonPath("$[0].solved", is(true))); + } + +} \ No newline at end of file diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/session/CourseTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/session/CourseTest.java new file mode 100644 index 000000000..75f05bb31 --- /dev/null +++ b/webgoat-container/src/test/java/org/owasp/webgoat/session/CourseTest.java @@ -0,0 +1,34 @@ +package org.owasp.webgoat.session; + +/** + * ************************************************************************************************ + * 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. + *

+ * + * @author nbaars + * @version $Id: $Id + * @since November 26, 2016 + */ +public class CourseTest { + +} \ No newline at end of file diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/session/LessonTrackerTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/session/LessonTrackerTest.java new file mode 100644 index 000000000..45f858753 --- /dev/null +++ b/webgoat-container/src/test/java/org/owasp/webgoat/session/LessonTrackerTest.java @@ -0,0 +1,73 @@ +package org.owasp.webgoat.session; + +import com.google.common.collect.Lists; +import org.junit.Test; +import org.owasp.webgoat.lessons.AbstractLesson; +import org.owasp.webgoat.lessons.Assignment; + +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * ************************************************************************************************ + * 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. + *

+ * + * @author nbaars + * @version $Id: $Id + * @since November 25, 2016 + */ +public class LessonTrackerTest { + + @Test + public void allAssignmentsSolvedShouldMarkLessonAsComplete() { + AbstractLesson lesson = mock(AbstractLesson.class); + when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment"))); + LessonTracker lessonTracker = new LessonTracker(lesson); + lessonTracker.assignmentSolved("assignment"); + + assertTrue(lessonTracker.isLessonSolved()); + } + + @Test + public void noAssignmentsSolvedShouldMarkLessonAsInComplete() { + AbstractLesson lesson = mock(AbstractLesson.class); + Assignment a1 = new Assignment("a1"); + Assignment a2 = new Assignment("a2"); + List assignments = Lists.newArrayList(a1, a2); + when(lesson.getAssignments()).thenReturn(assignments); + LessonTracker lessonTracker = new LessonTracker(lesson); + lessonTracker.assignmentSolved("a1"); + + Map lessonOverview = lessonTracker.getLessonOverview(); + assertThat(lessonOverview.get(a1)).isTrue(); + assertThat(lessonOverview.get(a2)).isFalse(); + } + + +} diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/session/UserTrackerTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/session/UserTrackerTest.java index 1a29893db..502f115c0 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/session/UserTrackerTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/session/UserTrackerTest.java @@ -3,15 +3,14 @@ package org.owasp.webgoat.session; import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Assignment; import java.io.File; import java.io.IOException; -import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** @@ -55,17 +54,38 @@ public class UserTrackerTest { @Test public void writeAndRead() { - UserTracker userTracker = new UserTracker(home.getParent(), "test"); - AbstractLesson abstractLesson = Mockito.mock(AbstractLesson.class); - Assignment assignment = Mockito.mock(Assignment.class); - when(abstractLesson.getAssignments()).thenReturn((List)Lists.newArrayList(assignment.getClass())); - userTracker.getLessonTracker(abstractLesson); - userTracker.assignmentSolved(abstractLesson, assignment); + UserTracker userTracker = new UserTracker(home.getParent(), "test", false); + AbstractLesson lesson = mock(AbstractLesson.class); + when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment"))); + userTracker.getLessonTracker(lesson); + userTracker.assignmentSolved(lesson, lesson.getAssignments().get(0).getName()); - userTracker = new UserTracker(home.getParent(), "test"); + userTracker = new UserTracker(home.getParent(), "test", false); userTracker.load(); - assertThat(userTracker.getLessonTracker(abstractLesson).isLessonSolved()).isTrue(); + assertThat(userTracker.getLessonTracker(lesson).isLessonSolved()).isTrue(); } + @Test + public void assignmentFailedShouldIncrementAttempts() { + UserTracker userTracker = new UserTracker(home.getParent(), "test", false); + AbstractLesson lesson = mock(AbstractLesson.class); + when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment"))); + userTracker.getLessonTracker(lesson); + userTracker.assignmentFailed(lesson); + userTracker.assignmentFailed(lesson); -} \ No newline at end of file + assertThat(userTracker.getLessonTracker(lesson).getNumberOfAttempts()).isEqualTo(2); + } + + @Test + public void resetShouldClearSolvedAssignment() { + UserTracker userTracker = new UserTracker(home.getParent(), "test", false); + AbstractLesson lesson = mock(AbstractLesson.class); + when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment"))); + userTracker.assignmentSolved(lesson, "assignment"); + + assertThat(userTracker.getLessonTracker(lesson).isLessonSolved()).isTrue(); + userTracker.reset(lesson); + assertThat(userTracker.getLessonTracker(lesson).isLessonSolved()).isFalse(); + } +} diff --git a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Attack.java b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Attack.java index ffddc5bb3..db1b7d5a0 100644 --- a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Attack.java +++ b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Attack.java @@ -1,7 +1,7 @@ package org.owasp.webgoat.plugin; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -38,7 +38,7 @@ import java.io.IOException; * @version $Id: $Id * @since August 11, 2016 */ -public class Attack extends Assignment { +public class Attack extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String answer) throws IOException { diff --git a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Salaries.java b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Salaries.java index 1fa3d0cc2..902f06642 100644 --- a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Salaries.java +++ b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/Salaries.java @@ -6,7 +6,7 @@ package org.owasp.webgoat.plugin; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import org.owasp.webgoat.lessons.Endpoint; +import org.owasp.webgoat.endpoints.Endpoint; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.w3c.dom.Node; diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java index 88e975681..8d1562682 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java @@ -2,17 +2,11 @@ package org.owasp.webgoat.plugin; import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; -import org.owasp.webgoat.session.DatabaseUtilities; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -50,7 +44,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class CrossSiteScriptingLesson1 extends Assignment { +public class CrossSiteScriptingLesson1 extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String answer_xss_1, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java index 69e0f4431..3e27d32a5 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java @@ -2,17 +2,11 @@ package org.owasp.webgoat.plugin; import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; -import org.owasp.webgoat.session.DatabaseUtilities; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -50,7 +44,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class CrossSiteScriptingLesson5a extends Assignment { +public class CrossSiteScriptingLesson5a extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam Integer QTY1, diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java index 111830a10..453106f73 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java @@ -11,8 +11,8 @@ import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -51,7 +51,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class CrossSiteScriptingLesson5b extends Assignment { +public class CrossSiteScriptingLesson5b extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java index b32eef186..bd5648e8f 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java @@ -10,8 +10,8 @@ import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class CrossSiteScriptingLesson6a extends Assignment { +public class CrossSiteScriptingLesson6a extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String userid_6a, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java index c537b395a..6470a1acc 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java @@ -4,14 +4,13 @@ package org.owasp.webgoat.plugin; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,7 +49,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class CrossSiteScriptingLesson6b extends Assignment { +public class CrossSiteScriptingLesson6b extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java index a339a258b..1c67f054e 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java @@ -1,7 +1,7 @@ package org.owasp.webgoat.plugin; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -13,7 +13,7 @@ import java.io.IOException; /** * Created by jason on 11/23/16. */ -public class DOMCrossSiteScripting extends Assignment { +public class DOMCrossSiteScripting extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam Integer param1, diff --git a/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsLesson.java b/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsLesson.java index 9a5a7eab2..aa57fd3ae 100644 --- a/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsLesson.java +++ b/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsLesson.java @@ -1,7 +1,7 @@ package org.owasp.webgoat.plugin; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -44,7 +44,7 @@ import java.io.IOException; * @created October 28, 2003 */ -public class HttpBasicsLesson extends Assignment { +public class HttpBasicsLesson extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String person, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsQuiz.java b/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsQuiz.java index 48353231e..3c881c90d 100644 --- a/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsQuiz.java +++ b/webgoat-lessons/http-basics/src/main/java/org/owasp/webgoat/plugin/HttpBasicsQuiz.java @@ -1,7 +1,7 @@ package org.owasp.webgoat.plugin; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -44,7 +44,7 @@ import java.io.IOException; * @created October 28, 2003 */ -public class HttpBasicsQuiz extends Assignment { +public class HttpBasicsQuiz extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String answer, @RequestParam String magic_answer, @RequestParam String magic_num, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5a.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5a.java index f4dea9384..8a27f07a4 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5a.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5a.java @@ -10,8 +10,8 @@ import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class SqlInjectionLesson5a extends Assignment { +public class SqlInjectionLesson5a extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String account, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5b.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5b.java index dee2784d2..d1044ee10 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5b.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson5b.java @@ -11,8 +11,8 @@ import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -51,7 +51,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class SqlInjectionLesson5b extends Assignment { +public class SqlInjectionLesson5b extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6a.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6a.java index 8430b0101..026b4d7a1 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6a.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6a.java @@ -10,8 +10,8 @@ import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class SqlInjectionLesson6a extends Assignment { +public class SqlInjectionLesson6a extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String userid_6a, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6b.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6b.java index cc5c3251f..e77f22d6c 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6b.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/SqlInjectionLesson6b.java @@ -4,14 +4,13 @@ package org.owasp.webgoat.plugin; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.http.HttpServletRequest; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.owasp.webgoat.session.DatabaseUtilities; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,7 +49,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ -public class SqlInjectionLesson6b extends Assignment { +public class SqlInjectionLesson6b extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException { diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java index 359149583..25ab60317 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java @@ -2,8 +2,8 @@ package org.owasp.webgoat.plugin; import com.google.common.base.Joiner; import org.apache.commons.lang.exception.ExceptionUtils; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -46,7 +46,7 @@ import static org.owasp.webgoat.plugin.SimpleXXE.parseXml; * @version $Id: $Id * @since November 18, 2016 */ -public class BlindSendFileAssignment extends Assignment { +public class BlindSendFileAssignment extends AssignmentEndpoint { @Override public String getPath() { diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java index a2f0e3a5d..4d7caca17 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java @@ -1,8 +1,8 @@ package org.owasp.webgoat.plugin; import com.fasterxml.jackson.databind.ObjectMapper; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; @@ -44,7 +44,7 @@ import static org.owasp.webgoat.plugin.SimpleXXE.parseXml; * @version $Id: $Id * @since November 17, 2016 */ -public class ContentTypeAssignment extends Assignment { +public class ContentTypeAssignment extends AssignmentEndpoint { @Override public String getPath() { diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/Ping.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/Ping.java index e189af8ce..d6f591c9a 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/Ping.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/Ping.java @@ -1,7 +1,7 @@ package org.owasp.webgoat.plugin; import lombok.extern.slf4j.Slf4j; -import org.owasp.webgoat.lessons.Endpoint; +import org.owasp.webgoat.endpoints.Endpoint; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java index e62afcd5e..fbcc4b62c 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java @@ -1,8 +1,8 @@ package org.owasp.webgoat.plugin; import org.apache.commons.exec.OS; -import org.owasp.webgoat.lessons.Assignment; -import org.owasp.webgoat.lessons.model.AttackResult; +import org.owasp.webgoat.endpoints.AssignmentEndpoint; +import org.owasp.webgoat.lessons.AttackResult; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -44,7 +44,7 @@ import java.io.StringReader; * @version $Id: $Id * @since November 17, 2016 */ -public class SimpleXXE extends Assignment { +public class SimpleXXE extends AssignmentEndpoint { private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"}; private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};