Merge pull request #74 from nbaars/master
Property files are now detected while extracting the plugin
This commit is contained in:
commit
ba6997f52f
@ -24,7 +24,6 @@ public class Plugin {
|
|||||||
|
|
||||||
private static final String NAME_LESSON_SOLUTION_DIRECTORY = "lessonSolutions";
|
private static final String NAME_LESSON_SOLUTION_DIRECTORY = "lessonSolutions";
|
||||||
private static final String NAME_LESSON_PLANS_DIRECTORY = "lessonPlans";
|
private static final String NAME_LESSON_PLANS_DIRECTORY = "lessonPlans";
|
||||||
private static final String NAME_LESSON_I18N_DIRECTORY = "i18n";
|
|
||||||
private final Path pluginDirectory;
|
private final Path pluginDirectory;
|
||||||
|
|
||||||
private Class<AbstractLesson> lesson;
|
private Class<AbstractLesson> lesson;
|
||||||
@ -61,7 +60,15 @@ public class Plugin {
|
|||||||
this.lesson = clazz;
|
this.lesson = clazz;
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException ce) {
|
} catch (ClassNotFoundException ce) {
|
||||||
throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.", ce);
|
throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.",
|
||||||
|
ce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadProperties(List<Path> properties) {
|
||||||
|
for (Path propertyFile : properties) {
|
||||||
|
LabelProvider.updatePluginResources(propertyFile);
|
||||||
|
LabelProvider.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,35 +83,13 @@ public class Plugin {
|
|||||||
if (fileEndsWith(file, ".java")) {
|
if (fileEndsWith(file, ".java")) {
|
||||||
lessonSourceFile = file.toFile();
|
lessonSourceFile = file.toFile();
|
||||||
}
|
}
|
||||||
if (fileEndsWith(file, ".properties") && hasParentDirectoryWithName(file, NAME_LESSON_I18N_DIRECTORY)) {
|
|
||||||
copyProperties(reload, file);
|
|
||||||
}
|
|
||||||
if (fileEndsWith(file, ".css", ".jsp", ".js")) {
|
if (fileEndsWith(file, ".css", ".jsp", ".js")) {
|
||||||
pluginFiles.add(file.toFile());
|
pluginFiles.add(file.toFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyProperties(boolean reload, Path file) {
|
|
||||||
try {
|
|
||||||
byte[] lines = Files.readAllBytes(file);
|
|
||||||
Path propertiesPath = createPropertiesDirectory();
|
|
||||||
LabelProvider.updatePluginResources(propertiesPath);
|
|
||||||
PluginFileUtils.createDirsIfNotExists(file.getParent());
|
|
||||||
Files.write(propertiesPath.resolve(file.getFileName()), lines);
|
|
||||||
} catch (IOException io) {
|
|
||||||
throw new PluginLoadingFailure("Property file detected, but unable to copy the properties", io);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Path createPropertiesDirectory() throws IOException {
|
|
||||||
if (Files.exists(pluginDirectory.resolve(NAME_LESSON_I18N_DIRECTORY))) {
|
|
||||||
return pluginDirectory.resolve(NAME_LESSON_I18N_DIRECTORY);
|
|
||||||
} else {
|
|
||||||
return Files.createDirectory(pluginDirectory.resolve(NAME_LESSON_I18N_DIRECTORY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rewritePaths(Path pluginTarget) {
|
public void rewritePaths(Path pluginTarget) {
|
||||||
try {
|
try {
|
||||||
replaceInFiles(this.lesson.getSimpleName() + "_files",
|
replaceInFiles(this.lesson.getSimpleName() + "_files",
|
||||||
@ -117,19 +102,20 @@ public class Plugin {
|
|||||||
lessonPlansLanguageFiles.values());
|
lessonPlansLanguageFiles.values());
|
||||||
|
|
||||||
String[] replacements = {"jsp", "js"};
|
String[] replacements = {"jsp", "js"};
|
||||||
for ( String replacement : replacements ) {
|
for (String replacement : replacements) {
|
||||||
String s = String.format("plugin/%s/%s/", this.lesson.getSimpleName(), replacement);
|
String s = String.format("plugin/%s/%s/", this.lesson.getSimpleName(), replacement);
|
||||||
String r = String.format("%s/plugin/%s/%s/", pluginTarget.getFileName().toString(),
|
String r = String.format("%s/plugin/%s/%s/", pluginTarget.getFileName().toString(),
|
||||||
this.lesson.getSimpleName(), replacement);
|
this.lesson.getSimpleName(), replacement);
|
||||||
replaceInFiles(s,r, pluginFiles);
|
replaceInFiles(s, r, pluginFiles);
|
||||||
replaceInFiles(s,r, Arrays.asList(lessonSourceFile));
|
replaceInFiles(s, r, Arrays.asList(lessonSourceFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
//CSS with url('/plugin/images') should not begin with / otherwise image cannot be found
|
//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 s = String.format("/plugin/%s/images/", this.lesson.getSimpleName());
|
||||||
String r = String.format("%s/plugin/%s/images/", pluginTarget.getFileName().toString(), this.lesson.getSimpleName());
|
String r = String
|
||||||
replaceInFiles(s,r, pluginFiles);
|
.format("%s/plugin/%s/images/", pluginTarget.getFileName().toString(), this.lesson.getSimpleName());
|
||||||
replaceInFiles(s,r, Arrays.asList(lessonSourceFile));
|
replaceInFiles(s, r, pluginFiles);
|
||||||
|
replaceInFiles(s, r, Arrays.asList(lessonSourceFile));
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -19,6 +19,8 @@ import java.util.List;
|
|||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||||
import static org.owasp.webgoat.plugins.PluginFileUtils.createDirsIfNotExists;
|
import static org.owasp.webgoat.plugins.PluginFileUtils.createDirsIfNotExists;
|
||||||
|
import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith;
|
||||||
|
import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the jar file and place them in the system temp directory in the folder webgoat and collect the files
|
* Extract the jar file and place them in the system temp directory in the folder webgoat and collect the files
|
||||||
@ -26,9 +28,11 @@ import static org.owasp.webgoat.plugins.PluginFileUtils.createDirsIfNotExists;
|
|||||||
*/
|
*/
|
||||||
public class PluginExtractor {
|
public class PluginExtractor {
|
||||||
|
|
||||||
|
private static final String NAME_LESSON_I18N_DIRECTORY = "i18n";
|
||||||
private final Path pluginArchive;
|
private final Path pluginArchive;
|
||||||
private final List<String> classes = Lists.newArrayList();
|
private final List<String> classes = Lists.newArrayList();
|
||||||
private final List<Path> files = new ArrayList<>();
|
private final List<Path> files = new ArrayList<>();
|
||||||
|
private final List<Path> properties = new ArrayList<>();
|
||||||
|
|
||||||
public PluginExtractor(Path pluginArchive) {
|
public PluginExtractor(Path pluginArchive) {
|
||||||
this.pluginArchive = pluginArchive;
|
this.pluginArchive = pluginArchive;
|
||||||
@ -43,7 +47,14 @@ public class PluginExtractor {
|
|||||||
if (file.toString().endsWith(".class")) {
|
if (file.toString().endsWith(".class")) {
|
||||||
classes.add(file.toString());
|
classes.add(file.toString());
|
||||||
}
|
}
|
||||||
files.add(Files.copy(file, createDirsIfNotExists(Paths.get(target.toString(), file.toString())), REPLACE_EXISTING));
|
if (fileEndsWith(file, ".properties") && hasParentDirectoryWithName(file,
|
||||||
|
NAME_LESSON_I18N_DIRECTORY)) {
|
||||||
|
properties.add(Files
|
||||||
|
.copy(file, createDirsIfNotExists(Paths.get(target.toString(), file.toString())),
|
||||||
|
REPLACE_EXISTING));
|
||||||
|
}
|
||||||
|
files.add(Files.copy(file, createDirsIfNotExists(Paths.get(target.toString(), file.toString())),
|
||||||
|
REPLACE_EXISTING));
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -60,10 +71,12 @@ public class PluginExtractor {
|
|||||||
return this.files;
|
return this.files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Path> getProperties() {
|
||||||
|
return this.properties;
|
||||||
|
}
|
||||||
|
|
||||||
private FileSystem createZipFileSystem() throws Exception {
|
private FileSystem createZipFileSystem() throws Exception {
|
||||||
final URI uri = URI.create("jar:file:" + pluginArchive.toUri().getPath());
|
final URI uri = URI.create("jar:file:" + pluginArchive.toUri().getPath());
|
||||||
return FileSystems.newFileSystem(uri, new HashMap<String, Object>());
|
return FileSystems.newFileSystem(uri, new HashMap<String, Object>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ public class PluginsLoader implements Runnable {
|
|||||||
if (plugin.getLesson().isPresent()) {
|
if (plugin.getLesson().isPresent()) {
|
||||||
PluginFileUtils.createDirsIfNotExists(pluginTarget);
|
PluginFileUtils.createDirsIfNotExists(pluginTarget);
|
||||||
plugin.loadFiles(extractor.getFiles(), reload);
|
plugin.loadFiles(extractor.getFiles(), reload);
|
||||||
|
plugin.loadProperties(extractor.getProperties());
|
||||||
plugin.rewritePaths(pluginTarget);
|
plugin.rewritePaths(pluginTarget);
|
||||||
plugins.add(plugin);
|
plugins.add(plugin);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import org.springframework.core.io.Resource;
|
|||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.core.io.UrlResource;
|
import org.springframework.core.io.UrlResource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.DefaultPropertiesPersister;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
@ -58,6 +59,9 @@ public class LabelProvider {
|
|||||||
labels.setFallbackToSystemLocale(false);
|
labels.setFallbackToSystemLocale(false);
|
||||||
labels.setUseCodeAsDefaultMessage(true);
|
labels.setUseCodeAsDefaultMessage(true);
|
||||||
pluginLabels.setParentMessageSource(labels);
|
pluginLabels.setParentMessageSource(labels);
|
||||||
|
pluginLabels.setPropertiesPersister(new DefaultPropertiesPersister() {
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updatePluginResources(final Path propertyFile) {
|
public static void updatePluginResources(final Path propertyFile) {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package org.owasp.webgoat.plugins;
|
package org.owasp.webgoat.plugins;
|
||||||
|
|
||||||
import com.saucelabs.common.SauceOnDemandAuthentication;
|
import com.saucelabs.common.SauceOnDemandAuthentication;
|
||||||
|
import com.saucelabs.common.SauceOnDemandSessionIdProvider;
|
||||||
|
import com.saucelabs.junit.ConcurrentParameterized;
|
||||||
|
import com.saucelabs.junit.SauceOnDemandTestWatcher;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@ -14,19 +16,14 @@ import org.openqa.selenium.WebElement;
|
|||||||
import org.openqa.selenium.remote.CapabilityType;
|
import org.openqa.selenium.remote.CapabilityType;
|
||||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||||
import org.openqa.selenium.remote.RemoteWebDriver;
|
import org.openqa.selenium.remote.RemoteWebDriver;
|
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||||
import com.saucelabs.junit.ConcurrentParameterized;
|
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||||
import com.saucelabs.junit.SauceOnDemandTestWatcher;
|
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import com.saucelabs.common.SauceOnDemandSessionIdProvider;
|
|
||||||
|
|
||||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
|
||||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -249,7 +246,7 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
|
|||||||
|
|
||||||
String pageSource = driver.getPageSource();
|
String pageSource = driver.getPageSource();
|
||||||
|
|
||||||
assertTrue("Page source should contain lessons: Test 1", pageSource.contains("Bypass a Path Based Access Control Scheme"));
|
assertTrue("Page source should contain lessons: Test 1", pageSource.contains("Reflected XSS"));
|
||||||
assertTrue("Page source should contain lessons: Test 2", pageSource.contains("Access Control Flaws"));
|
assertTrue("Page source should contain lessons: Test 2", pageSource.contains("Access Control Flaws"));
|
||||||
assertTrue("Page source should contain lessons: Test 3", pageSource.contains("Improper Error Handling"));
|
assertTrue("Page source should contain lessons: Test 3", pageSource.contains("Improper Error Handling"));
|
||||||
assertTrue("Page source should contain lessons: Test 34", pageSource.contains("Fail Open Authentication Scheme"));
|
assertTrue("Page source should contain lessons: Test 34", pageSource.contains("Fail Open Authentication Scheme"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user