From f12c06fc5518940e8c58cb66e0c435eac8a03824 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 29 Jun 2016 00:23:29 +0200 Subject: [PATCH] Reading yml file based lesson configuration --- .../owasp/webgoat/controller/StartLesson.java | 4 +- .../owasp/webgoat/lessons/AbstractLesson.java | 2 - .../webgoat/plugins/LessonConfiguration.java | 36 +++++++ .../org/owasp/webgoat/plugins/Plugin.java | 97 +++++++++++++------ .../webgoat/plugins/PluginLoadingFailure.java | 9 ++ .../owasp/webgoat/plugins/YmlBasedLesson.java | 78 +++++++++++++++ .../resources/templates/lesson_content.html | 2 +- 7 files changed, 193 insertions(+), 35 deletions(-) create mode 100644 webgoat-container/src/main/java/org/owasp/webgoat/plugins/LessonConfiguration.java create mode 100644 webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java index 1256d50f52..65ddfbcabf 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java @@ -31,6 +31,7 @@ package org.owasp.webgoat.controller; import org.owasp.webgoat.lessons.RandomLessonAdapter; +import org.owasp.webgoat.plugins.YmlBasedLesson; import org.owasp.webgoat.session.WebSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -63,7 +64,8 @@ public ModelAndView start(HttpServletRequest request) { model.addObject("lesson", ws.getCurrentLesson()); model.addObject("message", ws.getMessage()); model.addObject("instructions", ws.getInstructions()); - model.addObject("migrated", refactored.contains(ws.getCurrentLesson().getClass().getSimpleName())); //remove after ECS removal otherwise you will see the lesson twice + boolean isMigrated = ws.getCurrentLesson() instanceof YmlBasedLesson; + model.addObject("migrated", isMigrated); //remove after ECS removal otherwise you will see the lesson twice model.setViewName("lesson_content"); return model; } 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 bd0cd65df0..933545d104 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 @@ -998,6 +998,4 @@ protected LabelManager getLabelManager() { } return labelManager; } - - } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/LessonConfiguration.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/LessonConfiguration.java new file mode 100644 index 0000000000..8a96c6655b --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/LessonConfiguration.java @@ -0,0 +1,36 @@ +package org.owasp.webgoat.plugins; + +/** + * ************************************************************************************************ + * 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 WebGoat + * @version $Id: $Id + * @since June 28, 2016 + */ +public class LessonConfiguration { + + private String title; + +} 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 82608ea22c..f1074c72bd 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 @@ -1,27 +1,29 @@ package org.owasp.webgoat.plugins; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.common.base.Optional; import com.google.common.collect.Lists; +import org.apache.commons.io.FileUtils; import org.owasp.webgoat.lessons.AbstractLesson; import org.springframework.util.StringUtils; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith; import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithName; -import static org.owasp.webgoat.plugins.PluginFileUtils.replaceInFiles; /** *

Plugin class.

* - * @version $Id: $Id * @author dm + * @version $Id: $Id */ public class Plugin { @@ -30,6 +32,7 @@ public class Plugin { private PluginClassLoader classLoader; private Class lesson; + private YmlBasedLesson ymlBasedLesson; private Map solutionLanguageFiles = new HashMap<>(); private Map lessonPlansLanguageFiles = new HashMap<>(); private List pluginFiles = Lists.newArrayList(); @@ -51,6 +54,7 @@ public void findLesson(List classes) { } private void findLesson(String name) { + //Old code remove after we migrated the lessons String realClassName = StringUtils.trimLeadingCharacter(name, '/').replaceAll("/", ".").replaceAll(".class", ""); try { @@ -62,6 +66,33 @@ private void findLesson(String name) { } catch (ClassNotFoundException ce) { throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.", ce); } + + //New code all lessons should work as below + if (this.lesson == null) { + readYmlLessonConfiguration(); + } + } + + private void readYmlLessonConfiguration() { + java.util.Optional ymlFile = this.pluginFiles.stream().filter(f -> f.getName().endsWith(".yml")).findFirst(); + if (ymlFile.isPresent()) { + try { + String ymlStr = FileUtils.readFileToString(ymlFile.get()); + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + Map ymlAsMap = mapper.readValue(ymlStr, new TypeReference>() { + }); + Map lessonYml = (Map) ymlAsMap.get("lesson"); + final String category = (String) lessonYml.get("category"); + final List hints = (List) lessonYml.get("hints"); + final String title = (String) lessonYml.get("title"); + final String html = (String) lessonYml.get("html"); + this.ymlBasedLesson = new YmlBasedLesson(category, hints, title, html); + } catch (IOException e) { + throw new PluginLoadingFailure("Unable to read yml file", e); + } + } + + } /** @@ -80,7 +111,7 @@ public void loadFiles(Path file) { lessonSourceFile = file.toFile(); } - if (fileEndsWith(file, ".css", ".jsp", ".js")) { + if (fileEndsWith(file, ".css", ".jsp", ".js", ".yml")) { pluginFiles.add(file.toFile()); } } @@ -91,33 +122,33 @@ public void loadFiles(Path file) { * @param pluginTarget a {@link java.nio.file.Path} object. */ public void rewritePaths(Path pluginTarget) { - try { - replaceInFiles(this.lesson.getSimpleName() + "_files", - "plugin_lessons/plugin/" + this.lesson - .getSimpleName() + "/lessonSolutions/en/" + this.lesson.getSimpleName() + "_files", - solutionLanguageFiles.values()); - replaceInFiles(this.lesson.getSimpleName() + "_files", - "plugin_lessons/plugin/" + this.lesson - .getSimpleName() + "/lessonPlans/en/" + this.lesson.getSimpleName() + "_files", - lessonPlansLanguageFiles.values()); - - String[] replacements = {"jsp", "js"}; - for (String replacement : replacements) { - String s = String.format("plugin/%s/%s/", this.lesson.getSimpleName(), replacement); - String r = String.format("plugin_lessons/plugin/s/%s/", this.lesson.getSimpleName(), replacement); - replaceInFiles(s, r, pluginFiles); - replaceInFiles(s, r, Arrays.asList(lessonSourceFile)); - } - - //CSS with url('/plugin/images') should not begin with / otherwise image cannot be found - String s = String.format("/plugin/%s/images/", this.lesson.getSimpleName()); - String r = String - .format("plugin_lessons/plugin/%s/images/", this.lesson.getSimpleName()); - replaceInFiles(s, r, pluginFiles); - replaceInFiles(s, r, Arrays.asList(lessonSourceFile)); - } catch (IOException e) { - throw new PluginLoadingFailure("Unable to rewrite the paths in the solutions", e); - } +// try { +// replaceInFiles(this.lesson.getSimpleName() + "_files", +// "plugin_lessons/plugin/" + this.lesson +// .getSimpleName() + "/lessonSolutions/en/" + this.lesson.getSimpleName() + "_files", +// solutionLanguageFiles.values()); +// replaceInFiles(this.lesson.getSimpleName() + "_files", +// "plugin_lessons/plugin/" + this.lesson +// .getSimpleName() + "/lessonPlans/en/" + this.lesson.getSimpleName() + "_files", +// lessonPlansLanguageFiles.values()); +// +// String[] replacements = {"jsp", "js"}; +// for (String replacement : replacements) { +// String s = String.format("plugin/%s/%s/", this.lesson.getSimpleName(), replacement); +// String r = String.format("plugin_lessons/plugin/s/%s/", this.lesson.getSimpleName(), replacement); +// replaceInFiles(s, r, pluginFiles); +// replaceInFiles(s, r, Arrays.asList(lessonSourceFile)); +// } +// +// //CSS with url('/plugin/images') should not begin with / otherwise image cannot be found +// String s = String.format("/plugin/%s/images/", this.lesson.getSimpleName()); +// String r = String +// .format("plugin_lessons/plugin/%s/images/", this.lesson.getSimpleName()); +// replaceInFiles(s, r, pluginFiles); +// replaceInFiles(s, r, Arrays.asList(lessonSourceFile)); +// } catch (IOException e) { +// throw new PluginLoadingFailure("Unable to rewrite the paths in the solutions", e); +// } } /** @@ -127,9 +158,13 @@ public void rewritePaths(Path pluginTarget) { */ public Optional getLesson() { try { + if (ymlBasedLesson != null) { + return Optional.of(ymlBasedLesson); + } if (lesson != null) { return Optional.of(lesson.newInstance()); } + } catch (IllegalAccessException | InstantiationException e) { throw new PluginLoadingFailure("Unable to instantiate the lesson " + lesson.getName(), e); } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginLoadingFailure.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginLoadingFailure.java index ec91047913..007228ddbe 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginLoadingFailure.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginLoadingFailure.java @@ -8,6 +8,15 @@ */ public class PluginLoadingFailure extends RuntimeException { + /** + *

Constructor for PluginLoadingFailure.

+ * + * @param message a {@link java.lang.String} object. + */ + public PluginLoadingFailure(String message) { + super(message); + } + /** *

Constructor for PluginLoadingFailure.

* diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java new file mode 100644 index 0000000000..86e983b9bb --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java @@ -0,0 +1,78 @@ +package org.owasp.webgoat.plugins; + +import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.lessons.LessonAdapter; +import org.owasp.webgoat.session.WebSession; + +import java.util.List; + +/** + * ************************************************************************************************ + * 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 WebGoat + * @version $Id: $Id + * @since June 28, 2016 + */ +public class YmlBasedLesson extends LessonAdapter { + + private final static Integer DEFAULT_RANKING = new Integer(10); + private final String category; + private final List hints; + private final String title; + private final String html; + + public YmlBasedLesson(String category, List hints, String title, String html) { + this.category = category; + this.hints = hints; + this.title = title; + this.html = html; + } + + @Override + protected Category getDefaultCategory() { + return Category.getCategory(category); + } + + @Override + protected List getHints(WebSession s) { + return hints; + } + + @Override + protected Integer getDefaultRanking() { + return DEFAULT_RANKING; + } + + @Override + public String getTitle() { + return title; + } + + public String getHtml() { + return html; + } + + +} diff --git a/webgoat-container/src/main/resources/templates/lesson_content.html b/webgoat-container/src/main/resources/templates/lesson_content.html index 1753ca92f6..5572abf425 100644 --- a/webgoat-container/src/main/resources/templates/lesson_content.html +++ b/webgoat-container/src/main/resources/templates/lesson_content.html @@ -14,7 +14,7 @@

-
+