Merge branch 'feature/spring-boot' of https://github.com/WebGoat/WebGoat into feature/spring-boot
This commit is contained in:
commit
dad7bdba92
@ -161,11 +161,7 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
@ -264,6 +260,11 @@
|
||||
|
||||
<!-- ************* END spring MVC and related dependencies ************** -->
|
||||
<!-- ************* START: Dependencies for Unit and Integration Testing ************** -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
@ -52,7 +52,6 @@ public class HammerHead {
|
||||
/**
|
||||
* Entry point for WebGoat, redirects to the first lesson found within the course.
|
||||
*/
|
||||
//// TODO: 11/6/2016 course necessary?
|
||||
@RequestMapping(path = "/attack", method = {RequestMethod.GET, RequestMethod.POST})
|
||||
public ModelAndView attack() {
|
||||
return new ModelAndView("redirect:" + "start.mvc" + course.getFirstLesson().getLink());
|
||||
|
@ -30,14 +30,17 @@
|
||||
*/
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.owasp.webgoat.plugins.Plugin;
|
||||
import org.owasp.webgoat.plugins.PluginClassLoader;
|
||||
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
|
||||
import org.owasp.webgoat.plugins.PluginsLoader;
|
||||
import org.owasp.webgoat.session.Course;
|
||||
import org.owasp.webgoat.session.UserTracker;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.owasp.webgoat.session.WebgoatContext;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
@ -62,15 +65,10 @@ public class WebGoat extends SpringBootServletInitializer {
|
||||
}
|
||||
|
||||
@Bean(name = "pluginTargetDirectory")
|
||||
public File pluginTargetDirectory() {
|
||||
return com.google.common.io.Files.createTempDir();
|
||||
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
|
||||
return new File(webgoatHome);
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public ApplicationListener<ContextClosedEvent> closeEvent(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory) {
|
||||
// return e -> pluginTargetDirectory.delete();
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public PluginClassLoader pluginClassLoader() {
|
||||
return new PluginClassLoader(PluginClassLoader.class.getClassLoader());
|
||||
@ -96,4 +94,14 @@ public class WebGoat extends SpringBootServletInitializer {
|
||||
|
||||
return course;
|
||||
}
|
||||
|
||||
@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());
|
||||
userTracker.load();
|
||||
return userTracker;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.owasp.webgoat.session.Screen;
|
||||
|
||||
import java.util.List;
|
||||
@ -42,6 +44,10 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
||||
|
||||
private Integer ranking;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private List<Class<Assignment>> assignments;
|
||||
|
||||
/**
|
||||
* Constructor for the Lesson object
|
||||
*/
|
||||
@ -49,6 +55,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
||||
id = new Integer(++count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>getName.</p>
|
||||
*
|
||||
@ -135,6 +142,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
||||
|
||||
/**
|
||||
* <p>getHints.</p>
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
public abstract List<String> getHints();
|
||||
@ -198,8 +206,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public String getLink() {
|
||||
StringBuffer link = new StringBuffer(getPath());
|
||||
return link.append(getId()).toString();
|
||||
return String.format("%s%s.lesson", getPath(), getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,7 +218,5 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return "";
|
||||
}
|
||||
public abstract String getId();
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 20014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*/
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
* Extend this class and implement the met
|
||||
* </p>
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,11 @@
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
@ -22,36 +30,16 @@
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*
|
||||
* @author nbaars
|
||||
* @version $Id: $Id
|
||||
* @since November 13, 2016
|
||||
*/
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.owasp.webgoat.session.LessonTracker;
|
||||
import org.owasp.webgoat.session.UserTracker;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
* Extend this class and implement the met
|
||||
* </p>
|
||||
* Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint.
|
||||
*/
|
||||
@LessonEndpointMapping
|
||||
public abstract class AssignmentEndpoint implements MvcEndpoint {
|
||||
public abstract class Endpoint implements MvcEndpoint {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("pluginTargetDirectory")
|
||||
private File pluginDirectory;
|
||||
@Autowired
|
||||
private UserTracker userTracker;
|
||||
|
||||
/**
|
||||
* The directory of the plugin directory in which the lessons resides, so if you want to access the lesson 'ClientSideFiltering' you will
|
||||
@ -69,23 +57,6 @@ public abstract class AssignmentEndpoint implements MvcEndpoint {
|
||||
return new File(this.pluginDirectory, "plugin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lesson tracker which is based on the current user and do the
|
||||
* @return
|
||||
*/
|
||||
protected LessonTracker getLessonTracker() {
|
||||
LessonTracker lessonTracker = userTracker.getCurrentLessonTracker();
|
||||
return lessonTracker;
|
||||
}
|
||||
|
||||
protected AttackResult trackProgress(AttackResult attackResult) {
|
||||
//// TODO: 11/5/2016 improve
|
||||
if (attackResult.isLessonCompleted()) {
|
||||
getLessonTracker().incrementNumVisits();
|
||||
}
|
||||
getLessonTracker().setCompleted(attackResult.isLessonCompleted());
|
||||
return attackResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isSensitive() {
|
||||
@ -93,8 +64,7 @@ public abstract class AssignmentEndpoint implements MvcEndpoint {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Class<? extends Endpoint> getEndpointType() {
|
||||
public final Class<? extends org.springframework.boot.actuate.endpoint.Endpoint> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,7 @@
|
||||
*/
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
//// TODO: 11/8/2016 remove
|
||||
public abstract class LessonAdapter extends AbstractLesson {
|
||||
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
|
||||
/**
|
||||
*************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 20014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*
|
||||
* @author WebGoat
|
||||
* @since December 12, 2015
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation as a marker annotation. During the startup we scan the plugins for classes which use this annotation.
|
||||
* @see AssignmentEndpoint for more information.
|
||||
*/
|
||||
@Component
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LessonEndpointMapping { }
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -37,9 +33,7 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class NewLesson extends LessonAdapter {
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private int totalNumberOfAssignments = 0;
|
||||
|
||||
|
||||
@Override
|
||||
public abstract Category getDefaultCategory();
|
||||
@ -55,10 +49,4 @@ public abstract class NewLesson extends LessonAdapter {
|
||||
@Override
|
||||
public abstract String getId();
|
||||
|
||||
public final List<String> getHints(WebSession w) {
|
||||
throw new IllegalStateException("Do not use");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.owasp.webgoat.lessons.model;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
@ -29,6 +31,7 @@ package org.owasp.webgoat.lessons.model;
|
||||
* @version $Id: $Id
|
||||
* @since August 13, 2016
|
||||
*/
|
||||
@Getter
|
||||
public class AttackResult {
|
||||
|
||||
private boolean lessonCompleted;
|
||||
@ -54,15 +57,7 @@ public class AttackResult {
|
||||
return attackResult;
|
||||
}
|
||||
|
||||
public boolean isLessonCompleted() {
|
||||
public boolean assignmentSolved() {
|
||||
return lessonCompleted;
|
||||
}
|
||||
|
||||
public String getFeedback() {
|
||||
return feedback;
|
||||
}
|
||||
|
||||
public String getOutput() {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.owasp.webgoat.lessons.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
@ -10,6 +11,7 @@ import org.owasp.webgoat.session.WebSession;
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
//// TODO: 11/5/2016 this can be removed???
|
||||
@Getter
|
||||
public class LessonInfoModel {
|
||||
|
||||
private String lessonTitle;
|
||||
|
@ -3,18 +3,16 @@ package org.owasp.webgoat.plugins;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||
import org.owasp.webgoat.lessons.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.Endpoint;
|
||||
import org.owasp.webgoat.lessons.NewLesson;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>Plugin class.</p>
|
||||
@ -24,23 +22,22 @@ import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithNa
|
||||
*/
|
||||
public class Plugin {
|
||||
|
||||
private static final String NAME_LESSON_SOLUTION_DIRECTORY = "lessonSolutions";
|
||||
private static final String NAME_LESSON_PLANS_DIRECTORY = "lessonPlans";
|
||||
|
||||
private PluginClassLoader classLoader;
|
||||
private Class<NewLesson> newLesson;
|
||||
private List<Class<AssignmentEndpoint>> lessonEndpoints = Lists.newArrayList();
|
||||
private Map<String, File> solutionLanguageFiles = new HashMap<>();
|
||||
private Map<String, File> lessonPlansLanguageFiles = new HashMap<>();
|
||||
private List<Class<Assignment>> assignments = Lists.newArrayList();
|
||||
private List<Class<Endpoint>> endpoints = Lists.newArrayList();
|
||||
private List<File> pluginFiles = Lists.newArrayList();
|
||||
private File lessonSourceFile;
|
||||
|
||||
public Plugin(PluginClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
public List<Class<AssignmentEndpoint>> getLessonEndpoints() {
|
||||
return this.lessonEndpoints;
|
||||
public List<Class<Assignment>> getAssignments() {
|
||||
return this.assignments;
|
||||
}
|
||||
|
||||
public List<Class<Endpoint>> getEndpoints() {
|
||||
return this.endpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,8 +71,10 @@ public class Plugin {
|
||||
try {
|
||||
Class clazz = classLoader.loadClass(realClassName);
|
||||
|
||||
if (AssignmentEndpoint.class.isAssignableFrom(clazz)) {
|
||||
this.lessonEndpoints.add(clazz);
|
||||
if (Assignment.class.isAssignableFrom(clazz)) {
|
||||
this.assignments.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);
|
||||
@ -89,16 +88,6 @@ public class Plugin {
|
||||
* @param file a {@link java.nio.file.Path} object.
|
||||
*/
|
||||
public void loadFiles(Path file) {
|
||||
if (fileEndsWith(file, ".html") && hasParentDirectoryWithName(file, NAME_LESSON_SOLUTION_DIRECTORY)) {
|
||||
solutionLanguageFiles.put(file.getParent().getFileName().toString(), file.toFile());
|
||||
}
|
||||
if (fileEndsWith(file, ".html") && hasParentDirectoryWithName(file, NAME_LESSON_PLANS_DIRECTORY)) {
|
||||
lessonPlansLanguageFiles.put(file.getParent().getFileName().toString(), file.toFile());
|
||||
}
|
||||
if (fileEndsWith(file, ".java")) {
|
||||
lessonSourceFile = file.toFile();
|
||||
}
|
||||
|
||||
if (fileEndsWith(file, ".css", ".jsp", ".js")) {
|
||||
pluginFiles.add(file.toFile());
|
||||
}
|
||||
@ -106,13 +95,14 @@ public class Plugin {
|
||||
|
||||
/**
|
||||
* Lesson is optional, it is also possible that the supplied jar contains only helper classes.
|
||||
* Lesson could be a new lesson (adoc based) or still ECS based.
|
||||
*
|
||||
* @return a {@link com.google.common.base.Optional} object.
|
||||
*/
|
||||
public Optional<AbstractLesson> getLesson() {
|
||||
try {
|
||||
if (newLesson != null) {
|
||||
AbstractLesson lesson = newLesson.newInstance();
|
||||
lesson.setAssignments(this.assignments);
|
||||
return Optional.of(newLesson.newInstance());
|
||||
}
|
||||
} catch (IllegalAccessException | InstantiationException e) {
|
||||
@ -121,42 +111,5 @@ public class Plugin {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getLessonSolution.</p>
|
||||
*
|
||||
* @param language a {@link java.lang.String} object.
|
||||
* @return a {@link com.google.common.base.Optional} object.
|
||||
*/
|
||||
public Optional<File> getLessonSolution(String language) {
|
||||
return Optional.fromNullable(this.solutionLanguageFiles.get(language));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getLessonSolutions.</p>
|
||||
*
|
||||
* @return a {@link java.util.Map} object.
|
||||
*/
|
||||
public Map<String, File> getLessonSolutions() {
|
||||
return this.solutionLanguageFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getLessonSource.</p>
|
||||
*
|
||||
* @return a {@link com.google.common.base.Optional} object.
|
||||
*/
|
||||
public Optional<File> getLessonSource() {
|
||||
return Optional.fromNullable(lessonSourceFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getLessonPlans.</p>
|
||||
*
|
||||
* @return a {@link java.util.Map} object.
|
||||
*/
|
||||
public Map<String, File> getLessonPlans() {
|
||||
return this.lessonPlansLanguageFiles;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -49,14 +50,17 @@ public class PluginEndpointPublisher {
|
||||
}
|
||||
|
||||
public void publish(Plugin plugin) {
|
||||
plugin.getLessonEndpoints().forEach(e -> {
|
||||
try {
|
||||
BeanDefinition beanDefinition = new RootBeanDefinition(e, Autowire.BY_TYPE.value(), true);
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
|
||||
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to register " + e.getSimpleName() + " as endpoint with Spring, skipping...");
|
||||
}
|
||||
});
|
||||
plugin.getAssignments().forEach(e -> publishEndpoint(e));
|
||||
plugin.getEndpoints().forEach(e -> publishEndpoint(e));
|
||||
}
|
||||
|
||||
private void publishEndpoint(Class<? extends MvcEndpoint> e) {
|
||||
try {
|
||||
BeanDefinition beanDefinition = new RootBeanDefinition(e, Autowire.BY_TYPE.value(), true);
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
|
||||
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to register " + e.getSimpleName() + " as endpoint with Spring, skipping...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* <p>LessonMenuService class.</p>
|
||||
@ -56,7 +55,7 @@ import java.util.Optional;
|
||||
public class LessonMenuService {
|
||||
|
||||
private final Course course;
|
||||
private final UserTracker userTracker;
|
||||
private UserTracker userTracker;
|
||||
private final WebSession webSession;
|
||||
|
||||
/**
|
||||
@ -82,8 +81,8 @@ public class LessonMenuService {
|
||||
lessonItem.setName(lesson.getTitle());
|
||||
lessonItem.setLink(lesson.getLink());
|
||||
lessonItem.setType(LessonMenuItemType.LESSON);
|
||||
Optional<LessonTracker> lessonTracker = userTracker.getLessonTracker(lesson);
|
||||
lessonItem.setComplete(lessonTracker.isPresent() ? lessonTracker.get().getCompleted() : false);
|
||||
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
||||
lessonItem.setComplete(lessonTracker.isLessonSolved());
|
||||
categoryItem.addChild(lessonItem);
|
||||
}
|
||||
menu.add(categoryItem);
|
||||
|
@ -6,6 +6,7 @@ import org.owasp.webgoat.i18n.LabelManager;
|
||||
import org.owasp.webgoat.lessons.model.LessonInfoModel;
|
||||
import org.owasp.webgoat.session.LessonTracker;
|
||||
import org.owasp.webgoat.session.UserTracker;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@ -24,6 +25,7 @@ public class LessonProgressService {
|
||||
|
||||
private LabelManager labelManager;
|
||||
private UserTracker userTracker;
|
||||
private WebSession webSession;
|
||||
|
||||
/**
|
||||
* <p>LessonProgressService.</p>
|
||||
@ -33,10 +35,14 @@ public class LessonProgressService {
|
||||
@RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public Map getLessonInfo() {
|
||||
LessonTracker lessonTracker = userTracker.getCurrentLessonTracker();
|
||||
boolean lessonCompleted = lessonTracker.getCompleted();
|
||||
String successMessage = labelManager.get("LessonCompleted");
|
||||
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
|
||||
Map json = Maps.newHashMap();
|
||||
String successMessage = "";
|
||||
boolean lessonCompleted = false;
|
||||
if (lessonTracker != null) {
|
||||
lessonCompleted = lessonTracker.isLessonSolved();
|
||||
successMessage = labelManager.get("LessonCompleted");
|
||||
}
|
||||
json.put("lessonCompleted", lessonCompleted);
|
||||
json.put("successMessage", successMessage);
|
||||
return json;
|
||||
|
@ -24,12 +24,14 @@
|
||||
package org.owasp.webgoat.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||
import org.owasp.webgoat.session.UserTracker;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
/**
|
||||
* <p>RestartLessonService class.</p>
|
||||
@ -39,6 +41,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
*/
|
||||
@Controller
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class RestartLessonService {
|
||||
|
||||
private final WebSession webSession;
|
||||
@ -50,13 +53,11 @@ public class RestartLessonService {
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
|
||||
public
|
||||
@ResponseBody
|
||||
String restartLesson() {
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public void restartLesson() {
|
||||
AbstractLesson al = webSession.getCurrentLesson();
|
||||
System.out.println("Restarting lesson: " + al);
|
||||
userTracker.getCurrentLessonTracker().setCompleted(false);
|
||||
log.debug("Restarting lesson: " + al);
|
||||
|
||||
return webSession.getCurrentLesson().getLink();
|
||||
userTracker.reset(al);
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public class Course {
|
||||
for (Plugin plugin : plugins) {
|
||||
try {
|
||||
NewLesson lesson = (NewLesson) plugin.getLesson().get();
|
||||
lesson.setTotalNumberOfAssignments(plugin.getLessonEndpoints().size());
|
||||
lesson.setAssignments(plugin.getAssignments());
|
||||
lessons.add(lesson);
|
||||
} catch (Exception e) {
|
||||
log.error("Error in loadLessons: ", e);
|
||||
|
@ -1,13 +1,13 @@
|
||||
|
||||
package org.owasp.webgoat.session;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
@ -40,290 +40,43 @@ import java.util.Properties;
|
||||
* @version $Id: $Id
|
||||
* @since October 29, 2003
|
||||
*/
|
||||
@Slf4j
|
||||
public class LessonTracker {
|
||||
public class LessonTracker implements Serializable {
|
||||
private static final long serialVersionUID = 5410058267505412928L;
|
||||
private final List<String> assignments;
|
||||
private final Set<String> solvedAssignments = Sets.newHashSet();
|
||||
private int numberOfAttempts = 0;
|
||||
|
||||
private boolean completed = false;
|
||||
|
||||
private int maxHintLevel = 0;
|
||||
|
||||
private int numVisits = 0;
|
||||
|
||||
private boolean viewedCookies = false;
|
||||
|
||||
private boolean viewedHtml = false;
|
||||
|
||||
private boolean viewedLessonPlan = false;
|
||||
|
||||
private boolean viewedParameters = false;
|
||||
|
||||
private boolean viewedSource = false;
|
||||
|
||||
private boolean viewedSolution = false;
|
||||
|
||||
Properties lessonProperties = new Properties();
|
||||
|
||||
private int totalNumberOfAssignments = 0;
|
||||
|
||||
public void setTotalNumberOfAssignments(int totalNumberOfAssignments) {
|
||||
this.totalNumberOfAssignments = totalNumberOfAssignments;
|
||||
public LessonTracker(AbstractLesson lesson) {
|
||||
this.assignments = lesson.getAssignments().stream().map(a -> a.getSimpleName()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the completed attribute of the LessonTracker object
|
||||
* Mark an assingment as solved
|
||||
*
|
||||
* @return The completed value
|
||||
* @param solvedAssignment the assignment which the user solved
|
||||
*/
|
||||
public boolean getCompleted() {
|
||||
return completed;
|
||||
public void assignmentSolved(String solvedAssignment) {
|
||||
solvedAssignments.add(solvedAssignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maxHintLevel attribute of the LessonTracker object
|
||||
*
|
||||
* @return The maxHintLevel value
|
||||
* @return did they user solved all assignments for the lesson?
|
||||
*/
|
||||
public int getMaxHintLevel() {
|
||||
return maxHintLevel;
|
||||
public boolean isLessonSolved() {
|
||||
return solvedAssignments.size() == assignments.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the numVisits attribute of the LessonTracker object
|
||||
*
|
||||
* @return The numVisits value
|
||||
* Increase the number attempts to solve the lesson
|
||||
*/
|
||||
public int getNumVisits() {
|
||||
return numVisits;
|
||||
public void incrementAttempts() {
|
||||
numberOfAttempts++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the viewedCookies attribute of the LessonTracker object
|
||||
*
|
||||
* @return The viewedCookies value
|
||||
* Reset the tracker. We do not reset the number of attempts here!
|
||||
*/
|
||||
public boolean getViewedCookies() {
|
||||
return viewedCookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the viewedHtml attribute of the LessonTracker object
|
||||
*
|
||||
* @return The viewedHtml value
|
||||
*/
|
||||
public boolean getViewedHtml() {
|
||||
return viewedHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the viewedLessonPlan attribute of the LessonTracker object
|
||||
*
|
||||
* @return The viewedLessonPlan value
|
||||
*/
|
||||
public boolean getViewedLessonPlan() {
|
||||
return viewedLessonPlan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the viewedParameters attribute of the LessonTracker object
|
||||
*
|
||||
* @return The viewedParameters value
|
||||
*/
|
||||
public boolean getViewedParameters() {
|
||||
return viewedParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the viewedSource attribute of the LessonTracker object
|
||||
*
|
||||
* @return The viewedSource value
|
||||
*/
|
||||
public boolean getViewedSource() {
|
||||
return viewedSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>viewedSolution</code>.</p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public boolean getViewedSolution() {
|
||||
return viewedSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*/
|
||||
public void incrementNumVisits() {
|
||||
numVisits++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the properties attribute of the LessonTracker object
|
||||
*
|
||||
* @param props The new properties value
|
||||
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
|
||||
*/
|
||||
protected void setProperties(Properties props, Screen screen) {
|
||||
completed = Boolean.valueOf(props.getProperty(screen.getTitle() + ".completed")).booleanValue();
|
||||
maxHintLevel = Integer.parseInt(props.getProperty(screen.getTitle() + ".maxHintLevel", "0"));
|
||||
numVisits = Integer.parseInt(props.getProperty(screen.getTitle() + ".numVisits", "0"));
|
||||
viewedCookies = Boolean.valueOf(props.getProperty(screen.getTitle() + ".viewedCookies", "false")).booleanValue();
|
||||
viewedHtml = Boolean.valueOf(props.getProperty(screen.getTitle() + ".viewedHtml", "false")).booleanValue();
|
||||
viewedLessonPlan = Boolean.valueOf(props.getProperty(screen.getTitle() + ".viewedLessonPlan", "false")).booleanValue();
|
||||
viewedParameters = Boolean.valueOf(props.getProperty(screen.getTitle() + ".viewedParameters", "false")).booleanValue();
|
||||
viewedSource = Boolean.valueOf(props.getProperty(screen.getTitle() + ".viewedSource", "false")).booleanValue();
|
||||
totalNumberOfAssignments = Integer.parseInt(props.getProperty(screen.getTitle() + ".totalNumberOfAssignments", "0"));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getUserDir.</p>
|
||||
*
|
||||
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getUserDir(WebSession s) {
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getTrackerFile(WebSession s, String user, Screen screen) {
|
||||
return getUserDir(s) + user + "." + screen.getClass().getName() + ".props";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param screen Description of the Parameter
|
||||
* @param screen Description of the Parameter
|
||||
* @param screen Description of the Parameter
|
||||
* @param screen Description of the Parameter
|
||||
* @param screen Description of the Parameter
|
||||
* @param screen Description of the Parameter
|
||||
* @param s Description of the Parameter
|
||||
* @param user a {@link java.lang.String} object.
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
public static LessonTracker load(WebSession s, String user, Screen screen) {
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
String fileName = getTrackerFile(s, user, screen);
|
||||
if (fileName != null) {
|
||||
Properties tempProps = new Properties();
|
||||
// System.out.println("Loading lesson state from: " + fileName);
|
||||
in = new FileInputStream(fileName);
|
||||
tempProps.load(in);
|
||||
// allow the screen to use any custom properties it may have set
|
||||
LessonTracker tempLessonTracker = new LessonTracker();
|
||||
tempLessonTracker.setProperties(tempProps, screen);
|
||||
return tempLessonTracker;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
// Normal if the lesson has not been accessed yet.
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed to load lesson state for " + screen);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return new LessonTracker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the completed attribute of the LessonTracker object
|
||||
*
|
||||
* @param completed The new completed value
|
||||
*/
|
||||
public void setCompleted(boolean completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maxHintLevel attribute of the LessonTracker object
|
||||
*
|
||||
* @param maxHintLevel The new maxHintLevel value
|
||||
*/
|
||||
public void setMaxHintLevel(int maxHintLevel) {
|
||||
this.maxHintLevel = Math.max(this.maxHintLevel, maxHintLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the storing of properties for the logged in and a screen.
|
||||
*
|
||||
* @param s Description of the Parameter
|
||||
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
|
||||
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
|
||||
*/
|
||||
public void store(WebSession s, Screen screen) {
|
||||
store(s, screen, s.getUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the storing of properties for a user and a screen.
|
||||
*
|
||||
* @param s Description of the Parameter
|
||||
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
|
||||
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
|
||||
* @param user a {@link java.lang.String} object.
|
||||
*/
|
||||
public void store(WebSession s, Screen screen, String user) {
|
||||
|
||||
String fileName = getTrackerFile(s, user, screen);
|
||||
// System.out.println( "Storing data to" + fileName );
|
||||
lessonProperties.setProperty(screen.getTitle() + ".completed", Boolean.toString(completed));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".maxHintLevel", Integer.toString(maxHintLevel));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".numVisits", Integer.toString(numVisits));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".viewedCookies", Boolean.toString(viewedCookies));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".viewedHtml", Boolean.toString(viewedHtml));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".viewedLessonPlan", Boolean.toString(viewedLessonPlan));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".viewedParameters", Boolean.toString(viewedParameters));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".viewedSource", Boolean.toString(viewedSource));
|
||||
lessonProperties.setProperty(screen.getTitle() + ".totalNumberOfAssignments", Integer.toString(totalNumberOfAssignments));
|
||||
try (FileOutputStream out = new FileOutputStream(fileName)) {
|
||||
lessonProperties.store(out, s.getUserName());
|
||||
} catch (IOException e) {
|
||||
log.warn("Warning User data for {} will not persist", s.getUserName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buff = new StringBuffer();
|
||||
buff.append("LessonTracker:" + "\n");
|
||||
buff.append(" - completed:................. " + completed + "\n");
|
||||
buff.append(" - maxHintLevel:.............. " + maxHintLevel + "\n");
|
||||
buff.append(" - numVisits:................. " + numVisits + "\n");
|
||||
buff.append(" - viewedCookies:............. " + viewedCookies + "\n");
|
||||
buff.append(" - viewedHtml:................ " + viewedHtml + "\n");
|
||||
buff.append(" - viewedLessonPlan:.......... " + viewedLessonPlan + "\n");
|
||||
buff.append(" - viewedParameters:.......... " + viewedParameters + "\n");
|
||||
buff.append(" - viewedSource:.............. " + viewedSource + "\n" + "\n");
|
||||
buff.append(" - totalNumberOfAssignments:.. " + viewedSource + "\n" + "\n");
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>lessonProperties</code>.</p>
|
||||
*
|
||||
* @return Returns the lessonProperties.
|
||||
*/
|
||||
public Properties getLessonProperties() {
|
||||
return lessonProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Setter for the field <code>lessonProperties</code>.</p>
|
||||
*
|
||||
* @param lessonProperties The lessonProperties to set.
|
||||
*/
|
||||
public void setLessonProperties(Properties lessonProperties) {
|
||||
this.lessonProperties = lessonProperties;
|
||||
void reset() {
|
||||
solvedAssignments.clear();
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
|
||||
package org.owasp.webgoat.session;
|
||||
|
||||
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.stereotype.Component;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.SerializationUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
@ -40,34 +43,15 @@ import java.util.Optional;
|
||||
* @version $Id: $Id
|
||||
* @since October 29, 2003
|
||||
*/
|
||||
@Component
|
||||
public class UserTracker {
|
||||
|
||||
private static Map<String, HashMap<String, LessonTracker>> storage = new HashMap<>();
|
||||
private final String webgoatHome;
|
||||
private final WebSession webSession;
|
||||
private final String user;
|
||||
private Map<String, LessonTracker> storage = new HashMap<>();
|
||||
|
||||
public UserTracker(@Value("${webgoat.user.directory}") final String webgoatHome, final WebSession webSession) {
|
||||
public UserTracker(@Value("${webgoat.user.directory}") final String webgoatHome, final String user) {
|
||||
this.webgoatHome = webgoatHome;
|
||||
this.webSession = webSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getCurrentLessonTracker.</p>
|
||||
*
|
||||
* @return a {@link org.owasp.webgoat.session.LessonTracker} object.
|
||||
*/
|
||||
public LessonTracker getCurrentLessonTracker() {
|
||||
String lessonTitle = webSession.getCurrentLesson().getTitle();
|
||||
String username = webSession.getUserName();
|
||||
HashMap<String, LessonTracker> usermap = getUserMap(username);
|
||||
LessonTracker tracker = usermap.get(lessonTitle);
|
||||
if (tracker == null) {
|
||||
// Creates a new lesson tracker, if one does not exist on disk.
|
||||
tracker = LessonTracker.load(webSession, username, webSession.getCurrentLesson());
|
||||
usermap.put(lessonTitle, tracker);
|
||||
}
|
||||
return tracker;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,31 +60,45 @@ public class UserTracker {
|
||||
* @param lesson the lesson
|
||||
* @return the optional lesson tracker
|
||||
*/
|
||||
public Optional<LessonTracker> getLessonTracker(AbstractLesson lesson) {
|
||||
String username = webSession.getUserName();
|
||||
return Optional.ofNullable(getUserMap(username).getOrDefault(lesson.getTitle(), null));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the userMap attribute of the UserTracker object
|
||||
*
|
||||
* @param userName Description of the Parameter
|
||||
* @return The userMap value
|
||||
*/
|
||||
private HashMap<String, LessonTracker> getUserMap(String userName) {
|
||||
|
||||
HashMap<String, LessonTracker> usermap = storage.get(userName);
|
||||
|
||||
if (usermap == null) {
|
||||
|
||||
usermap = new HashMap<>();
|
||||
|
||||
storage.put(userName, usermap);
|
||||
|
||||
public LessonTracker getLessonTracker(AbstractLesson lesson) {
|
||||
LessonTracker lessonTracker = storage.get(lesson.getTitle());
|
||||
if (lessonTracker == null) {
|
||||
lessonTracker = new LessonTracker(lesson);
|
||||
storage.put(lesson.getTitle(), lessonTracker);
|
||||
}
|
||||
|
||||
return (usermap);
|
||||
return lessonTracker;
|
||||
}
|
||||
|
||||
public void assignmentSolved(AbstractLesson lesson, Assignment assignment) {
|
||||
LessonTracker lessonTracker = getLessonTracker(lesson);
|
||||
lessonTracker.incrementAttempts();
|
||||
lessonTracker.assignmentSolved(assignment.getClass().getSimpleName());
|
||||
save();
|
||||
}
|
||||
|
||||
public void assignmentFailed(AbstractLesson lesson) {
|
||||
LessonTracker lessonTracker = getLessonTracker(lesson);
|
||||
lessonTracker.incrementAttempts();
|
||||
save();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void load() {
|
||||
File file = new File(webgoatHome, user);
|
||||
if (file.exists() && file.isFile()) {
|
||||
this.storage = (Map<String, LessonTracker>) SerializationUtils.deserialize(FileCopyUtils.copyToByteArray(file));
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void save() {
|
||||
File file = new File(webgoatHome, user);
|
||||
FileCopyUtils.copy(SerializationUtils.serialize(this.storage), file);
|
||||
}
|
||||
|
||||
|
||||
public void reset(AbstractLesson al) {
|
||||
getLessonTracker(al).reset();
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package org.owasp.webgoat.session;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
|
||||
@ -44,13 +43,13 @@ public class WebSession {
|
||||
private final User currentUser;
|
||||
private final WebgoatContext webgoatContext;
|
||||
private AbstractLesson currentLesson;
|
||||
private UserTracker userTracker;
|
||||
|
||||
/**
|
||||
* Constructor for the WebSession object
|
||||
*
|
||||
* @param webgoatContext a {@link org.owasp.webgoat.session.WebgoatContext} object.
|
||||
*/
|
||||
@Autowired
|
||||
public WebSession(WebgoatContext webgoatContext) {
|
||||
this.webgoatContext = webgoatContext;
|
||||
this.currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
@ -76,7 +75,6 @@ public class WebSession {
|
||||
DatabaseUtilities.returnConnection(s.getUserName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p> Setter for the field <code>currentScreen</code>. </p>
|
||||
*
|
||||
|
@ -187,22 +187,11 @@ define(['jquery',
|
||||
|
||||
this.restartLesson = function() {
|
||||
var self=this;
|
||||
var fragment = "attack/" + self.scr + "/" + self.menu;
|
||||
console.log("Navigating to " + fragment);
|
||||
// Avoiding the trigger event - handle - navigate loop by
|
||||
// loading the lesson explicitly (after executing the restart
|
||||
// servlet).
|
||||
goatRouter.navigate(fragment);
|
||||
// Resetting the user's lesson state (assuming a single browser
|
||||
// and session per user).
|
||||
$.ajax({
|
||||
url:'service/restartlesson.mvc',
|
||||
method:'GET'
|
||||
}).done(function(text) {
|
||||
console.log("Received a response from the restart servlet: '" + text + "'");
|
||||
// Explicitly loading the lesson instead of triggering an
|
||||
// event in goatRouter.navigate().
|
||||
self.loadLesson(self.scr,self.menu);
|
||||
}).done(function(lessonLink) {
|
||||
self.loadLesson(self.name);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -77,7 +77,7 @@ define(['jquery',
|
||||
this.renderFeedback(data.feedback);
|
||||
|
||||
this.renderOutput(data.output || "");
|
||||
if (data.lessonComplete) {
|
||||
if (data.lessonCompleted) {
|
||||
this.trigger('lesson:complete');
|
||||
}
|
||||
return false;
|
||||
|
@ -0,0 +1,71 @@
|
||||
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.when;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 20014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*
|
||||
* @author nbaars
|
||||
* @version $Id: $Id
|
||||
* @since November 15, 2016
|
||||
*/
|
||||
public class UserTrackerTest {
|
||||
|
||||
private File home;
|
||||
|
||||
@Before
|
||||
public void init() throws IOException {
|
||||
home = File.createTempFile("test", "test");
|
||||
home.deleteOnExit();
|
||||
}
|
||||
|
||||
@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 = new UserTracker(home.getParent(), "test");
|
||||
userTracker.load();
|
||||
assertThat(userTracker.getLessonTracker(abstractLesson).isLessonSolved()).isTrue();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import org.owasp.webgoat.lessons.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.lessons.LessonEndpointMapping;
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -39,8 +38,7 @@ import java.io.IOException;
|
||||
* @version $Id: $Id
|
||||
* @since August 11, 2016
|
||||
*/
|
||||
@LessonEndpointMapping
|
||||
public class Attack extends AssignmentEndpoint {
|
||||
public class Attack extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String answer) throws IOException {
|
||||
|
@ -7,8 +7,7 @@ package org.owasp.webgoat.plugin;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.owasp.webgoat.lessons.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.lessons.LessonEndpointMapping;
|
||||
import org.owasp.webgoat.lessons.Endpoint;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.w3c.dom.Node;
|
||||
@ -26,8 +25,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@LessonEndpointMapping
|
||||
public class Salaries extends AssignmentEndpoint {
|
||||
public class Salaries extends Endpoint {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public void invoke(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import org.owasp.webgoat.lessons.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.lessons.LessonEndpointMapping;
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -45,8 +44,7 @@ import java.io.IOException;
|
||||
* @created October 28, 2003
|
||||
*/
|
||||
|
||||
@LessonEndpointMapping
|
||||
public class HttpBasicsLesson extends AssignmentEndpoint {
|
||||
public class HttpBasicsLesson extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String person, HttpServletRequest request) throws IOException {
|
||||
|
@ -1,17 +1,15 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.owasp.webgoat.lessons.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.lessons.LessonEndpointMapping;
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
@ -46,8 +44,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
* @created October 28, 2003
|
||||
*/
|
||||
|
||||
@LessonEndpointMapping
|
||||
public class HttpBasicsQuiz extends AssignmentEndpoint {
|
||||
public class HttpBasicsQuiz extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String answer, @RequestParam String magic_answer, @RequestParam String magic_num, HttpServletRequest request) throws IOException {
|
||||
|
Loading…
x
Reference in New Issue
Block a user