Merge pull request #34 from nbaars/webgoat-container
This looks good. Nice improvements
This commit is contained in:
commit
f6a839251a
@ -0,0 +1,24 @@
|
|||||||
|
package org.owasp.webgoat.plugins;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class GlobalProperties {
|
||||||
|
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
public GlobalProperties(Path pluginDirectory) {
|
||||||
|
this.plugin = new Plugin(pluginDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadProperties(Path globalPropertiesPath) {
|
||||||
|
try {
|
||||||
|
List<Path> filesInDirectory = PluginFileUtils.getFilesInDirectory(globalPropertiesPath);
|
||||||
|
this.plugin.loadFiles(filesInDirectory, true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException("Unable to load global properties, check your installation for the directory i18n: " + globalPropertiesPath.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,11 +11,13 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.nio.file.StandardOpenOption.APPEND;
|
||||||
|
import static java.nio.file.StandardOpenOption.CREATE;
|
||||||
|
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||||
import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith;
|
import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith;
|
||||||
import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithName;
|
import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithName;
|
||||||
|
|
||||||
@ -96,9 +98,9 @@ public class Plugin {
|
|||||||
Path propertiesPath = createPropertiesDirectory();
|
Path propertiesPath = createPropertiesDirectory();
|
||||||
ResourceBundleClassLoader.setPropertiesPath(propertiesPath);
|
ResourceBundleClassLoader.setPropertiesPath(propertiesPath);
|
||||||
if ( reload ) {
|
if ( reload ) {
|
||||||
Files.write(propertiesPath.resolve(file.getFileName()), bos.toByteArray(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
Files.write(propertiesPath.resolve(file.getFileName()), bos.toByteArray(), CREATE, APPEND);
|
||||||
} else {
|
} else {
|
||||||
Files.write(propertiesPath.resolve(file.getFileName()), bos.toByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
Files.write(propertiesPath.resolve(file.getFileName()), bos.toByteArray(), CREATE, TRUNCATE_EXISTING);
|
||||||
}
|
}
|
||||||
} catch (IOException io) {
|
} catch (IOException io) {
|
||||||
throw new PluginLoadingFailure("Property file detected, but unable to copy the properties", io);
|
throw new PluginLoadingFailure("Property file detected, but unable to copy the properties", io);
|
||||||
@ -118,9 +120,9 @@ public class Plugin {
|
|||||||
for (Map.Entry<String, File> html : solutionLanguageFiles.entrySet()) {
|
for (Map.Entry<String, File> html : solutionLanguageFiles.entrySet()) {
|
||||||
byte[] htmlFileAsBytes = Files.readAllBytes(Paths.get(html.getValue().toURI()));
|
byte[] htmlFileAsBytes = Files.readAllBytes(Paths.get(html.getValue().toURI()));
|
||||||
String htmlFile = new String(htmlFileAsBytes);
|
String htmlFile = new String(htmlFileAsBytes);
|
||||||
htmlFile = htmlFile.replaceAll(this.lesson.getSimpleName() + "_files", pluginTarget.getFileName().toString() + "/lessons/plugin/SqlStringInjection/lessonSolutions/en/" + this.lesson.getSimpleName() + "_files");
|
htmlFile = htmlFile.replaceAll("lesson_solutions/" + this.lesson.getSimpleName() + "_files", pluginTarget.getFileName().toString() + "/lessons/plugin/" + this.lesson.getSimpleName() + "/lessonSolutions/en/" + this.lesson.getSimpleName() + "_files");
|
||||||
Files.write(Paths.get(html.getValue().toURI()), htmlFile.getBytes(), StandardOpenOption.CREATE,
|
Files.write(Paths.get(html.getValue().toURI()), htmlFile.getBytes(), CREATE,
|
||||||
StandardOpenOption.TRUNCATE_EXISTING);
|
TRUNCATE_EXISTING);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginLoadingFailure("Unable to rewrite the paths in the solutions", e);
|
throw new PluginLoadingFailure("Unable to rewrite the paths in the solutions", e);
|
||||||
@ -143,4 +145,5 @@ public class Plugin {
|
|||||||
public Map<String, File> getLessonPlans() {
|
public Map<String, File> getLessonPlans() {
|
||||||
return this.lessonPlansLanguageFiles;
|
return this.lessonPlansLanguageFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public class PluginFileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasParentDirectoryWithName(Path p, String s) {
|
public static boolean hasParentDirectoryWithName(Path p, String s) {
|
||||||
if (p == null || p.getParent() == null || p.getRoot().equals(p.getParent())) {
|
if (p == null || p.getParent() == null || p.getParent().equals(p.getRoot())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (p.getParent().getFileName().toString().equals(s)) {
|
if (p.getParent().getFileName().toString().equals(s)) {
|
||||||
@ -31,8 +31,7 @@ public class PluginFileUtils {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Path> getFilesInDirectory( Path directory) throws IOException
|
public static List<Path> getFilesInDirectory( Path directory) throws IOException {
|
||||||
{
|
|
||||||
List<Path> files = new ArrayList<>();
|
List<Path> files = new ArrayList<>();
|
||||||
DirectoryStream<Path> dirStream;
|
DirectoryStream<Path> dirStream;
|
||||||
dirStream = Files.newDirectoryStream(directory);
|
dirStream = Files.newDirectoryStream(directory);
|
||||||
|
@ -3,6 +3,7 @@ package org.owasp.webgoat.session;
|
|||||||
import org.owasp.webgoat.HammerHead;
|
import org.owasp.webgoat.HammerHead;
|
||||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
import org.owasp.webgoat.lessons.Category;
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.plugins.GlobalProperties;
|
||||||
import org.owasp.webgoat.plugins.Plugin;
|
import org.owasp.webgoat.plugins.Plugin;
|
||||||
import org.owasp.webgoat.plugins.PluginFileUtils;
|
import org.owasp.webgoat.plugins.PluginFileUtils;
|
||||||
import org.owasp.webgoat.plugins.PluginsLoader;
|
import org.owasp.webgoat.plugins.PluginsLoader;
|
||||||
@ -284,7 +285,6 @@ public class Course {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadLessonFromPlugin(ServletContext context) {
|
private void loadLessonFromPlugin(ServletContext context) {
|
||||||
context.getContextPath();
|
|
||||||
logger.debug("Loading plugins into cache");
|
logger.debug("Loading plugins into cache");
|
||||||
String pluginPath = context.getRealPath("plugin_lessons");
|
String pluginPath = context.getRealPath("plugin_lessons");
|
||||||
String targetPath = context.getRealPath("plugin_extracted");
|
String targetPath = context.getRealPath("plugin_extracted");
|
||||||
@ -292,17 +292,8 @@ public class Course {
|
|||||||
logger.error("Plugins directory {} not found", pluginPath);
|
logger.error("Plugins directory {} not found", pluginPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
new GlobalProperties(Paths.get(targetPath)).loadProperties(Paths.get(context.getRealPath("container//i18n")));
|
||||||
|
|
||||||
// Do a one time load of the container properties
|
|
||||||
String containerPath = context.getRealPath("container//i18n");
|
|
||||||
Plugin theContainer = new Plugin(Paths.get(targetPath));
|
|
||||||
try {
|
|
||||||
theContainer.loadFiles(PluginFileUtils.getFilesInDirectory(Paths.get(containerPath)), false);
|
|
||||||
} catch (IOException io) {
|
|
||||||
logger.error("Error loading container properties: ", io);
|
|
||||||
}
|
|
||||||
|
|
||||||
Path pluginDirectory = Paths.get(pluginPath);
|
|
||||||
List<Plugin> plugins = new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins(true);
|
List<Plugin> plugins = new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins(true);
|
||||||
for (Plugin plugin : plugins) {
|
for (Plugin plugin : plugins) {
|
||||||
try {
|
try {
|
||||||
@ -314,7 +305,7 @@ public class Course {
|
|||||||
|
|
||||||
lesson.update(properties);
|
lesson.update(properties);
|
||||||
|
|
||||||
if (lesson.getHidden() == false) {
|
if (!lesson.getHidden()) {
|
||||||
lessons.add(lesson);
|
lessons.add(lesson);
|
||||||
}
|
}
|
||||||
for(Map.Entry<String, File> lessonPlan : plugin.getLessonPlans().entrySet()) {
|
for(Map.Entry<String, File> lessonPlan : plugin.getLessonPlans().entrySet()) {
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.owasp.webgoat.plugins;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
public class GlobalPropertiesTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void propertyFilesShouldBeLoaded() throws IOException {
|
||||||
|
Path tempDirectory = PluginTestHelper.createTmpDir();
|
||||||
|
Path pluginDirectory = Files.createDirectory(Paths.get(tempDirectory.toString(), "plugins"));
|
||||||
|
Path directory = Files.createDirectory(Paths.get(tempDirectory.toString(), "i18n"));
|
||||||
|
Path globalProperties = Files.createFile(Paths.get(directory.toString(), "global.properties"));
|
||||||
|
Files.write(globalProperties, Arrays.asList("test=label for test"), StandardCharsets.UTF_8);
|
||||||
|
new GlobalProperties(pluginDirectory).loadProperties(directory);
|
||||||
|
|
||||||
|
ClassLoader propertyFilesClassLoader =
|
||||||
|
ResourceBundleClassLoader.createPropertyFilesClassLoader(this.getClass().getClassLoader());
|
||||||
|
assertNotNull(propertyFilesClassLoader.getResourceAsStream("global.properties"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void propertyFilesDirectoryNotFoundShouldRaiseError() throws IOException {
|
||||||
|
Path tempDirectory = PluginTestHelper.createTmpDir();
|
||||||
|
Path pluginDirectory = Files.createDirectory(Paths.get(tempDirectory.toString(), "plugins"));
|
||||||
|
Path directory = Files.createDirectory(Paths.get(tempDirectory.toString(), "i18n"));
|
||||||
|
Files.delete(directory);
|
||||||
|
|
||||||
|
new GlobalProperties(pluginDirectory).loadProperties(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
src/test/java/org/owasp/webgoat/plugins/PluginTest.java
Normal file
45
src/test/java/org/owasp/webgoat/plugins/PluginTest.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package org.owasp.webgoat.plugins;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.matchers.JUnitMatchers.containsString;
|
||||||
|
import static org.junit.matchers.JUnitMatchers.hasItem;
|
||||||
|
|
||||||
|
public class PluginTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathShouldBeRewrittenInHtmlFile() throws Exception {
|
||||||
|
Path tmpDir = PluginTestHelper.createTmpDir();
|
||||||
|
Path pluginSourcePath = PluginTestHelper.pathForLoading();
|
||||||
|
Plugin plugin = PluginTestHelper.createPluginFor(TestPlugin.class);
|
||||||
|
Path htmlFile = Paths.get(pluginSourcePath.toString(), "lessonSolutions", "rewrite_test.html");
|
||||||
|
plugin.loadFiles(Arrays.asList(htmlFile), true);
|
||||||
|
plugin.rewritePaths(tmpDir);
|
||||||
|
List<String> allLines = Files.readAllLines(htmlFile, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
assertThat(allLines,
|
||||||
|
hasItem(containsString("lessons/plugin/TestPlugin/lessonSolutions/en/TestPlugin_files/image001.png")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotRewriteOtherLinksStartingWithLesson_solutions() throws Exception {
|
||||||
|
Path tmpDir = PluginTestHelper.createTmpDir();
|
||||||
|
Path pluginSourcePath = PluginTestHelper.pathForLoading();
|
||||||
|
Plugin plugin = PluginTestHelper.createPluginFor(TestPlugin.class);
|
||||||
|
Path htmlFile = Paths.get(pluginSourcePath.toString(), "lessonSolutions", "rewrite_test.html");
|
||||||
|
plugin.loadFiles(Arrays.asList(htmlFile), true);
|
||||||
|
plugin.rewritePaths(tmpDir);
|
||||||
|
List<String> allLines = Files.readAllLines(htmlFile, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
assertThat(allLines,
|
||||||
|
hasItem(containsString("lesson_solutions/Unknown_files/image001.png")));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.owasp.webgoat.plugins;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PluginTestHelper {
|
||||||
|
|
||||||
|
private static Path tempDirectory;
|
||||||
|
|
||||||
|
public static Path createTmpDir() throws IOException {
|
||||||
|
tempDirectory = Files.createTempDirectory(PluginTestHelper.class.getSimpleName());
|
||||||
|
tempDirectory.toFile().deleteOnExit();
|
||||||
|
return tempDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path pathForLoading() throws IOException, URISyntaxException {
|
||||||
|
Path path = Paths.get(PluginTestHelper.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||||
|
return Paths.get(path.toString(), "org/owasp/webgoat/plugins");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Plugin createPluginFor(Class pluginClass) throws Exception {
|
||||||
|
Path pluginTargetPath = Files.createDirectory(Paths.get(tempDirectory.toString(), "pluginTargetPath"));
|
||||||
|
Plugin plugin = new Plugin(pluginTargetPath);
|
||||||
|
Map<String, byte[]> classes = new HashMap<>();
|
||||||
|
classes.put(pluginClass.getName(), Files.readAllBytes(Paths.get(pathForLoading().toString(), pluginClass.getSimpleName() + ".class")));
|
||||||
|
plugin.loadClasses(classes);
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
}
|
6
src/test/java/org/owasp/webgoat/plugins/TestPlugin.java
Normal file
6
src/test/java/org/owasp/webgoat/plugins/TestPlugin.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package org.owasp.webgoat.plugins;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.SequentialLessonAdapter;
|
||||||
|
|
||||||
|
public class TestPlugin extends SequentialLessonAdapter {
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head lang="en">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<v:imagedata src="lesson_solutions/TestPlugin_files/image001.png" o:title=""/>
|
||||||
|
<v:imagedata src="lesson_solutions/Unknown_files/image001.png" o:title=""/>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user