Apply formatting
This will make sure we have a consistent style across our project and the PRs are only concerned with actual changes and no longer about style.
This commit is contained in:
@ -1,59 +1,59 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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
|
||||
*
|
||||
* <p>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 - 2014 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.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
|
||||
/**
|
||||
* <p>AjaxAuthenticationEntryPoint class.</p>
|
||||
* AjaxAuthenticationEntryPoint class.
|
||||
*
|
||||
* @author zupzup
|
||||
*/
|
||||
|
||||
public class AjaxAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
||||
public AjaxAuthenticationEntryPoint(String loginFormUrl) {
|
||||
super(loginFormUrl);
|
||||
}
|
||||
public AjaxAuthenticationEntryPoint(String loginFormUrl) {
|
||||
super(loginFormUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||
if (request.getHeader("x-requested-with") != null) {
|
||||
response.sendError(401, authException.getMessage());
|
||||
} else {
|
||||
super.commence(request, response, authException);
|
||||
}
|
||||
@Override
|
||||
public void commence(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
AuthenticationException authException)
|
||||
throws IOException, ServletException {
|
||||
if (request.getHeader("x-requested-with") != null) {
|
||||
response.sendError(401, authException.getMessage());
|
||||
} else {
|
||||
super.commence(request, response, authException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,47 @@
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* 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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @author WebGoat
|
||||
* @version $Id: $Id
|
||||
* @since December 12, 2015
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import static org.asciidoctor.Asciidoctor.Factory.create;
|
||||
|
||||
import io.undertow.util.Headers;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.asciidoctor.Asciidoctor;
|
||||
import org.asciidoctor.extension.JavaExtensionRegistry;
|
||||
@ -46,113 +56,117 @@ import org.thymeleaf.templateresolver.FileTemplateResolver;
|
||||
import org.thymeleaf.templateresource.ITemplateResource;
|
||||
import org.thymeleaf.templateresource.StringTemplateResource;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.asciidoctor.Asciidoctor.Factory.create;
|
||||
|
||||
/**
|
||||
* Thymeleaf resolver for AsciiDoc used in the lesson, can be used as follows inside a lesson file:
|
||||
* <p>
|
||||
* <code>
|
||||
*
|
||||
* <p><code>
|
||||
* <div th:replace="doc:AccessControlMatrix_plan.adoc"></div>
|
||||
* </code>
|
||||
*/
|
||||
@Slf4j
|
||||
public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
|
||||
|
||||
private static final Asciidoctor asciidoctor = create();
|
||||
private static final String PREFIX = "doc:";
|
||||
private static final Asciidoctor asciidoctor = create();
|
||||
private static final String PREFIX = "doc:";
|
||||
|
||||
private final Language language;
|
||||
private final ResourceLoader resourceLoader;
|
||||
private final Language language;
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
public AsciiDoctorTemplateResolver(Language language, ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
this.language = language;
|
||||
setResolvablePatterns(Set.of(PREFIX + "*"));
|
||||
public AsciiDoctorTemplateResolver(Language language, ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
this.language = language;
|
||||
setResolvablePatterns(Set.of(PREFIX + "*"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ITemplateResource computeTemplateResource(
|
||||
IEngineConfiguration configuration,
|
||||
String ownerTemplate,
|
||||
String template,
|
||||
String resourceName,
|
||||
String characterEncoding,
|
||||
Map<String, Object> templateResolutionAttributes) {
|
||||
var templateName = resourceName.substring(PREFIX.length());
|
||||
log.debug("template used: {}", templateName);
|
||||
try (InputStream is = getInputStream(templateName)) {
|
||||
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
|
||||
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
|
||||
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
|
||||
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
|
||||
extensionRegistry.inlineMacro("webGoatTempDir", WebGoatTmpDirMacro.class);
|
||||
extensionRegistry.inlineMacro("operatingSystem", OperatingSystemMacro.class);
|
||||
extensionRegistry.inlineMacro("username", UsernameMacro.class);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
||||
return new StringTemplateResource(writer.getBuffer().toString());
|
||||
} catch (IOException e) {
|
||||
return new StringTemplateResource(
|
||||
"<div>Unable to find documentation for: " + templateName + " </div>");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
|
||||
var templateName = resourceName.substring(PREFIX.length());
|
||||
log.debug("template used: {}", templateName);
|
||||
try (InputStream is = getInputStream(templateName)) {
|
||||
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
|
||||
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
|
||||
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
|
||||
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
|
||||
extensionRegistry.inlineMacro("webGoatTempDir", WebGoatTmpDirMacro.class);
|
||||
extensionRegistry.inlineMacro("operatingSystem", OperatingSystemMacro.class);
|
||||
extensionRegistry.inlineMacro("username", UsernameMacro.class);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
||||
return new StringTemplateResource(writer.getBuffer().toString());
|
||||
} catch (IOException e) {
|
||||
return new StringTemplateResource("<div>Unable to find documentation for: " + templateName + " </div>");
|
||||
}
|
||||
private InputStream getInputStream(String templateName) throws IOException {
|
||||
log.debug("locale: {}", language.getLocale().getLanguage());
|
||||
String computedResourceName =
|
||||
computeResourceName(templateName, language.getLocale().getLanguage());
|
||||
if (resourceLoader
|
||||
.getResource("classpath:/" + computedResourceName)
|
||||
.isReadable() /*isFile()*/) {
|
||||
log.debug("localized file exists");
|
||||
return resourceLoader.getResource("classpath:/" + computedResourceName).getInputStream();
|
||||
} else {
|
||||
log.debug("using english template");
|
||||
return resourceLoader.getResource("classpath:/" + templateName).getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getInputStream(String templateName) throws IOException {
|
||||
log.debug("locale: {}",language.getLocale().getLanguage());
|
||||
String computedResourceName = computeResourceName(templateName, language.getLocale().getLanguage());
|
||||
if (resourceLoader.getResource("classpath:/" + computedResourceName).isReadable()/*isFile()*/) {
|
||||
log.debug("localized file exists");
|
||||
return resourceLoader.getResource("classpath:/" + computedResourceName).getInputStream();
|
||||
} else {
|
||||
log.debug("using english template");
|
||||
return resourceLoader.getResource("classpath:/" + templateName).getInputStream();
|
||||
}
|
||||
private String computeResourceName(String resourceName, String language) {
|
||||
String computedResourceName;
|
||||
if (language.equals("en")) {
|
||||
computedResourceName = resourceName;
|
||||
} else {
|
||||
computedResourceName = resourceName.replace(".adoc", "_".concat(language).concat(".adoc"));
|
||||
}
|
||||
private String computeResourceName(String resourceName, String language) {
|
||||
String computedResourceName;
|
||||
if (language.equals("en")) {
|
||||
computedResourceName = resourceName;
|
||||
} else {
|
||||
computedResourceName = resourceName.replace(".adoc", "_".concat(language).concat(".adoc"));
|
||||
}
|
||||
log.debug("computed local file name: {}", computedResourceName);
|
||||
log.debug("file exists: {}",resourceLoader.getResource("classpath:/"+computedResourceName).isReadable());
|
||||
return computedResourceName;
|
||||
}
|
||||
|
||||
private Map<String, Object> createAttributes() {
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("source-highlighter", "coderay");
|
||||
attributes.put("backend", "xhtml");
|
||||
attributes.put("lang", determineLanguage());
|
||||
attributes.put("icons", org.asciidoctor.Attributes.FONT_ICONS);
|
||||
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("attributes", attributes);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private String determineLanguage() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||
|
||||
Locale browserLocale = (Locale) request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
|
||||
if (null != browserLocale) {
|
||||
log.debug("browser locale {}", browserLocale);
|
||||
return browserLocale.getLanguage();
|
||||
} else {
|
||||
String langHeader = request.getHeader(Headers.ACCEPT_LANGUAGE_STRING);
|
||||
if (null != langHeader) {
|
||||
log.debug("browser locale {}", langHeader);
|
||||
return langHeader.substring(0,2);
|
||||
} else {
|
||||
log.debug("browser default english");
|
||||
return "en";
|
||||
}
|
||||
}
|
||||
log.debug("computed local file name: {}", computedResourceName);
|
||||
log.debug(
|
||||
"file exists: {}",
|
||||
resourceLoader.getResource("classpath:/" + computedResourceName).isReadable());
|
||||
return computedResourceName;
|
||||
}
|
||||
|
||||
private Map<String, Object> createAttributes() {
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("source-highlighter", "coderay");
|
||||
attributes.put("backend", "xhtml");
|
||||
attributes.put("lang", determineLanguage());
|
||||
attributes.put("icons", org.asciidoctor.Attributes.FONT_ICONS);
|
||||
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("attributes", attributes);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private String determineLanguage() {
|
||||
HttpServletRequest request =
|
||||
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||
|
||||
Locale browserLocale =
|
||||
(Locale)
|
||||
request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
|
||||
if (null != browserLocale) {
|
||||
log.debug("browser locale {}", browserLocale);
|
||||
return browserLocale.getLanguage();
|
||||
} else {
|
||||
String langHeader = request.getHeader(Headers.ACCEPT_LANGUAGE_STRING);
|
||||
if (null != langHeader) {
|
||||
log.debug("browser locale {}", langHeader);
|
||||
return langHeader.substring(0, 2);
|
||||
} else {
|
||||
log.debug("browser default english");
|
||||
return "en";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import javax.sql.DataSource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flywaydb.core.Flyway;
|
||||
@ -11,58 +14,54 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class DatabaseConfiguration {
|
||||
|
||||
private final DataSourceProperties properties;
|
||||
private final LessonScanner lessonScanner;
|
||||
private final DataSourceProperties properties;
|
||||
private final LessonScanner lessonScanner;
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public DataSource dataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName(properties.getDriverClassName());
|
||||
dataSource.setUrl(properties.getUrl());
|
||||
dataSource.setUsername(properties.getUsername());
|
||||
dataSource.setPassword(properties.getPassword());
|
||||
return dataSource;
|
||||
}
|
||||
@Bean
|
||||
@Primary
|
||||
public DataSource dataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName(properties.getDriverClassName());
|
||||
dataSource.setUrl(properties.getUrl());
|
||||
dataSource.setUsername(properties.getUsername());
|
||||
dataSource.setPassword(properties.getPassword());
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define 2 Flyway instances, 1 for WebGoat itself which it uses for internal storage like users and 1 for lesson
|
||||
* specific tables we use. This way we clean the data in the lesson database quite easily see {@link RestartLessonService#restartLesson()}
|
||||
* for how we clean the lesson related tables.
|
||||
*/
|
||||
@Bean(initMethod = "migrate")
|
||||
public Flyway flyWayContainer() {
|
||||
return Flyway
|
||||
.configure()
|
||||
.configuration(Map.of("driver", properties.getDriverClassName()))
|
||||
.dataSource(dataSource())
|
||||
.schemas("container")
|
||||
.locations("db/container")
|
||||
.load();
|
||||
}
|
||||
/**
|
||||
* Define 2 Flyway instances, 1 for WebGoat itself which it uses for internal storage like users
|
||||
* and 1 for lesson specific tables we use. This way we clean the data in the lesson database
|
||||
* quite easily see {@link RestartLessonService#restartLesson()} for how we clean the lesson
|
||||
* related tables.
|
||||
*/
|
||||
@Bean(initMethod = "migrate")
|
||||
public Flyway flyWayContainer() {
|
||||
return Flyway.configure()
|
||||
.configuration(Map.of("driver", properties.getDriverClassName()))
|
||||
.dataSource(dataSource())
|
||||
.schemas("container")
|
||||
.locations("db/container")
|
||||
.load();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<String, Flyway> flywayLessons(LessonDataSource lessonDataSource) {
|
||||
return schema -> Flyway
|
||||
.configure()
|
||||
.configuration(Map.of("driver", properties.getDriverClassName()))
|
||||
.schemas(schema)
|
||||
.dataSource(lessonDataSource)
|
||||
.locations("lessons")
|
||||
.load();
|
||||
}
|
||||
@Bean
|
||||
public Function<String, Flyway> flywayLessons(LessonDataSource lessonDataSource) {
|
||||
return schema ->
|
||||
Flyway.configure()
|
||||
.configuration(Map.of("driver", properties.getDriverClassName()))
|
||||
.schemas(schema)
|
||||
.dataSource(lessonDataSource)
|
||||
.locations("lessons")
|
||||
.load();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LessonDataSource lessonDataSource() {
|
||||
return new LessonDataSource(dataSource());
|
||||
}
|
||||
@Bean
|
||||
public LessonDataSource lessonDataSource() {
|
||||
return new LessonDataSource(dataSource());
|
||||
}
|
||||
}
|
||||
|
@ -9,30 +9,29 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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
|
||||
*
|
||||
* <p>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 - 2014 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.
|
||||
*
|
||||
* @author Jeff Williams
|
||||
@ -45,13 +44,13 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
@AllArgsConstructor
|
||||
public class HammerHead {
|
||||
|
||||
private final Course course;
|
||||
private final Course course;
|
||||
|
||||
/**
|
||||
* Entry point for WebGoat, redirects to the first lesson found within the course.
|
||||
*/
|
||||
@RequestMapping(path = "/attack", method = {RequestMethod.GET, RequestMethod.POST})
|
||||
public ModelAndView attack() {
|
||||
return new ModelAndView("redirect:" + "start.mvc" + course.getFirstLesson().getLink());
|
||||
}
|
||||
/** Entry point for WebGoat, redirects to the first lesson found within the course. */
|
||||
@RequestMapping(
|
||||
path = "/attack",
|
||||
method = {RequestMethod.GET, RequestMethod.POST})
|
||||
public ModelAndView attack() {
|
||||
return new ModelAndView("redirect:" + "start.mvc" + course.getFirstLesson().getLink());
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,70 @@
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import org.owasp.webgoat.container.lessons.LessonConnectionInvocationHandler;
|
||||
import org.springframework.jdbc.datasource.ConnectionProxy;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sql.DataSource;
|
||||
import org.owasp.webgoat.container.lessons.LessonConnectionInvocationHandler;
|
||||
import org.springframework.jdbc.datasource.ConnectionProxy;
|
||||
|
||||
public class LessonDataSource implements DataSource {
|
||||
|
||||
private final DataSource originalDataSource;
|
||||
private final DataSource originalDataSource;
|
||||
|
||||
public LessonDataSource(DataSource dataSource) {
|
||||
this.originalDataSource = dataSource;
|
||||
}
|
||||
public LessonDataSource(DataSource dataSource) {
|
||||
this.originalDataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
var targetConnection = originalDataSource.getConnection();
|
||||
return (Connection) Proxy.newProxyInstance(
|
||||
ConnectionProxy.class.getClassLoader(),
|
||||
new Class[]{ConnectionProxy.class},
|
||||
new LessonConnectionInvocationHandler(targetConnection));
|
||||
}
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
var targetConnection = originalDataSource.getConnection();
|
||||
return (Connection)
|
||||
Proxy.newProxyInstance(
|
||||
ConnectionProxy.class.getClassLoader(),
|
||||
new Class[] {ConnectionProxy.class},
|
||||
new LessonConnectionInvocationHandler(targetConnection));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
return originalDataSource.getConnection(username, password);
|
||||
}
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
return originalDataSource.getConnection(username, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return originalDataSource.getLogWriter();
|
||||
}
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return originalDataSource.getLogWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
originalDataSource.setLogWriter(out);
|
||||
}
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
originalDataSource.setLogWriter(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) throws SQLException {
|
||||
originalDataSource.setLoginTimeout(seconds);
|
||||
}
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) throws SQLException {
|
||||
originalDataSource.setLoginTimeout(seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return originalDataSource.getLoginTimeout();
|
||||
}
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return originalDataSource.getLoginTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return originalDataSource.getParentLogger();
|
||||
}
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return originalDataSource.getParentLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> clazz) throws SQLException {
|
||||
return originalDataSource.unwrap(clazz);
|
||||
}
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> clazz) throws SQLException {
|
||||
return originalDataSource.unwrap(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> clazz) throws SQLException {
|
||||
return originalDataSource.isWrapperFor(clazz);
|
||||
}
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> clazz) throws SQLException {
|
||||
return originalDataSource.isWrapperFor(clazz);
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,41 @@
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author WebGoat
|
||||
* @version $Id: $Id
|
||||
* @since October 28, 2003
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.thymeleaf.IEngineConfiguration;
|
||||
@ -38,45 +43,48 @@ import org.thymeleaf.templateresolver.FileTemplateResolver;
|
||||
import org.thymeleaf.templateresource.ITemplateResource;
|
||||
import org.thymeleaf.templateresource.StringTemplateResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Dynamically resolve a lesson. In the html file this can be invoked as:
|
||||
*
|
||||
* <code>
|
||||
* Dynamically resolve a lesson. In the html file this can be invoked as: <code>
|
||||
* <div th:case="true" th:replace="lesson:__${lesson.class.simpleName}__"></div>
|
||||
* </code>
|
||||
* <p>
|
||||
* Thymeleaf will invoke this resolver based on the prefix and this implementation will resolve the html in the plugins directory
|
||||
*
|
||||
* <p>Thymeleaf will invoke this resolver based on the prefix and this implementation will resolve
|
||||
* the html in the plugins directory
|
||||
*/
|
||||
@Slf4j
|
||||
public class LessonTemplateResolver extends FileTemplateResolver {
|
||||
|
||||
private static final String PREFIX = "lesson:";
|
||||
private ResourceLoader resourceLoader;
|
||||
private Map<String, byte[]> resources = new HashMap<>();
|
||||
private static final String PREFIX = "lesson:";
|
||||
private ResourceLoader resourceLoader;
|
||||
private Map<String, byte[]> resources = new HashMap<>();
|
||||
|
||||
public LessonTemplateResolver(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
setResolvablePatterns(Set.of(PREFIX + "*"));
|
||||
}
|
||||
public LessonTemplateResolver(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
setResolvablePatterns(Set.of(PREFIX + "*"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
|
||||
var templateName = resourceName.substring(PREFIX.length());
|
||||
byte[] resource = resources.get(templateName);
|
||||
if (resource == null) {
|
||||
try {
|
||||
resource = resourceLoader.getResource("classpath:/" + templateName).getInputStream().readAllBytes();
|
||||
} catch (IOException e) {
|
||||
log.error("Unable to find lesson HTML: {}", template);
|
||||
}
|
||||
resources.put(templateName, resource);
|
||||
}
|
||||
return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8));
|
||||
@Override
|
||||
protected ITemplateResource computeTemplateResource(
|
||||
IEngineConfiguration configuration,
|
||||
String ownerTemplate,
|
||||
String template,
|
||||
String resourceName,
|
||||
String characterEncoding,
|
||||
Map<String, Object> templateResolutionAttributes) {
|
||||
var templateName = resourceName.substring(PREFIX.length());
|
||||
byte[] resource = resources.get(templateName);
|
||||
if (resource == null) {
|
||||
try {
|
||||
resource =
|
||||
resourceLoader
|
||||
.getResource("classpath:/" + templateName)
|
||||
.getInputStream()
|
||||
.readAllBytes();
|
||||
} catch (IOException e) {
|
||||
log.error("Unable to find lesson HTML: {}", template);
|
||||
}
|
||||
resources.put(templateName, resource);
|
||||
}
|
||||
return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,40 @@
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author WebGoat
|
||||
* @version $Id: $Id
|
||||
* @since October 28, 2003
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.i18n.Language;
|
||||
@ -62,175 +66,195 @@ import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
import org.thymeleaf.templateresource.ITemplateResource;
|
||||
import org.thymeleaf.templateresource.StringTemplateResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Configuration for Spring MVC
|
||||
*/
|
||||
/** Configuration for Spring MVC */
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class MvcConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private static final String UTF8 = "UTF-8";
|
||||
private static final String UTF8 = "UTF-8";
|
||||
|
||||
private final LessonScanner lessonScanner;
|
||||
private final LessonScanner lessonScanner;
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/login").setViewName("login");
|
||||
registry.addViewController("/lesson_content").setViewName("lesson_content");
|
||||
registry.addViewController("/start.mvc").setViewName("main_new");
|
||||
registry.addViewController("/scoreboard").setViewName("scoreboard");
|
||||
}
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/login").setViewName("login");
|
||||
registry.addViewController("/lesson_content").setViewName("lesson_content");
|
||||
registry.addViewController("/start.mvc").setViewName("main_new");
|
||||
registry.addViewController("/scoreboard").setViewName("scoreboard");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver(SpringTemplateEngine thymeleafTemplateEngine) {
|
||||
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
|
||||
resolver.setTemplateEngine(thymeleafTemplateEngine);
|
||||
resolver.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
|
||||
return resolver;
|
||||
}
|
||||
@Bean
|
||||
public ViewResolver viewResolver(SpringTemplateEngine thymeleafTemplateEngine) {
|
||||
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
|
||||
resolver.setTemplateEngine(thymeleafTemplateEngine);
|
||||
resolver.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
|
||||
return resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for loading lesson templates based on Thymeleaf, for example:
|
||||
*
|
||||
* <div th:include="/lessons/spoofcookie/templates/spoofcookieform.html" id="content"></div>
|
||||
*/
|
||||
@Bean
|
||||
public ITemplateResolver lessonThymeleafTemplateResolver(ResourceLoader resourceLoader) {
|
||||
var resolver = new FileTemplateResolver() {
|
||||
@Override
|
||||
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
|
||||
try (var is = resourceLoader.getResource("classpath:" + resourceName).getInputStream()) {
|
||||
return new StringTemplateResource(new String(is.readAllBytes(), StandardCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Responsible for loading lesson templates based on Thymeleaf, for example:
|
||||
*
|
||||
* <p><div th:include="/lessons/spoofcookie/templates/spoofcookieform.html" id="content"></div>
|
||||
*/
|
||||
@Bean
|
||||
public ITemplateResolver lessonThymeleafTemplateResolver(ResourceLoader resourceLoader) {
|
||||
var resolver =
|
||||
new FileTemplateResolver() {
|
||||
@Override
|
||||
protected ITemplateResource computeTemplateResource(
|
||||
IEngineConfiguration configuration,
|
||||
String ownerTemplate,
|
||||
String template,
|
||||
String resourceName,
|
||||
String characterEncoding,
|
||||
Map<String, Object> templateResolutionAttributes) {
|
||||
try (var is =
|
||||
resourceLoader.getResource("classpath:" + resourceName).getInputStream()) {
|
||||
return new StringTemplateResource(
|
||||
new String(is.readAllBytes(), StandardCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
resolver.setOrder(1);
|
||||
return resolver;
|
||||
}
|
||||
resolver.setOrder(1);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all normal WebGoat specific Thymeleaf templates
|
||||
*/
|
||||
@Bean
|
||||
public ITemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) {
|
||||
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
|
||||
resolver.setPrefix("classpath:/webgoat/templates/");
|
||||
resolver.setSuffix(".html");
|
||||
resolver.setTemplateMode(TemplateMode.HTML);
|
||||
resolver.setOrder(2);
|
||||
resolver.setCharacterEncoding(UTF8);
|
||||
resolver.setApplicationContext(applicationContext);
|
||||
return resolver;
|
||||
}
|
||||
/** Loads all normal WebGoat specific Thymeleaf templates */
|
||||
@Bean
|
||||
public ITemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) {
|
||||
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
|
||||
resolver.setPrefix("classpath:/webgoat/templates/");
|
||||
resolver.setSuffix(".html");
|
||||
resolver.setTemplateMode(TemplateMode.HTML);
|
||||
resolver.setOrder(2);
|
||||
resolver.setCharacterEncoding(UTF8);
|
||||
resolver.setApplicationContext(applicationContext);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the html for the complete lesson, see lesson_content.html
|
||||
*/
|
||||
@Bean
|
||||
public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) {
|
||||
LessonTemplateResolver resolver = new LessonTemplateResolver(resourceLoader);
|
||||
resolver.setOrder(0);
|
||||
resolver.setCacheable(false);
|
||||
resolver.setCharacterEncoding(UTF8);
|
||||
return resolver;
|
||||
}
|
||||
/** Loads the html for the complete lesson, see lesson_content.html */
|
||||
@Bean
|
||||
public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) {
|
||||
LessonTemplateResolver resolver = new LessonTemplateResolver(resourceLoader);
|
||||
resolver.setOrder(0);
|
||||
resolver.setCacheable(false);
|
||||
resolver.setCharacterEncoding(UTF8);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the lesson asciidoc.
|
||||
*/
|
||||
@Bean
|
||||
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language, ResourceLoader resourceLoader) {
|
||||
log.debug("template locale {}", language);
|
||||
AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language, resourceLoader);
|
||||
resolver.setCacheable(false);
|
||||
resolver.setOrder(1);
|
||||
resolver.setCharacterEncoding(UTF8);
|
||||
return resolver;
|
||||
}
|
||||
/** Loads the lesson asciidoc. */
|
||||
@Bean
|
||||
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(
|
||||
Language language, ResourceLoader resourceLoader) {
|
||||
log.debug("template locale {}", language);
|
||||
AsciiDoctorTemplateResolver resolver =
|
||||
new AsciiDoctorTemplateResolver(language, resourceLoader);
|
||||
resolver.setCacheable(false);
|
||||
resolver.setOrder(1);
|
||||
resolver.setCharacterEncoding(UTF8);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpringTemplateEngine thymeleafTemplateEngine(ITemplateResolver springThymeleafTemplateResolver,
|
||||
LessonTemplateResolver lessonTemplateResolver,
|
||||
AsciiDoctorTemplateResolver asciiDoctorTemplateResolver,
|
||||
ITemplateResolver lessonThymeleafTemplateResolver) {
|
||||
SpringTemplateEngine engine = new SpringTemplateEngine();
|
||||
engine.setEnableSpringELCompiler(true);
|
||||
engine.addDialect(new SpringSecurityDialect());
|
||||
engine.setTemplateResolvers(
|
||||
Set.of(lessonTemplateResolver, asciiDoctorTemplateResolver, lessonThymeleafTemplateResolver, springThymeleafTemplateResolver));
|
||||
return engine;
|
||||
}
|
||||
@Bean
|
||||
public SpringTemplateEngine thymeleafTemplateEngine(
|
||||
ITemplateResolver springThymeleafTemplateResolver,
|
||||
LessonTemplateResolver lessonTemplateResolver,
|
||||
AsciiDoctorTemplateResolver asciiDoctorTemplateResolver,
|
||||
ITemplateResolver lessonThymeleafTemplateResolver) {
|
||||
SpringTemplateEngine engine = new SpringTemplateEngine();
|
||||
engine.setEnableSpringELCompiler(true);
|
||||
engine.addDialect(new SpringSecurityDialect());
|
||||
engine.setTemplateResolvers(
|
||||
Set.of(
|
||||
lessonTemplateResolver,
|
||||
asciiDoctorTemplateResolver,
|
||||
lessonThymeleafTemplateResolver,
|
||||
springThymeleafTemplateResolver));
|
||||
return engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
//WebGoat internal
|
||||
registry.addResourceHandler("/css/**").addResourceLocations("classpath:/webgoat/static/css/");
|
||||
registry.addResourceHandler("/js/**")
|
||||
.addResourceLocations("classpath:/webgoat/static/js/");
|
||||
registry.addResourceHandler("/plugins/**").addResourceLocations("classpath:/webgoat/static/plugins/");
|
||||
registry.addResourceHandler("/fonts/**").addResourceLocations("classpath:/webgoat/static/fonts/");
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
// WebGoat internal
|
||||
registry.addResourceHandler("/css/**").addResourceLocations("classpath:/webgoat/static/css/");
|
||||
registry.addResourceHandler("/js/**").addResourceLocations("classpath:/webgoat/static/js/");
|
||||
registry
|
||||
.addResourceHandler("/plugins/**")
|
||||
.addResourceLocations("classpath:/webgoat/static/plugins/");
|
||||
registry
|
||||
.addResourceHandler("/fonts/**")
|
||||
.addResourceLocations("classpath:/webgoat/static/fonts/");
|
||||
|
||||
//WebGoat lessons
|
||||
registry.addResourceHandler("/images/**").addResourceLocations(lessonScanner.applyPattern("classpath:/lessons/%s/images/").toArray(String[]::new));
|
||||
registry.addResourceHandler("/lesson_js/**").addResourceLocations(lessonScanner.applyPattern("classpath:/lessons/%s/js/").toArray(String[]::new));
|
||||
registry.addResourceHandler("/lesson_css/**").addResourceLocations(lessonScanner.applyPattern("classpath:/lessons/%s/css/").toArray(String[]::new));
|
||||
registry.addResourceHandler("/lesson_templates/**").addResourceLocations(lessonScanner.applyPattern("classpath:/lessons/%s/templates/").toArray(String[]::new));
|
||||
registry.addResourceHandler("/video/**").addResourceLocations(lessonScanner.applyPattern("classpath:/lessons/%s/video/").toArray(String[]::new));
|
||||
}
|
||||
// WebGoat lessons
|
||||
registry
|
||||
.addResourceHandler("/images/**")
|
||||
.addResourceLocations(
|
||||
lessonScanner.applyPattern("classpath:/lessons/%s/images/").toArray(String[]::new));
|
||||
registry
|
||||
.addResourceHandler("/lesson_js/**")
|
||||
.addResourceLocations(
|
||||
lessonScanner.applyPattern("classpath:/lessons/%s/js/").toArray(String[]::new));
|
||||
registry
|
||||
.addResourceHandler("/lesson_css/**")
|
||||
.addResourceLocations(
|
||||
lessonScanner.applyPattern("classpath:/lessons/%s/css/").toArray(String[]::new));
|
||||
registry
|
||||
.addResourceHandler("/lesson_templates/**")
|
||||
.addResourceLocations(
|
||||
lessonScanner.applyPattern("classpath:/lessons/%s/templates/").toArray(String[]::new));
|
||||
registry
|
||||
.addResourceHandler("/video/**")
|
||||
.addResourceLocations(
|
||||
lessonScanner.applyPattern("classpath:/lessons/%s/video/").toArray(String[]::new));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PluginMessages pluginMessages(Messages messages, Language language,
|
||||
ResourcePatternResolver resourcePatternResolver) {
|
||||
PluginMessages pluginMessages = new PluginMessages(messages, language, resourcePatternResolver);
|
||||
pluginMessages.setDefaultEncoding("UTF-8");
|
||||
pluginMessages.setBasenames("i18n/WebGoatLabels");
|
||||
pluginMessages.setFallbackToSystemLocale(false);
|
||||
return pluginMessages;
|
||||
}
|
||||
@Bean
|
||||
public PluginMessages pluginMessages(
|
||||
Messages messages, Language language, ResourcePatternResolver resourcePatternResolver) {
|
||||
PluginMessages pluginMessages = new PluginMessages(messages, language, resourcePatternResolver);
|
||||
pluginMessages.setDefaultEncoding("UTF-8");
|
||||
pluginMessages.setBasenames("i18n/WebGoatLabels");
|
||||
pluginMessages.setFallbackToSystemLocale(false);
|
||||
return pluginMessages;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Language language(LocaleResolver localeResolver) {
|
||||
return new Language(localeResolver);
|
||||
}
|
||||
@Bean
|
||||
public Language language(LocaleResolver localeResolver) {
|
||||
return new Language(localeResolver);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocaleResolver localeResolver() {
|
||||
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
|
||||
return localeResolver;
|
||||
}
|
||||
@Bean
|
||||
public LocaleResolver localeResolver() {
|
||||
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
|
||||
return localeResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocaleChangeInterceptor localeChangeInterceptor() {
|
||||
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
|
||||
lci.setParamName("lang");
|
||||
return lci;
|
||||
}
|
||||
@Bean
|
||||
public LocaleChangeInterceptor localeChangeInterceptor() {
|
||||
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
|
||||
lci.setParamName("lang");
|
||||
return lci;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(localeChangeInterceptor());
|
||||
}
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(localeChangeInterceptor());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Messages messageSource(Language language) {
|
||||
Messages messages = new Messages(language);
|
||||
messages.setDefaultEncoding("UTF-8");
|
||||
messages.setBasename("classpath:i18n/messages");
|
||||
messages.setFallbackToSystemLocale(false);
|
||||
return messages;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LabelDebugger labelDebugger() {
|
||||
return new LabelDebugger();
|
||||
}
|
||||
@Bean
|
||||
public Messages messageSource(Language language) {
|
||||
Messages messages = new Messages(language);
|
||||
messages.setDefaultEncoding("UTF-8");
|
||||
messages.setBasename("classpath:i18n/messages");
|
||||
messages.setFallbackToSystemLocale(false);
|
||||
return messages;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LabelDebugger labelDebugger() {
|
||||
return new LabelDebugger();
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,37 @@
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author WebGoat
|
||||
* @version $Id: $Id
|
||||
* @since October 28, 2003
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import java.io.File;
|
||||
import org.owasp.webgoat.container.session.UserSessionData;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -43,33 +44,31 @@ import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = { "org.owasp.webgoat.container", "org.owasp.webgoat.lessons"})
|
||||
@ComponentScan(basePackages = {"org.owasp.webgoat.container", "org.owasp.webgoat.lessons"})
|
||||
@PropertySource("classpath:application-webgoat.properties")
|
||||
@EnableAutoConfiguration
|
||||
public class WebGoat {
|
||||
|
||||
@Bean(name = "pluginTargetDirectory")
|
||||
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
|
||||
return new File(webgoatHome);
|
||||
}
|
||||
@Bean(name = "pluginTargetDirectory")
|
||||
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
|
||||
return new File(webgoatHome);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public WebSession webSession() {
|
||||
return new WebSession();
|
||||
}
|
||||
@Bean
|
||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public WebSession webSession() {
|
||||
return new WebSession();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public UserSessionData userSessionData() {
|
||||
return new UserSessionData("test", "data");
|
||||
}
|
||||
@Bean
|
||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public UserSessionData userSessionData() {
|
||||
return new UserSessionData("test", "data");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
}
|
||||
|
@ -2,36 +2,35 @@
|
||||
* ************************************************************************************************
|
||||
* 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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @author WebGoat
|
||||
* @version $Id: $Id
|
||||
* @since December 12, 2015
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.owasp.webgoat.container.i18n.Language;
|
||||
import org.owasp.webgoat.container.users.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -44,59 +43,66 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
||||
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||
|
||||
/**
|
||||
* Security configuration for WebGoat.
|
||||
*/
|
||||
/** Security configuration for WebGoat. */
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final UserService userDetailsService;
|
||||
private final UserService userDetailsService;
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry security = http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/css/**", "/images/**", "/js/**", "fonts/**", "/plugins/**", "/registration", "/register.mvc", "/actuator/**").permitAll()
|
||||
.anyRequest().authenticated();
|
||||
security.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.defaultSuccessUrl("/welcome.mvc", true)
|
||||
.usernameParameter("username")
|
||||
.passwordParameter("password")
|
||||
.permitAll();
|
||||
security.and()
|
||||
.logout().deleteCookies("JSESSIONID").invalidateHttpSession(true);
|
||||
security.and().csrf().disable();
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry security =
|
||||
http.authorizeRequests()
|
||||
.antMatchers(
|
||||
"/css/**",
|
||||
"/images/**",
|
||||
"/js/**",
|
||||
"fonts/**",
|
||||
"/plugins/**",
|
||||
"/registration",
|
||||
"/register.mvc",
|
||||
"/actuator/**")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.authenticated();
|
||||
security
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.defaultSuccessUrl("/welcome.mvc", true)
|
||||
.usernameParameter("username")
|
||||
.passwordParameter("password")
|
||||
.permitAll();
|
||||
security.and().logout().deleteCookies("JSESSIONID").invalidateHttpSession(true);
|
||||
security.and().csrf().disable();
|
||||
|
||||
http.headers().cacheControl().disable();
|
||||
http.exceptionHandling().authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"));
|
||||
}
|
||||
http.headers().cacheControl().disable();
|
||||
http.exceptionHandling().authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(userDetailsService);
|
||||
}
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(userDetailsService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public UserDetailsService userDetailsServiceBean() throws Exception {
|
||||
return userDetailsService;
|
||||
}
|
||||
@Bean
|
||||
@Override
|
||||
public UserDetailsService userDetailsServiceBean() throws Exception {
|
||||
return userDetailsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
protected AuthenticationManager authenticationManager() throws Exception {
|
||||
return super.authenticationManager();
|
||||
}
|
||||
@Override
|
||||
@Bean
|
||||
protected AuthenticationManager authenticationManager() throws Exception {
|
||||
return super.authenticationManager();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Bean
|
||||
public NoOpPasswordEncoder passwordEncoder() {
|
||||
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
@Bean
|
||||
public NoOpPasswordEncoder passwordEncoder() {
|
||||
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,12 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
@RequiredArgsConstructor
|
||||
public class WebWolfRedirect {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
@GetMapping("/WebWolf")
|
||||
public ModelAndView openWebWolf() {
|
||||
var url = applicationContext.getEnvironment().getProperty("webwolf.url");
|
||||
@GetMapping("/WebWolf")
|
||||
public ModelAndView openWebWolf() {
|
||||
var url = applicationContext.getEnvironment().getProperty("webwolf.url");
|
||||
|
||||
return new ModelAndView("redirect:" + url + "/home");
|
||||
}
|
||||
return new ModelAndView("redirect:" + url + "/home");
|
||||
}
|
||||
}
|
||||
|
@ -7,19 +7,20 @@ import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Make environment available in the asciidoc code (which you cannot inject because it is handled by the framework)
|
||||
* Make environment available in the asciidoc code (which you cannot inject because it is handled by
|
||||
* the framework)
|
||||
*/
|
||||
@Component
|
||||
public class EnvironmentExposure implements ApplicationContextAware {
|
||||
|
||||
private static ApplicationContext context;
|
||||
private static ApplicationContext context;
|
||||
|
||||
public static Environment getEnv() {
|
||||
return context.getEnvironment();
|
||||
}
|
||||
public static Environment getEnv() {
|
||||
return context.getEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
context = applicationContext;
|
||||
}
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
context = applicationContext;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
package org.owasp.webgoat.container.asciidoc;
|
||||
|
||||
import java.util.Map;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class OperatingSystemMacro extends InlineMacroProcessor {
|
||||
|
||||
public OperatingSystemMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
public OperatingSystemMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
|
||||
public OperatingSystemMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
public OperatingSystemMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var osName = System.getProperty("os.name");
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var osName = System.getProperty("os.name");
|
||||
|
||||
//see https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", osName);
|
||||
}
|
||||
// see
|
||||
// https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", osName);
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
package org.owasp.webgoat.container.asciidoc;
|
||||
|
||||
import java.util.Map;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class UsernameMacro extends InlineMacroProcessor {
|
||||
|
||||
public UsernameMacro(String macroName) {
|
||||
super(macroName);
|
||||
public UsernameMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
|
||||
public UsernameMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
var username = "unknown";
|
||||
if (auth.getPrincipal() instanceof WebGoatUser webGoatUser) {
|
||||
username = webGoatUser.getUsername();
|
||||
}
|
||||
|
||||
public UsernameMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
var username = "unknown";
|
||||
if (auth.getPrincipal() instanceof WebGoatUser webGoatUser) {
|
||||
username = webGoatUser.getUsername();
|
||||
}
|
||||
|
||||
//see https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", username);
|
||||
}
|
||||
// see
|
||||
// https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", username);
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,25 @@
|
||||
package org.owasp.webgoat.container.asciidoc;
|
||||
|
||||
import java.util.Map;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class WebGoatTmpDirMacro extends InlineMacroProcessor {
|
||||
|
||||
public WebGoatTmpDirMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
public WebGoatTmpDirMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
|
||||
public WebGoatTmpDirMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
public WebGoatTmpDirMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var env = EnvironmentExposure.getEnv().getProperty("webgoat.server.directory");
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var env = EnvironmentExposure.getEnv().getProperty("webgoat.server.directory");
|
||||
|
||||
//see https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", env);
|
||||
|
||||
}
|
||||
// see
|
||||
// https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", env);
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
package org.owasp.webgoat.container.asciidoc;
|
||||
|
||||
import java.util.Map;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class WebGoatVersionMacro extends InlineMacroProcessor {
|
||||
|
||||
public WebGoatVersionMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
public WebGoatVersionMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
|
||||
public WebGoatVersionMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
public WebGoatVersionMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var webgoatVersion = EnvironmentExposure.getEnv().getProperty("webgoat.build.version");
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String target, Map<String, Object> attributes) {
|
||||
var webgoatVersion = EnvironmentExposure.getEnv().getProperty("webgoat.build.version");
|
||||
|
||||
//see https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", webgoatVersion);
|
||||
}
|
||||
// see
|
||||
// https://discuss.asciidoctor.org/How-to-create-inline-macro-producing-HTML-In-AsciidoctorJ-td8313.html for why quoted is used
|
||||
return createPhraseNode(contentNode, "quoted", webgoatVersion);
|
||||
}
|
||||
}
|
||||
|
@ -1,73 +1,73 @@
|
||||
package org.owasp.webgoat.container.asciidoc;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Usage in asciidoc:
|
||||
* <p>
|
||||
* webWolfLink:here[] will display a href with here as text
|
||||
*
|
||||
* <p>webWolfLink:here[] will display a href with here as text
|
||||
*/
|
||||
public class WebWolfMacro extends InlineMacroProcessor {
|
||||
|
||||
public WebWolfMacro(String macroName) {
|
||||
super(macroName);
|
||||
public WebWolfMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
|
||||
public WebWolfMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String linkText, Map<String, Object> attributes) {
|
||||
var env = EnvironmentExposure.getEnv();
|
||||
var hostname = determineHost(env.getProperty("webwolf.port"));
|
||||
var target = (String) attributes.getOrDefault("target", "home");
|
||||
var href = hostname + "/" + target;
|
||||
|
||||
// are we using noLink in webWolfLink:landing[noLink]? Then display link with full href
|
||||
if (displayCompleteLinkNoFormatting(attributes)) {
|
||||
linkText = href;
|
||||
}
|
||||
|
||||
public WebWolfMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
var options = new HashMap<String, Object>();
|
||||
options.put("type", ":link");
|
||||
options.put("target", href);
|
||||
attributes.put("window", "_blank");
|
||||
return createPhraseNode(contentNode, "anchor", linkText, attributes, options).convert();
|
||||
}
|
||||
|
||||
private boolean displayCompleteLinkNoFormatting(Map<String, Object> attributes) {
|
||||
return attributes.values().stream().anyMatch(a -> a.equals("noLink"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the host from the hostname and ports that were used. The purpose is to make it
|
||||
* possible to use the application behind a reverse proxy. For instance in the docker
|
||||
* compose/stack version with webgoat webwolf and nginx proxy. You do not have to use the
|
||||
* indicated hostname, but if you do, you should define two hosts aliases 127.0.0.1
|
||||
* www.webgoat.local www.webwolf.local
|
||||
*/
|
||||
private String determineHost(String port) {
|
||||
HttpServletRequest request =
|
||||
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||
String host = request.getHeader("Host");
|
||||
int semicolonIndex = host.indexOf(":");
|
||||
if (semicolonIndex == -1 || host.endsWith(":80")) {
|
||||
host = host.replace(":80", "").replace("www.webgoat.local", "www.webwolf.local");
|
||||
} else {
|
||||
host = host.substring(0, semicolonIndex);
|
||||
host = host.concat(":").concat(port);
|
||||
}
|
||||
return "http://" + host + (includeWebWolfContext() ? "/WebWolf" : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String linkText, Map<String, Object> attributes) {
|
||||
var env = EnvironmentExposure.getEnv();
|
||||
var hostname = determineHost(env.getProperty("webwolf.port"));
|
||||
var target = (String) attributes.getOrDefault("target", "home");
|
||||
var href = hostname + "/" + target;
|
||||
|
||||
//are we using noLink in webWolfLink:landing[noLink]? Then display link with full href
|
||||
if (displayCompleteLinkNoFormatting(attributes)) {
|
||||
linkText = href;
|
||||
}
|
||||
|
||||
var options = new HashMap<String, Object>();
|
||||
options.put("type", ":link");
|
||||
options.put("target", href);
|
||||
attributes.put("window", "_blank");
|
||||
return createPhraseNode(contentNode, "anchor", linkText, attributes, options).convert();
|
||||
}
|
||||
|
||||
private boolean displayCompleteLinkNoFormatting(Map<String, Object> attributes) {
|
||||
return attributes.values().stream().anyMatch(a -> a.equals("noLink"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the host from the hostname and ports that were used.
|
||||
* The purpose is to make it possible to use the application behind a reverse proxy. For instance in the docker
|
||||
* compose/stack version with webgoat webwolf and nginx proxy.
|
||||
* You do not have to use the indicated hostname, but if you do, you should define two hosts aliases
|
||||
* 127.0.0.1 www.webgoat.local www.webwolf.local
|
||||
*/
|
||||
private String determineHost(String port) {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||
String host = request.getHeader("Host");
|
||||
int semicolonIndex = host.indexOf(":");
|
||||
if (semicolonIndex == -1 || host.endsWith(":80")) {
|
||||
host = host.replace(":80", "").replace("www.webgoat.local", "www.webwolf.local");
|
||||
} else {
|
||||
host = host.substring(0, semicolonIndex);
|
||||
host = host.concat(":").concat(port);
|
||||
}
|
||||
return "http://" + host + (includeWebWolfContext() ? "/WebWolf" : "");
|
||||
}
|
||||
|
||||
protected boolean includeWebWolfContext() {
|
||||
return true;
|
||||
}
|
||||
protected boolean includeWebWolfContext() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4,22 +4,22 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Usage in asciidoc:
|
||||
* <p>
|
||||
* webWolfLink:here[] will display a href with here as text
|
||||
* webWolfLink:landing[noLink] will display the complete url, for example: http://WW_HOST:WW_PORT/landing
|
||||
*
|
||||
* <p>webWolfLink:here[] will display a href with here as text webWolfLink:landing[noLink] will
|
||||
* display the complete url, for example: http://WW_HOST:WW_PORT/landing
|
||||
*/
|
||||
public class WebWolfRootMacro extends WebWolfMacro {
|
||||
|
||||
public WebWolfRootMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
public WebWolfRootMacro(String macroName) {
|
||||
super(macroName);
|
||||
}
|
||||
|
||||
public WebWolfRootMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
public WebWolfRootMacro(String macroName, Map<String, Object> config) {
|
||||
super(macroName, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean includeWebWolfContext() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
protected boolean includeWebWolfContext() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -35,57 +35,58 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public abstract class AssignmentEndpoint implements Initializeable {
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
@Autowired
|
||||
private UserSessionData userSessionData;
|
||||
@Getter
|
||||
@Autowired
|
||||
private PluginMessages messages;
|
||||
@Autowired private WebSession webSession;
|
||||
@Autowired private UserSessionData userSessionData;
|
||||
@Getter @Autowired private PluginMessages messages;
|
||||
|
||||
protected WebSession getWebSession() {
|
||||
return webSession;
|
||||
}
|
||||
protected WebSession getWebSession() {
|
||||
return webSession;
|
||||
}
|
||||
|
||||
protected UserSessionData getUserSessionData() {
|
||||
return userSessionData;
|
||||
}
|
||||
protected UserSessionData getUserSessionData() {
|
||||
return userSessionData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for create a successful result:
|
||||
* <p>
|
||||
* - Assignment is set to solved
|
||||
* - Feedback message is set to 'assignment.solved'
|
||||
* <p>
|
||||
* Of course you can overwrite these values in a specific lesson
|
||||
*
|
||||
* @return a builder for creating a result from a lesson
|
||||
* @param assignment
|
||||
*/
|
||||
protected AttackResult.AttackResultBuilder success(AssignmentEndpoint assignment) {
|
||||
return AttackResult.builder(messages).lessonCompleted(true).attemptWasMade().feedback("assignment.solved").assignment(assignment);
|
||||
}
|
||||
/**
|
||||
* Convenience method for create a successful result:
|
||||
*
|
||||
* <p>- Assignment is set to solved - Feedback message is set to 'assignment.solved'
|
||||
*
|
||||
* <p>Of course you can overwrite these values in a specific lesson
|
||||
*
|
||||
* @return a builder for creating a result from a lesson
|
||||
* @param assignment
|
||||
*/
|
||||
protected AttackResult.AttackResultBuilder success(AssignmentEndpoint assignment) {
|
||||
return AttackResult.builder(messages)
|
||||
.lessonCompleted(true)
|
||||
.attemptWasMade()
|
||||
.feedback("assignment.solved")
|
||||
.assignment(assignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for create a failed result:
|
||||
* <p>
|
||||
* - Assignment is set to not solved
|
||||
* - Feedback message is set to 'assignment.not.solved'
|
||||
* <p>
|
||||
* Of course you can overwrite these values in a specific lesson
|
||||
*
|
||||
* @return a builder for creating a result from a lesson
|
||||
* @param assignment
|
||||
*/
|
||||
protected AttackResult.AttackResultBuilder failed(AssignmentEndpoint assignment) {
|
||||
return AttackResult.builder(messages).lessonCompleted(false).attemptWasMade().feedback("assignment.not.solved").assignment(assignment);
|
||||
}
|
||||
/**
|
||||
* Convenience method for create a failed result:
|
||||
*
|
||||
* <p>- Assignment is set to not solved - Feedback message is set to 'assignment.not.solved'
|
||||
*
|
||||
* <p>Of course you can overwrite these values in a specific lesson
|
||||
*
|
||||
* @return a builder for creating a result from a lesson
|
||||
* @param assignment
|
||||
*/
|
||||
protected AttackResult.AttackResultBuilder failed(AssignmentEndpoint assignment) {
|
||||
return AttackResult.builder(messages)
|
||||
.lessonCompleted(false)
|
||||
.attemptWasMade()
|
||||
.feedback("assignment.not.solved")
|
||||
.assignment(assignment);
|
||||
}
|
||||
|
||||
protected AttackResult.AttackResultBuilder informationMessage(AssignmentEndpoint assignment) {
|
||||
return AttackResult.builder(messages).lessonCompleted(false).assignment(assignment);
|
||||
}
|
||||
protected AttackResult.AttackResultBuilder informationMessage(AssignmentEndpoint assignment) {
|
||||
return AttackResult.builder(messages).lessonCompleted(false).assignment(assignment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(WebGoatUser user) {
|
||||
}
|
||||
@Override
|
||||
public void initialize(WebGoatUser user) {}
|
||||
}
|
||||
|
@ -5,12 +5,10 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Created by nbaars on 1/14/17.
|
||||
*/
|
||||
/** Created by nbaars on 1/14/17. */
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AssignmentHints {
|
||||
|
||||
String[] value() default {};
|
||||
String[] value() default {};
|
||||
}
|
||||
|
@ -1,22 +1,19 @@
|
||||
package org.owasp.webgoat.container.assignments;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
/**
|
||||
* Created by nbaars on 1/14/17.
|
||||
*/
|
||||
/** Created by nbaars on 1/14/17. */
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AssignmentPath {
|
||||
|
||||
String[] path() default {};
|
||||
String[] path() default {};
|
||||
|
||||
RequestMethod[] method() default {};
|
||||
RequestMethod[] method() default {};
|
||||
|
||||
String value() default "";
|
||||
String value() default "";
|
||||
}
|
||||
|
@ -25,100 +25,104 @@
|
||||
|
||||
package org.owasp.webgoat.container.assignments;
|
||||
|
||||
import static org.apache.commons.text.StringEscapeUtils.escapeJson;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
||||
|
||||
import static org.apache.commons.text.StringEscapeUtils.escapeJson;
|
||||
|
||||
public class AttackResult {
|
||||
|
||||
public static class AttackResultBuilder {
|
||||
|
||||
public static class AttackResultBuilder {
|
||||
|
||||
private boolean lessonCompleted;
|
||||
private PluginMessages messages;
|
||||
private Object[] feedbackArgs;
|
||||
private String feedbackResourceBundleKey;
|
||||
private String output;
|
||||
private Object[] outputArgs;
|
||||
private AssignmentEndpoint assignment;
|
||||
private boolean attemptWasMade = false;
|
||||
|
||||
public AttackResultBuilder(PluginMessages messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public AttackResultBuilder lessonCompleted(boolean lessonCompleted) {
|
||||
this.lessonCompleted = lessonCompleted;
|
||||
this.feedbackResourceBundleKey = "lesson.completed";
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder lessonCompleted(boolean lessonCompleted, String resourceBundleKey) {
|
||||
this.lessonCompleted = lessonCompleted;
|
||||
this.feedbackResourceBundleKey = resourceBundleKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder feedbackArgs(Object... args) {
|
||||
this.feedbackArgs = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder feedback(String resourceBundleKey) {
|
||||
this.feedbackResourceBundleKey = resourceBundleKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder output(String output) {
|
||||
this.output = output;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder outputArgs(Object... args) {
|
||||
this.outputArgs = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder attemptWasMade() {
|
||||
this.attemptWasMade = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResult build() {
|
||||
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs), assignment.getClass().getSimpleName(), attemptWasMade);
|
||||
}
|
||||
|
||||
public AttackResultBuilder assignment(AssignmentEndpoint assignment) {
|
||||
this.assignment = assignment;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private boolean lessonCompleted;
|
||||
@Getter
|
||||
private String feedback;
|
||||
@Getter
|
||||
private PluginMessages messages;
|
||||
private Object[] feedbackArgs;
|
||||
private String feedbackResourceBundleKey;
|
||||
private String output;
|
||||
@Getter
|
||||
private final String assignment;
|
||||
@Getter
|
||||
private boolean attemptWasMade;
|
||||
private Object[] outputArgs;
|
||||
private AssignmentEndpoint assignment;
|
||||
private boolean attemptWasMade = false;
|
||||
|
||||
public AttackResult(boolean lessonCompleted, String feedback, String output, String assignment, boolean attemptWasMade) {
|
||||
this.lessonCompleted = lessonCompleted;
|
||||
this.feedback = escapeJson(feedback);
|
||||
this.output = escapeJson(output);
|
||||
this.assignment = assignment;
|
||||
this.attemptWasMade = attemptWasMade;
|
||||
public AttackResultBuilder(PluginMessages messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public static AttackResultBuilder builder(PluginMessages messages) {
|
||||
return new AttackResultBuilder(messages);
|
||||
public AttackResultBuilder lessonCompleted(boolean lessonCompleted) {
|
||||
this.lessonCompleted = lessonCompleted;
|
||||
this.feedbackResourceBundleKey = "lesson.completed";
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean assignmentSolved() {
|
||||
return lessonCompleted;
|
||||
public AttackResultBuilder lessonCompleted(boolean lessonCompleted, String resourceBundleKey) {
|
||||
this.lessonCompleted = lessonCompleted;
|
||||
this.feedbackResourceBundleKey = resourceBundleKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder feedbackArgs(Object... args) {
|
||||
this.feedbackArgs = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder feedback(String resourceBundleKey) {
|
||||
this.feedbackResourceBundleKey = resourceBundleKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder output(String output) {
|
||||
this.output = output;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder outputArgs(Object... args) {
|
||||
this.outputArgs = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResultBuilder attemptWasMade() {
|
||||
this.attemptWasMade = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttackResult build() {
|
||||
return new AttackResult(
|
||||
lessonCompleted,
|
||||
messages.getMessage(feedbackResourceBundleKey, feedbackArgs),
|
||||
messages.getMessage(output, output, outputArgs),
|
||||
assignment.getClass().getSimpleName(),
|
||||
attemptWasMade);
|
||||
}
|
||||
|
||||
public AttackResultBuilder assignment(AssignmentEndpoint assignment) {
|
||||
this.assignment = assignment;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter private boolean lessonCompleted;
|
||||
@Getter private String feedback;
|
||||
@Getter private String output;
|
||||
@Getter private final String assignment;
|
||||
@Getter private boolean attemptWasMade;
|
||||
|
||||
public AttackResult(
|
||||
boolean lessonCompleted,
|
||||
String feedback,
|
||||
String output,
|
||||
String assignment,
|
||||
boolean attemptWasMade) {
|
||||
this.lessonCompleted = lessonCompleted;
|
||||
this.feedback = escapeJson(feedback);
|
||||
this.output = escapeJson(output);
|
||||
this.assignment = assignment;
|
||||
this.attemptWasMade = attemptWasMade;
|
||||
}
|
||||
|
||||
public static AttackResultBuilder builder(PluginMessages messages) {
|
||||
return new AttackResultBuilder(messages);
|
||||
}
|
||||
|
||||
public boolean assignmentSolved() {
|
||||
return lessonCompleted;
|
||||
}
|
||||
}
|
||||
|
@ -36,39 +36,46 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||
@RestControllerAdvice
|
||||
public class LessonTrackerInterceptor implements ResponseBodyAdvice<Object> {
|
||||
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
private WebSession webSession;
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
private WebSession webSession;
|
||||
|
||||
public LessonTrackerInterceptor(UserTrackerRepository userTrackerRepository, WebSession webSession) {
|
||||
this.userTrackerRepository = userTrackerRepository;
|
||||
this.webSession = webSession;
|
||||
public LessonTrackerInterceptor(
|
||||
UserTrackerRepository userTrackerRepository, WebSession webSession) {
|
||||
this.userTrackerRepository = userTrackerRepository;
|
||||
this.webSession = webSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(
|
||||
MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object beforeBodyWrite(
|
||||
Object o,
|
||||
MethodParameter methodParameter,
|
||||
MediaType mediaType,
|
||||
Class<? extends HttpMessageConverter<?>> aClass,
|
||||
ServerHttpRequest serverHttpRequest,
|
||||
ServerHttpResponse serverHttpResponse) {
|
||||
if (o instanceof AttackResult attackResult) {
|
||||
trackProgress(attackResult);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> clazz) {
|
||||
return true;
|
||||
protected AttackResult trackProgress(AttackResult attackResult) {
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
if (userTracker == null) {
|
||||
userTracker = new UserTracker(webSession.getUserName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
|
||||
if (o instanceof AttackResult attackResult) {
|
||||
trackProgress(attackResult);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
protected AttackResult trackProgress(AttackResult attackResult) {
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
if (userTracker == null) {
|
||||
userTracker = new UserTracker(webSession.getUserName());
|
||||
}
|
||||
if (attackResult.assignmentSolved()) {
|
||||
userTracker.assignmentSolved(webSession.getCurrentLesson(), attackResult.getAssignment());
|
||||
} else {
|
||||
userTracker.assignmentFailed(webSession.getCurrentLesson());
|
||||
}
|
||||
userTrackerRepository.saveAndFlush(userTracker);
|
||||
return attackResult;
|
||||
if (attackResult.assignmentSolved()) {
|
||||
userTracker.assignmentSolved(webSession.getCurrentLesson(), attackResult.getAssignment());
|
||||
} else {
|
||||
userTracker.assignmentFailed(webSession.getCurrentLesson());
|
||||
}
|
||||
userTrackerRepository.saveAndFlush(userTracker);
|
||||
return attackResult;
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,37 @@
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author WebGoat
|
||||
* @version $Id: $Id
|
||||
* @since October 28, 2003
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.owasp.webgoat.container.session.Course;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@ -38,52 +39,52 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
@Controller
|
||||
public class StartLesson {
|
||||
|
||||
private final WebSession ws;
|
||||
private final Course course;
|
||||
private final WebSession ws;
|
||||
private final Course course;
|
||||
|
||||
public StartLesson(WebSession ws, Course course) {
|
||||
this.ws = ws;
|
||||
this.course = course;
|
||||
}
|
||||
public StartLesson(WebSession ws, Course course) {
|
||||
this.ws = ws;
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>start.</p>
|
||||
*
|
||||
* @return a {@link ModelAndView} object.
|
||||
*/
|
||||
@RequestMapping(path = "startlesson.mvc", method = {RequestMethod.GET, RequestMethod.POST})
|
||||
public ModelAndView start() {
|
||||
var model = new ModelAndView();
|
||||
/**
|
||||
* start.
|
||||
*
|
||||
* @return a {@link ModelAndView} object.
|
||||
*/
|
||||
@RequestMapping(
|
||||
path = "startlesson.mvc",
|
||||
method = {RequestMethod.GET, RequestMethod.POST})
|
||||
public ModelAndView start() {
|
||||
var model = new ModelAndView();
|
||||
|
||||
model.addObject("course", course);
|
||||
model.addObject("lesson", ws.getCurrentLesson());
|
||||
model.setViewName("lesson_content");
|
||||
model.addObject("course", course);
|
||||
model.addObject("lesson", ws.getCurrentLesson());
|
||||
model.setViewName("lesson_content");
|
||||
|
||||
return model;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@RequestMapping(value = {"*.lesson"}, produces = "text/html")
|
||||
public ModelAndView lessonPage(HttpServletRequest request) {
|
||||
var model = new ModelAndView("lesson_content");
|
||||
var path = request.getRequestURL().toString(); // we now got /a/b/c/AccessControlMatrix.lesson
|
||||
var lessonName = path.substring(path.lastIndexOf('/') + 1, path.indexOf(".lesson"));
|
||||
@RequestMapping(
|
||||
value = {"*.lesson"},
|
||||
produces = "text/html")
|
||||
public ModelAndView lessonPage(HttpServletRequest request) {
|
||||
var model = new ModelAndView("lesson_content");
|
||||
var path = request.getRequestURL().toString(); // we now got /a/b/c/AccessControlMatrix.lesson
|
||||
var lessonName = path.substring(path.lastIndexOf('/') + 1, path.indexOf(".lesson"));
|
||||
|
||||
course.getLessons()
|
||||
.stream()
|
||||
.filter(l -> l.getId().equals(lessonName))
|
||||
.findFirst()
|
||||
.ifPresent(lesson -> {
|
||||
ws.setCurrentLesson(lesson);
|
||||
model.addObject("lesson", lesson);
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
course.getLessons().stream()
|
||||
.filter(l -> l.getId().equals(lessonName))
|
||||
.findFirst()
|
||||
.ifPresent(
|
||||
lesson -> {
|
||||
ws.setCurrentLesson(lesson);
|
||||
model.addObject("lesson", lesson);
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,42 @@
|
||||
/**
|
||||
*************************************************************************************************
|
||||
* ************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* <p>This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
* <p>Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* <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.
|
||||
*
|
||||
* 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>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
|
||||
* <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.
|
||||
*
|
||||
* Getting Source ==============
|
||||
* <p>Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author WebGoat
|
||||
* @since October 28, 2003
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* <p>Welcome class.</p>
|
||||
* Welcome class.
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
@ -47,29 +44,28 @@ import javax.servlet.http.HttpSession;
|
||||
@Controller
|
||||
public class Welcome {
|
||||
|
||||
private static final String WELCOMED = "welcomed";
|
||||
|
||||
/**
|
||||
* <p>welcome.</p>
|
||||
*
|
||||
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
|
||||
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
|
||||
*/
|
||||
@GetMapping(path = {"welcome.mvc"})
|
||||
public ModelAndView welcome(HttpServletRequest request) {
|
||||
private static final String WELCOMED = "welcomed";
|
||||
|
||||
// set the welcome attribute
|
||||
// this is so the attack servlet does not also
|
||||
// send them to the welcome page
|
||||
HttpSession session = request.getSession();
|
||||
if (session.getAttribute(WELCOMED) == null) {
|
||||
session.setAttribute(WELCOMED, "true");
|
||||
}
|
||||
|
||||
//go ahead and send them to webgoat (skip the welcome page)
|
||||
ModelAndView model = new ModelAndView();
|
||||
model.setViewName("forward:/attack?start=true");
|
||||
return model;
|
||||
/**
|
||||
* welcome.
|
||||
*
|
||||
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
|
||||
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
|
||||
*/
|
||||
@GetMapping(path = {"welcome.mvc"})
|
||||
public ModelAndView welcome(HttpServletRequest request) {
|
||||
|
||||
// set the welcome attribute
|
||||
// this is so the attack servlet does not also
|
||||
// send them to the welcome page
|
||||
HttpSession session = request.getSession();
|
||||
if (session.getAttribute(WELCOMED) == null) {
|
||||
session.setAttribute(WELCOMED, "true");
|
||||
}
|
||||
|
||||
|
||||
// go ahead and send them to webgoat (skip the welcome page)
|
||||
ModelAndView model = new ModelAndView();
|
||||
model.setViewName("forward:/attack?start=true");
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
@ -25,15 +25,15 @@
|
||||
|
||||
package org.owasp.webgoat.container.i18n;
|
||||
|
||||
import java.util.Locale;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Wrapper around the LocaleResolver from Spring so we do not need to bother with passing the HttpRequest object
|
||||
* when asking for a Locale.
|
||||
* Wrapper around the LocaleResolver from Spring so we do not need to bother with passing the
|
||||
* HttpRequest object when asking for a Locale.
|
||||
*
|
||||
* @author nbaars
|
||||
* @date 2/7/17
|
||||
@ -41,9 +41,10 @@ import java.util.Locale;
|
||||
@AllArgsConstructor
|
||||
public class Language {
|
||||
|
||||
private final LocaleResolver localeResolver;
|
||||
private final LocaleResolver localeResolver;
|
||||
|
||||
public Locale getLocale() {
|
||||
return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
|
||||
}
|
||||
public Locale getLocale() {
|
||||
return localeResolver.resolveLocale(
|
||||
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
|
||||
}
|
||||
}
|
||||
|
@ -25,36 +25,35 @@
|
||||
|
||||
package org.owasp.webgoat.container.i18n;
|
||||
|
||||
import java.util.Properties;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* <p>ExposedReloadableResourceMessageBundleSource class.</p>
|
||||
* Extends the reloadable message source with a way to get all messages
|
||||
* ExposedReloadableResourceMessageBundleSource class. Extends the reloadable message source with a
|
||||
* way to get all messages
|
||||
*
|
||||
* @author zupzup
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class Messages extends ReloadableResourceBundleMessageSource {
|
||||
|
||||
private final Language language;
|
||||
private final Language language;
|
||||
|
||||
/**
|
||||
* Gets all messages for presented Locale.
|
||||
*
|
||||
* @return all messages
|
||||
*/
|
||||
public Properties getMessages() {
|
||||
return getMergedProperties(language.getLocale()).getProperties();
|
||||
}
|
||||
/**
|
||||
* Gets all messages for presented Locale.
|
||||
*
|
||||
* @return all messages
|
||||
*/
|
||||
public Properties getMessages() {
|
||||
return getMergedProperties(language.getLocale()).getProperties();
|
||||
}
|
||||
|
||||
public String getMessage(String code, Object... args) {
|
||||
return getMessage(code, args, language.getLocale());
|
||||
}
|
||||
public String getMessage(String code, Object... args) {
|
||||
return getMessage(code, args, language.getLocale());
|
||||
}
|
||||
|
||||
public String getMessage(String code, String defaultValue, Object... args) {
|
||||
return super.getMessage(code, args, defaultValue, language.getLocale());
|
||||
}
|
||||
public String getMessage(String code, String defaultValue, Object... args) {
|
||||
return super.getMessage(code, args, defaultValue, language.getLocale());
|
||||
}
|
||||
}
|
||||
|
@ -25,11 +25,10 @@
|
||||
|
||||
package org.owasp.webgoat.container.i18n;
|
||||
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
/**
|
||||
* Message resource bundle for plugins.
|
||||
@ -38,49 +37,49 @@ import java.util.Properties;
|
||||
* @date 2/4/17
|
||||
*/
|
||||
public class PluginMessages extends ReloadableResourceBundleMessageSource {
|
||||
private static final String PROPERTIES_SUFFIX = ".properties";
|
||||
private static final String PROPERTIES_SUFFIX = ".properties";
|
||||
|
||||
private final Language language;
|
||||
private final ResourcePatternResolver resourcePatternResolver;
|
||||
private final Language language;
|
||||
private final ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
public PluginMessages(
|
||||
Messages messages, Language language, ResourcePatternResolver resourcePatternResolver) {
|
||||
this.language = language;
|
||||
this.setParentMessageSource(messages);
|
||||
this.setBasename("WebGoatLabels");
|
||||
this.resourcePatternResolver = resourcePatternResolver;
|
||||
}
|
||||
|
||||
public PluginMessages(Messages messages, Language language, ResourcePatternResolver resourcePatternResolver) {
|
||||
this.language = language;
|
||||
this.setParentMessageSource(messages);
|
||||
this.setBasename("WebGoatLabels");
|
||||
this.resourcePatternResolver = resourcePatternResolver;
|
||||
@Override
|
||||
protected PropertiesHolder refreshProperties(String filename, PropertiesHolder propHolder) {
|
||||
Properties properties = new Properties();
|
||||
long lastModified = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
var resources =
|
||||
resourcePatternResolver.getResources(
|
||||
"classpath:/lessons/**/i18n" + "/WebGoatLabels" + PROPERTIES_SUFFIX);
|
||||
for (var resource : resources) {
|
||||
String sourcePath = resource.getURI().toString().replace(PROPERTIES_SUFFIX, "");
|
||||
PropertiesHolder holder = super.refreshProperties(sourcePath, propHolder);
|
||||
properties.putAll(holder.getProperties());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to read plugin message", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertiesHolder refreshProperties(String filename, PropertiesHolder propHolder) {
|
||||
Properties properties = new Properties();
|
||||
long lastModified = System.currentTimeMillis();
|
||||
return new PropertiesHolder(properties, lastModified);
|
||||
}
|
||||
|
||||
try {
|
||||
var resources = resourcePatternResolver.getResources("classpath:/lessons/**/i18n" +
|
||||
"/WebGoatLabels" + PROPERTIES_SUFFIX);
|
||||
for (var resource : resources) {
|
||||
String sourcePath = resource.getURI().toString().replace(PROPERTIES_SUFFIX, "");
|
||||
PropertiesHolder holder = super.refreshProperties(sourcePath, propHolder);
|
||||
properties.putAll(holder.getProperties());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to read plugin message", e);
|
||||
}
|
||||
public Properties getMessages() {
|
||||
return getMergedProperties(language.getLocale()).getProperties();
|
||||
}
|
||||
|
||||
return new PropertiesHolder(properties, lastModified);
|
||||
}
|
||||
public String getMessage(String code, Object... args) {
|
||||
return getMessage(code, args, language.getLocale());
|
||||
}
|
||||
|
||||
|
||||
public Properties getMessages() {
|
||||
return getMergedProperties(language.getLocale()).getProperties();
|
||||
}
|
||||
|
||||
public String getMessage(String code, Object... args) {
|
||||
return getMessage(code, args, language.getLocale());
|
||||
}
|
||||
|
||||
public String getMessage(String code, String defaultValue, Object... args) {
|
||||
return super.getMessage(code, args, defaultValue, language.getLocale());
|
||||
}
|
||||
public String getMessage(String code, String defaultValue, Object... args) {
|
||||
return super.getMessage(code, args, defaultValue, language.getLocale());
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* 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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @author nbaars
|
||||
@ -40,30 +40,33 @@ import java.util.List;
|
||||
@Entity
|
||||
public class Assignment {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
private String name;
|
||||
private String path;
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Transient
|
||||
private List<String> hints;
|
||||
private String name;
|
||||
private String path;
|
||||
|
||||
private Assignment() {
|
||||
//Hibernate
|
||||
@Transient private List<String> hints;
|
||||
|
||||
private Assignment() {
|
||||
// Hibernate
|
||||
}
|
||||
|
||||
public Assignment(String name) {
|
||||
this(name, name, new ArrayList<>());
|
||||
}
|
||||
|
||||
public Assignment(String name, String path, List<String> hints) {
|
||||
if (path.equals("") || path.equals("/") || path.equals("/WebGoat/")) {
|
||||
throw new IllegalStateException(
|
||||
"The path of assignment '"
|
||||
+ name
|
||||
+ "' overrides WebGoat endpoints, please choose a path within the scope of the"
|
||||
+ " lesson");
|
||||
}
|
||||
|
||||
public Assignment(String name) {
|
||||
this(name, name, new ArrayList<>());
|
||||
}
|
||||
|
||||
public Assignment(String name, String path, List<String> hints) {
|
||||
if (path.equals("") || path.equals("/") || path.equals("/WebGoat/")) {
|
||||
throw new IllegalStateException("The path of assignment '" + name + "' overrides WebGoat endpoints, please choose a path within the scope of the lesson");
|
||||
}
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
this.hints = hints;
|
||||
}
|
||||
}
|
||||
|
@ -4,30 +4,29 @@ import lombok.Getter;
|
||||
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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
|
||||
*
|
||||
* <p>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 - 2014 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.
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
@ -35,40 +34,35 @@ import lombok.Getter;
|
||||
* @since October 28, 2003
|
||||
*/
|
||||
public enum Category {
|
||||
INTRODUCTION("Introduction", 5),
|
||||
GENERAL("General", 100),
|
||||
|
||||
INTRODUCTION("Introduction", 5),
|
||||
GENERAL("General", 100),
|
||||
|
||||
A1("(A1) Broken Access Control", 301),
|
||||
A2("(A2) Cryptographic Failures", 302),
|
||||
A3("(A3) Injection", 303),
|
||||
A1("(A1) Broken Access Control", 301),
|
||||
A2("(A2) Cryptographic Failures", 302),
|
||||
A3("(A3) Injection", 303),
|
||||
|
||||
A5("(A5) Security Misconfiguration", 305),
|
||||
A6("(A6) Vuln & Outdated Components", 306),
|
||||
A7("(A7) Identity & Auth Failure", 307),
|
||||
A8("(A8) Software & Data Integrity", 308),
|
||||
A9("(A9) Security Logging Failures", 309),
|
||||
A10("(A10) Server-side Request Forgery", 310),
|
||||
|
||||
CLIENT_SIDE("Client side", 1700),
|
||||
A5("(A5) Security Misconfiguration", 305),
|
||||
A6("(A6) Vuln & Outdated Components", 306),
|
||||
A7("(A7) Identity & Auth Failure", 307),
|
||||
A8("(A8) Software & Data Integrity", 308),
|
||||
A9("(A9) Security Logging Failures", 309),
|
||||
A10("(A10) Server-side Request Forgery", 310),
|
||||
|
||||
CHALLENGE("Challenges", 3000);
|
||||
CLIENT_SIDE("Client side", 1700),
|
||||
|
||||
@Getter
|
||||
private String name;
|
||||
@Getter
|
||||
private Integer ranking;
|
||||
CHALLENGE("Challenges", 3000);
|
||||
|
||||
Category(String name, Integer ranking) {
|
||||
this.name = name;
|
||||
this.ranking = ranking;
|
||||
}
|
||||
@Getter private String name;
|
||||
@Getter private Integer ranking;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
Category(String name, Integer ranking) {
|
||||
this.name = name;
|
||||
this.ranking = ranking;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||
@ -36,91 +41,103 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class CourseConfiguration {
|
||||
|
||||
private final List<Lesson> lessons;
|
||||
private final List<AssignmentEndpoint> assignments;
|
||||
private final Map<String, List<AssignmentEndpoint>> assignmentsByPackage;
|
||||
private final List<Lesson> lessons;
|
||||
private final List<AssignmentEndpoint> assignments;
|
||||
private final Map<String, List<AssignmentEndpoint>> assignmentsByPackage;
|
||||
|
||||
public CourseConfiguration(List<Lesson> lessons, List<AssignmentEndpoint> assignments) {
|
||||
this.lessons = lessons;
|
||||
this.assignments = assignments;
|
||||
assignmentsByPackage = this.assignments.stream().collect(groupingBy(a -> a.getClass().getPackageName()));
|
||||
}
|
||||
public CourseConfiguration(List<Lesson> lessons, List<AssignmentEndpoint> assignments) {
|
||||
this.lessons = lessons;
|
||||
this.assignments = assignments;
|
||||
assignmentsByPackage =
|
||||
this.assignments.stream().collect(groupingBy(a -> a.getClass().getPackageName()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Course course() {
|
||||
lessons.stream().forEach(l -> l.setAssignments(createAssignment(l)));
|
||||
return new Course(lessons);
|
||||
}
|
||||
@Bean
|
||||
public Course course() {
|
||||
lessons.stream().forEach(l -> l.setAssignments(createAssignment(l)));
|
||||
return new Course(lessons);
|
||||
}
|
||||
|
||||
private List<Assignment> createAssignment(Lesson lesson) {
|
||||
var endpoints = assignmentsByPackage.get(lesson.getClass().getPackageName());
|
||||
if (CollectionUtils.isEmpty(endpoints)) {
|
||||
log.warn("Lesson: {} has no endpoints, is this intentionally?", lesson.getTitle());
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return endpoints.stream()
|
||||
.map(e -> new Assignment(e.getClass().getSimpleName(), getPath(e.getClass()), getHints(e.getClass())))
|
||||
.toList();
|
||||
private List<Assignment> createAssignment(Lesson lesson) {
|
||||
var endpoints = assignmentsByPackage.get(lesson.getClass().getPackageName());
|
||||
if (CollectionUtils.isEmpty(endpoints)) {
|
||||
log.warn("Lesson: {} has no endpoints, is this intentionally?", lesson.getTitle());
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return endpoints.stream()
|
||||
.map(
|
||||
e ->
|
||||
new Assignment(
|
||||
e.getClass().getSimpleName(), getPath(e.getClass()), getHints(e.getClass())))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private String getPath(Class<? extends AssignmentEndpoint> e) {
|
||||
for (Method m : e.getMethods()) {
|
||||
if (methodReturnTypeIsOfTypeAttackResult(m)) {
|
||||
var mapping = getMapping(m);
|
||||
if (mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
}
|
||||
private String getPath(Class<? extends AssignmentEndpoint> e) {
|
||||
for (Method m : e.getMethods()) {
|
||||
if (methodReturnTypeIsOfTypeAttackResult(m)) {
|
||||
var mapping = getMapping(m);
|
||||
if (mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
throw new IllegalStateException("Assignment endpoint: " + e + " has no mapping like @GetMapping/@PostMapping etc," +
|
||||
"with return type 'AttackResult' or 'ResponseEntity<AttackResult>' please consider adding one");
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Assignment endpoint: "
|
||||
+ e
|
||||
+ " has no mapping like @GetMapping/@PostMapping etc,with return type 'AttackResult' or"
|
||||
+ " 'ResponseEntity<AttackResult>' please consider adding one");
|
||||
}
|
||||
|
||||
private boolean methodReturnTypeIsOfTypeAttackResult(Method m) {
|
||||
if (m.getReturnType() == AttackResult.class) {
|
||||
return true;
|
||||
}
|
||||
var genericType = m.getGenericReturnType();
|
||||
if (genericType instanceof ParameterizedType) {
|
||||
return ((ParameterizedType) m.getGenericReturnType()).getActualTypeArguments()[0] == AttackResult.class;
|
||||
}
|
||||
return false;
|
||||
private boolean methodReturnTypeIsOfTypeAttackResult(Method m) {
|
||||
if (m.getReturnType() == AttackResult.class) {
|
||||
return true;
|
||||
}
|
||||
var genericType = m.getGenericReturnType();
|
||||
if (genericType instanceof ParameterizedType) {
|
||||
return ((ParameterizedType) m.getGenericReturnType()).getActualTypeArguments()[0]
|
||||
== AttackResult.class;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getMapping(Method m) {
|
||||
String[] paths = null;
|
||||
//Find the path, either it is @GetMapping("/attack") of GetMapping(path = "/attack") both are valid, we need to consider both
|
||||
if (m.getAnnotation(RequestMapping.class) != null) {
|
||||
paths = ArrayUtils.addAll(m.getAnnotation(RequestMapping.class).value(), m.getAnnotation(RequestMapping.class).path());
|
||||
} else if (m.getAnnotation(PostMapping.class) != null) {
|
||||
paths = ArrayUtils.addAll(m.getAnnotation(PostMapping.class).value(), m.getAnnotation(PostMapping.class).path());
|
||||
} else if (m.getAnnotation(GetMapping.class) != null) {
|
||||
paths = ArrayUtils.addAll(m.getAnnotation(GetMapping.class).value(), m.getAnnotation(GetMapping.class).path());
|
||||
} else if (m.getAnnotation(PutMapping.class) != null) {
|
||||
paths = ArrayUtils.addAll(m.getAnnotation(PutMapping.class).value(), m.getAnnotation(PutMapping.class).path());
|
||||
}
|
||||
if (paths == null) {
|
||||
return null;
|
||||
} else {
|
||||
return Arrays.stream(paths).filter(path -> !"".equals(path)).findFirst().orElse("");
|
||||
}
|
||||
private String getMapping(Method m) {
|
||||
String[] paths = null;
|
||||
// Find the path, either it is @GetMapping("/attack") of GetMapping(path = "/attack") both are
|
||||
// valid, we need to consider both
|
||||
if (m.getAnnotation(RequestMapping.class) != null) {
|
||||
paths =
|
||||
ArrayUtils.addAll(
|
||||
m.getAnnotation(RequestMapping.class).value(),
|
||||
m.getAnnotation(RequestMapping.class).path());
|
||||
} else if (m.getAnnotation(PostMapping.class) != null) {
|
||||
paths =
|
||||
ArrayUtils.addAll(
|
||||
m.getAnnotation(PostMapping.class).value(),
|
||||
m.getAnnotation(PostMapping.class).path());
|
||||
} else if (m.getAnnotation(GetMapping.class) != null) {
|
||||
paths =
|
||||
ArrayUtils.addAll(
|
||||
m.getAnnotation(GetMapping.class).value(), m.getAnnotation(GetMapping.class).path());
|
||||
} else if (m.getAnnotation(PutMapping.class) != null) {
|
||||
paths =
|
||||
ArrayUtils.addAll(
|
||||
m.getAnnotation(PutMapping.class).value(), m.getAnnotation(PutMapping.class).path());
|
||||
}
|
||||
if (paths == null) {
|
||||
return null;
|
||||
} else {
|
||||
return Arrays.stream(paths).filter(path -> !"".equals(path)).findFirst().orElse("");
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getHints(Class<? extends AssignmentEndpoint> e) {
|
||||
if (e.isAnnotationPresent(AssignmentHints.class)) {
|
||||
return List.of(e.getAnnotationsByType(AssignmentHints.class)[0].value());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
private List<String> getHints(Class<? extends AssignmentEndpoint> e) {
|
||||
if (e.isAnnotationPresent(AssignmentHints.class)) {
|
||||
return List.of(e.getAnnotationsByType(AssignmentHints.class)[0].value());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
@ -30,7 +30,7 @@ package org.owasp.webgoat.container.lessons;
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* <p>Hint class.</p>
|
||||
* Hint class.
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
@ -38,6 +38,6 @@ import lombok.Value;
|
||||
@Value
|
||||
public class Hint {
|
||||
|
||||
private String hint;
|
||||
private String assignmentPath;
|
||||
private String hint;
|
||||
private String assignmentPath;
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package org.owasp.webgoat.container.lessons;
|
||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||
|
||||
/**
|
||||
* Interface for initialization of a lesson. It is called when a new user is added to WebGoat and when a users
|
||||
* reset a lesson. Make sure to clean beforehand and then re-initialize the lesson.
|
||||
* Interface for initialization of a lesson. It is called when a new user is added to WebGoat and
|
||||
* when a users reset a lesson. Make sure to clean beforehand and then re-initialize the lesson.
|
||||
*/
|
||||
public interface Initializeable {
|
||||
|
||||
void initialize(WebGoatUser webGoatUser);
|
||||
void initialize(WebGoatUser webGoatUser);
|
||||
}
|
||||
|
@ -22,115 +22,103 @@
|
||||
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class Lesson {
|
||||
|
||||
private static int count = 1;
|
||||
private Integer id = null;
|
||||
private List<Assignment> assignments;
|
||||
private static int count = 1;
|
||||
private Integer id = null;
|
||||
private List<Assignment> assignments;
|
||||
|
||||
/**
|
||||
* Constructor for the Lesson object
|
||||
*/
|
||||
protected Lesson() {
|
||||
id = ++count;
|
||||
}
|
||||
/** Constructor for the Lesson object */
|
||||
protected Lesson() {
|
||||
id = ++count;
|
||||
}
|
||||
|
||||
/**
|
||||
* getName.
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public String getName() {
|
||||
String className = getClass().getName();
|
||||
return className.substring(className.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>getName.</p>
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public String getName() {
|
||||
String className = getClass().getName();
|
||||
return className.substring(className.lastIndexOf('.') + 1);
|
||||
}
|
||||
/**
|
||||
* Gets the category attribute of the Lesson object
|
||||
*
|
||||
* @return The category value
|
||||
*/
|
||||
public Category getCategory() {
|
||||
return getDefaultCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category attribute of the Lesson object
|
||||
*
|
||||
* @return The category value
|
||||
*/
|
||||
public Category getCategory() {
|
||||
return getDefaultCategory();
|
||||
}
|
||||
/**
|
||||
* getDefaultCategory.
|
||||
*
|
||||
* @return a {@link org.owasp.webgoat.container.lessons.Category} object.
|
||||
*/
|
||||
protected abstract Category getDefaultCategory();
|
||||
|
||||
/**
|
||||
* <p>getDefaultCategory.</p>
|
||||
*
|
||||
* @return a {@link org.owasp.webgoat.container.lessons.Category} object.
|
||||
*/
|
||||
protected abstract Category getDefaultCategory();
|
||||
/**
|
||||
* Gets the title attribute of the HelloScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public abstract String getTitle();
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the HelloScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public abstract String getTitle();
|
||||
/**
|
||||
* Returns the default "path" portion of a lesson's URL.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* <p>Legacy webgoat lesson links are of the form "attack?Screen=Xmenu=Ystage=Z". This method
|
||||
* returns the path portion of the url, i.e., "attack" in the string above.
|
||||
*
|
||||
* <p>Newer, Spring-Controller-based classes will override this method to return "*.do"-styled
|
||||
* paths.
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
protected String getPath() {
|
||||
return "#lesson/";
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the default "path" portion of a lesson's URL.</p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Legacy webgoat lesson links are of the form
|
||||
* "attack?Screen=Xmenu=Ystage=Z". This method returns the path portion of
|
||||
* the url, i.e., "attack" in the string above.
|
||||
* <p>
|
||||
* Newer, Spring-Controller-based classes will override this method to
|
||||
* return "*.do"-styled paths.
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
protected String getPath() {
|
||||
return "#lesson/";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link that can be used to request this screen.
|
||||
* <p>
|
||||
* Rendering the link in the browser may result in Javascript sending
|
||||
* additional requests to perform necessary actions or to obtain data
|
||||
* relevant to the lesson or the element of the lesson selected by the
|
||||
* user. Thanks to using the hash mark "#" and Javascript handling the
|
||||
* clicks, the user will experience less waiting as the pages do not have
|
||||
* to reload entirely.
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public String getLink() {
|
||||
return String.format("%s%s.lesson", getPath(), getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
public String toString() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
public final String getId() {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public final String getPackage() {
|
||||
var packageName = this.getClass().getPackageName();
|
||||
//package name is the direct package name below lessons (any subpackage will be removed)
|
||||
return packageName.replaceAll("org.owasp.webgoat.lessons.", "").replaceAll("\\..*", "");
|
||||
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the link that can be used to request this screen.
|
||||
*
|
||||
* <p>Rendering the link in the browser may result in Javascript sending additional requests to
|
||||
* perform necessary actions or to obtain data relevant to the lesson or the element of the lesson
|
||||
* selected by the user. Thanks to using the hash mark "#" and Javascript handling the clicks, the
|
||||
* user will experience less waiting as the pages do not have to reload entirely.
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public String getLink() {
|
||||
return String.format("%s%s.lesson", getPath(), getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
public String toString() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
public final String getId() {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public final String getPackage() {
|
||||
var packageName = this.getClass().getPackageName();
|
||||
// package name is the direct package name below lessons (any subpackage will be removed)
|
||||
return packageName.replaceAll("org.owasp.webgoat.lessons.", "").replaceAll("\\..*", "");
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,38 @@
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Handler which sets the correct schema for the currently bounded user. This way users are not seeing each other
|
||||
* data and we can reset data for just one particular user.
|
||||
* Handler which sets the correct schema for the currently bounded user. This way users are not
|
||||
* seeing each other data and we can reset data for just one particular user.
|
||||
*/
|
||||
@Slf4j
|
||||
public class LessonConnectionInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final Connection targetConnection;
|
||||
private final Connection targetConnection;
|
||||
|
||||
public LessonConnectionInvocationHandler(Connection targetConnection) {
|
||||
this.targetConnection = targetConnection;
|
||||
}
|
||||
public LessonConnectionInvocationHandler(Connection targetConnection) {
|
||||
this.targetConnection = targetConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
var authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication != null && authentication.getPrincipal() instanceof WebGoatUser user) {
|
||||
try (var statement = targetConnection.createStatement()) {
|
||||
statement.execute("SET SCHEMA \"" + user.getUsername() + "\"");
|
||||
}
|
||||
}
|
||||
try {
|
||||
return method.invoke(targetConnection, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getTargetException();
|
||||
}
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
var authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication != null && authentication.getPrincipal() instanceof WebGoatUser user) {
|
||||
try (var statement = targetConnection.createStatement()) {
|
||||
statement.execute("SET SCHEMA \"" + user.getUsername() + "\"");
|
||||
}
|
||||
}
|
||||
try {
|
||||
return method.invoke(targetConnection, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getTargetException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* <p>LessonInfoModel class.</p>
|
||||
* LessonInfoModel class.
|
||||
*
|
||||
* @author dm
|
||||
* @version $Id: $Id
|
||||
@ -13,9 +13,8 @@ import lombok.Getter;
|
||||
@AllArgsConstructor
|
||||
public class LessonInfoModel {
|
||||
|
||||
private String lessonTitle;
|
||||
private boolean hasSource;
|
||||
private boolean hasSolution;
|
||||
private boolean hasPlan;
|
||||
|
||||
private String lessonTitle;
|
||||
private boolean hasSource;
|
||||
private boolean hasSolution;
|
||||
private boolean hasPlan;
|
||||
}
|
||||
|
@ -1,166 +1,162 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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>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 - 2014 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.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>LessonMenuItem class.</p>
|
||||
* LessonMenuItem class.
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
public class LessonMenuItem {
|
||||
|
||||
private String name;
|
||||
private LessonMenuItemType type;
|
||||
private List<LessonMenuItem> children = new ArrayList<>();
|
||||
private boolean complete;
|
||||
private String link;
|
||||
private int ranking;
|
||||
private String name;
|
||||
private LessonMenuItemType type;
|
||||
private List<LessonMenuItem> children = new ArrayList<>();
|
||||
private boolean complete;
|
||||
private String link;
|
||||
private int ranking;
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>name</code>.</p>
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* Getter for the field <code>name</code>.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Setter for the field <code>name</code>.</p>
|
||||
*
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Setter for the field <code>name</code>.
|
||||
*
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>children</code>.</p>
|
||||
*
|
||||
* @return the children
|
||||
*/
|
||||
public List<LessonMenuItem> getChildren() {
|
||||
return children;
|
||||
}
|
||||
/**
|
||||
* Getter for the field <code>children</code>.
|
||||
*
|
||||
* @return the children
|
||||
*/
|
||||
public List<LessonMenuItem> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Setter for the field <code>children</code>.</p>
|
||||
*
|
||||
* @param children the children to set
|
||||
*/
|
||||
public void setChildren(List<LessonMenuItem> children) {
|
||||
this.children = children;
|
||||
}
|
||||
/**
|
||||
* Setter for the field <code>children</code>.
|
||||
*
|
||||
* @param children the children to set
|
||||
*/
|
||||
public void setChildren(List<LessonMenuItem> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>type</code>.</p>
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public LessonMenuItemType getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* Getter for the field <code>type</code>.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public LessonMenuItemType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Setter for the field <code>type</code>.</p>
|
||||
*
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(LessonMenuItemType type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* Setter for the field <code>type</code>.
|
||||
*
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(LessonMenuItemType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>addChild.</p>
|
||||
*
|
||||
* @param child a {@link LessonMenuItem} object.
|
||||
*/
|
||||
public void addChild(LessonMenuItem child) {
|
||||
children.add(child);
|
||||
}
|
||||
/**
|
||||
* addChild.
|
||||
*
|
||||
* @param child a {@link LessonMenuItem} object.
|
||||
*/
|
||||
public void addChild(LessonMenuItem child) {
|
||||
children.add(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("Name: ").append(name).append(" | ");
|
||||
bldr.append("Type: ").append(type).append(" | ");
|
||||
return bldr.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("Name: ").append(name).append(" | ");
|
||||
bldr.append("Type: ").append(type).append(" | ");
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>isComplete.</p>
|
||||
*
|
||||
* @return the complete
|
||||
*/
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
/**
|
||||
* isComplete.
|
||||
*
|
||||
* @return the complete
|
||||
*/
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Setter for the field <code>complete</code>.</p>
|
||||
*
|
||||
* @param complete the complete to set
|
||||
*/
|
||||
public void setComplete(boolean complete) {
|
||||
this.complete = complete;
|
||||
}
|
||||
/**
|
||||
* Setter for the field <code>complete</code>.
|
||||
*
|
||||
* @param complete the complete to set
|
||||
*/
|
||||
public void setComplete(boolean complete) {
|
||||
this.complete = complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>link</code>.</p>
|
||||
*
|
||||
* @return the link
|
||||
*/
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
/**
|
||||
* Getter for the field <code>link</code>.
|
||||
*
|
||||
* @return the link
|
||||
*/
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Setter for the field <code>link</code>.</p>
|
||||
*
|
||||
* @param link the link to set
|
||||
*/
|
||||
public void setLink(String link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public void setRanking(int ranking) {
|
||||
this.ranking = ranking;
|
||||
}
|
||||
|
||||
public int getRanking() {
|
||||
return this.ranking;
|
||||
}
|
||||
/**
|
||||
* Setter for the field <code>link</code>.
|
||||
*
|
||||
* @param link the link to set
|
||||
*/
|
||||
public void setLink(String link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public void setRanking(int ranking) {
|
||||
this.ranking = ranking;
|
||||
}
|
||||
|
||||
public int getRanking() {
|
||||
return this.ranking;
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,40 @@
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
/**
|
||||
* <p>LessonMenuItemType class.</p>
|
||||
* LessonMenuItemType class.
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
public enum LessonMenuItemType {
|
||||
CATEGORY,
|
||||
LESSON,
|
||||
STAGE
|
||||
CATEGORY,
|
||||
LESSON,
|
||||
STAGE
|
||||
}
|
||||
|
@ -1,46 +1,42 @@
|
||||
package org.owasp.webgoat.container.lessons;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LessonScanner {
|
||||
|
||||
private static final Pattern lessonPattern = Pattern.compile("^.*/lessons/([^/]*)/.*$");
|
||||
private static final Pattern lessonPattern = Pattern.compile("^.*/lessons/([^/]*)/.*$");
|
||||
|
||||
@Getter
|
||||
private final Set<String> lessons = new HashSet<>();
|
||||
@Getter private final Set<String> lessons = new HashSet<>();
|
||||
|
||||
public LessonScanner(ResourcePatternResolver resourcePatternResolver) {
|
||||
try {
|
||||
var resources = resourcePatternResolver.getResources("classpath:/lessons/*/*");
|
||||
for (var resource : resources) {
|
||||
//WG can run as a fat jar or as directly from file system we need to support both so use the URL
|
||||
var url = resource.getURL();
|
||||
var matcher = lessonPattern.matcher(url.toString());
|
||||
if (matcher.matches()) {
|
||||
lessons.add(matcher.group(1));
|
||||
}
|
||||
}
|
||||
log.debug("Found {} lessons", lessons.size());
|
||||
} catch (IOException e) {
|
||||
log.warn("No lessons found...");
|
||||
public LessonScanner(ResourcePatternResolver resourcePatternResolver) {
|
||||
try {
|
||||
var resources = resourcePatternResolver.getResources("classpath:/lessons/*/*");
|
||||
for (var resource : resources) {
|
||||
// WG can run as a fat jar or as directly from file system we need to support both so use
|
||||
// the URL
|
||||
var url = resource.getURL();
|
||||
var matcher = lessonPattern.matcher(url.toString());
|
||||
if (matcher.matches()) {
|
||||
lessons.add(matcher.group(1));
|
||||
}
|
||||
|
||||
}
|
||||
log.debug("Found {} lessons", lessons.size());
|
||||
} catch (IOException e) {
|
||||
log.warn("No lessons found...");
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> applyPattern(String pattern) {
|
||||
return lessons.stream().map(lesson -> String.format(pattern, lesson)).toList();
|
||||
}
|
||||
public List<String> applyPattern(String pattern) {
|
||||
return lessons.stream().map(lesson -> String.format(pattern, lesson)).toList();
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,10 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequiredArgsConstructor
|
||||
public class EnvironmentService {
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
@GetMapping("/server-directory")
|
||||
public String homeDirectory() {
|
||||
return context.getEnvironment().getProperty("webgoat.server.directory");
|
||||
}
|
||||
private final ApplicationContext context;
|
||||
|
||||
@GetMapping("/server-directory")
|
||||
public String homeDirectory() {
|
||||
return context.getEnvironment().getProperty("webgoat.server.directory");
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Hint;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
@ -14,11 +16,8 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>HintService class.</p>
|
||||
* HintService class.
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
@ -26,36 +25,33 @@ import java.util.List;
|
||||
@RestController
|
||||
public class HintService {
|
||||
|
||||
public static final String URL_HINTS_MVC = "/service/hint.mvc";
|
||||
private final WebSession webSession;
|
||||
public static final String URL_HINTS_MVC = "/service/hint.mvc";
|
||||
private final WebSession webSession;
|
||||
|
||||
public HintService(WebSession webSession) {
|
||||
this.webSession = webSession;
|
||||
}
|
||||
public HintService(WebSession webSession) {
|
||||
this.webSession = webSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns hints for current lesson
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
@GetMapping(path = URL_HINTS_MVC, produces = "application/json")
|
||||
@ResponseBody
|
||||
public List<Hint> getHints() {
|
||||
Lesson l = webSession.getCurrentLesson();
|
||||
return createAssignmentHints(l);
|
||||
}
|
||||
/**
|
||||
* Returns hints for current lesson
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
@GetMapping(path = URL_HINTS_MVC, produces = "application/json")
|
||||
@ResponseBody
|
||||
public List<Hint> getHints() {
|
||||
Lesson l = webSession.getCurrentLesson();
|
||||
return createAssignmentHints(l);
|
||||
}
|
||||
|
||||
private List<Hint> createAssignmentHints(Lesson l) {
|
||||
if (l != null) {
|
||||
return l.getAssignments().stream()
|
||||
.map(this::createHint)
|
||||
.flatMap(Collection::stream)
|
||||
.toList();
|
||||
}
|
||||
return List.of();
|
||||
private List<Hint> createAssignmentHints(Lesson l) {
|
||||
if (l != null) {
|
||||
return l.getAssignments().stream().map(this::createHint).flatMap(Collection::stream).toList();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private List<Hint> createHint(Assignment a) {
|
||||
return a.getHints().stream().map(h -> new Hint(h, a.getPath())).toList();
|
||||
}
|
||||
private List<Hint> createHint(Assignment a) {
|
||||
return a.getHints().stream().map(h -> new Hint(h, a.getPath())).toList();
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,33 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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>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 - 2014 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.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.session.LabelDebugger;
|
||||
@ -40,10 +39,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>LabelDebugService class.</p>
|
||||
* LabelDebugService class.
|
||||
*
|
||||
* @author nbaars
|
||||
* @version $Id: $Id
|
||||
@ -53,45 +50,47 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
public class LabelDebugService {
|
||||
|
||||
private static final String URL_DEBUG_LABELS_MVC = "/service/debug/labels.mvc";
|
||||
private static final String KEY_ENABLED = "enabled";
|
||||
private static final String KEY_SUCCESS = "success";
|
||||
private static final String URL_DEBUG_LABELS_MVC = "/service/debug/labels.mvc";
|
||||
private static final String KEY_ENABLED = "enabled";
|
||||
private static final String KEY_SUCCESS = "success";
|
||||
|
||||
private LabelDebugger labelDebugger;
|
||||
private LabelDebugger labelDebugger;
|
||||
|
||||
/**
|
||||
* Checks if debugging of labels is enabled or disabled
|
||||
*
|
||||
* @return a {@link org.springframework.http.ResponseEntity} object.
|
||||
*/
|
||||
@RequestMapping(path = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public @ResponseBody
|
||||
ResponseEntity<Map<String, Object>> checkDebuggingStatus() {
|
||||
log.debug("Checking label debugging, it is {}", labelDebugger.isEnabled());
|
||||
Map<String, Object> result = createResponse(labelDebugger.isEnabled());
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
/**
|
||||
* Checks if debugging of labels is enabled or disabled
|
||||
*
|
||||
* @return a {@link org.springframework.http.ResponseEntity} object.
|
||||
*/
|
||||
@RequestMapping(path = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public @ResponseBody ResponseEntity<Map<String, Object>> checkDebuggingStatus() {
|
||||
log.debug("Checking label debugging, it is {}", labelDebugger.isEnabled());
|
||||
Map<String, Object> result = createResponse(labelDebugger.isEnabled());
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled flag on the label debugger to the given parameter
|
||||
*
|
||||
* @param enabled {@link org.owasp.webgoat.container.session.LabelDebugger} object
|
||||
* @return a {@link org.springframework.http.ResponseEntity} object.
|
||||
*/
|
||||
@RequestMapping(value = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE, params = KEY_ENABLED)
|
||||
public @ResponseBody
|
||||
ResponseEntity<Map<String, Object>> setDebuggingStatus(@RequestParam("enabled") Boolean enabled) {
|
||||
log.debug("Setting label debugging to {} ", labelDebugger.isEnabled());
|
||||
Map<String, Object> result = createResponse(enabled);
|
||||
labelDebugger.setEnabled(enabled);
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
/**
|
||||
* Sets the enabled flag on the label debugger to the given parameter
|
||||
*
|
||||
* @param enabled {@link org.owasp.webgoat.container.session.LabelDebugger} object
|
||||
* @return a {@link org.springframework.http.ResponseEntity} object.
|
||||
*/
|
||||
@RequestMapping(
|
||||
value = URL_DEBUG_LABELS_MVC,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE,
|
||||
params = KEY_ENABLED)
|
||||
public @ResponseBody ResponseEntity<Map<String, Object>> setDebuggingStatus(
|
||||
@RequestParam("enabled") Boolean enabled) {
|
||||
log.debug("Setting label debugging to {} ", labelDebugger.isEnabled());
|
||||
Map<String, Object> result = createResponse(enabled);
|
||||
labelDebugger.setEnabled(enabled);
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enabled {@link org.owasp.webgoat.container.session.LabelDebugger} object
|
||||
* @return a {@link java.util.Map} object.
|
||||
*/
|
||||
private Map<String, Object> createResponse(Boolean enabled) {
|
||||
return Map.of(KEY_SUCCESS, Boolean.TRUE, KEY_ENABLED, enabled);
|
||||
}
|
||||
/**
|
||||
* @param enabled {@link org.owasp.webgoat.container.session.LabelDebugger} object
|
||||
* @return a {@link java.util.Map} object.
|
||||
*/
|
||||
private Map<String, Object> createResponse(Boolean enabled) {
|
||||
return Map.of(KEY_SUCCESS, Boolean.TRUE, KEY_ENABLED, enabled);
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,33 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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
|
||||
*
|
||||
* <p>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 - 2014 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.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.Properties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.i18n.Messages;
|
||||
@ -40,11 +39,8 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
/**
|
||||
* <p>LabelService class.</p>
|
||||
* LabelService class.
|
||||
*
|
||||
* @author zupzup
|
||||
*/
|
||||
@ -53,19 +49,19 @@ import java.util.Properties;
|
||||
@RequiredArgsConstructor
|
||||
public class LabelService {
|
||||
|
||||
public static final String URL_LABELS_MVC = "/service/labels.mvc";
|
||||
private final Messages messages;
|
||||
private final PluginMessages pluginMessages;
|
||||
public static final String URL_LABELS_MVC = "/service/labels.mvc";
|
||||
private final Messages messages;
|
||||
private final PluginMessages pluginMessages;
|
||||
|
||||
/**
|
||||
* @return a map of all the labels
|
||||
*/
|
||||
@GetMapping(path = URL_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Properties> fetchLabels() {
|
||||
var allProperties = new Properties();
|
||||
allProperties.putAll(messages.getMessages());
|
||||
allProperties.putAll(pluginMessages.getMessages());
|
||||
return new ResponseEntity<>(allProperties, HttpStatus.OK);
|
||||
}
|
||||
/**
|
||||
* @return a map of all the labels
|
||||
*/
|
||||
@GetMapping(path = URL_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Properties> fetchLabels() {
|
||||
var allProperties = new Properties();
|
||||
allProperties.putAll(messages.getMessages());
|
||||
allProperties.putAll(pluginMessages.getMessages());
|
||||
return new ResponseEntity<>(allProperties, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
/**
|
||||
* <p>LessonInfoService class.</p>
|
||||
* LessonInfoService class.
|
||||
*
|
||||
* @author dm
|
||||
* @version $Id: $Id
|
||||
@ -19,18 +18,16 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@AllArgsConstructor
|
||||
public class LessonInfoService {
|
||||
|
||||
private final WebSession webSession;
|
||||
|
||||
/**
|
||||
* <p>getLessonInfo.</p>
|
||||
*
|
||||
* @return a {@link LessonInfoModel} object.
|
||||
*/
|
||||
@RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json")
|
||||
public @ResponseBody
|
||||
LessonInfoModel getLessonInfo() {
|
||||
Lesson lesson = webSession.getCurrentLesson();
|
||||
return new LessonInfoModel(lesson.getTitle(), false, false, false);
|
||||
}
|
||||
private final WebSession webSession;
|
||||
|
||||
/**
|
||||
* getLessonInfo.
|
||||
*
|
||||
* @return a {@link LessonInfoModel} object.
|
||||
*/
|
||||
@RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json")
|
||||
public @ResponseBody LessonInfoModel getLessonInfo() {
|
||||
Lesson lesson = webSession.getCurrentLesson();
|
||||
return new LessonInfoModel(lesson.getTitle(), false, false, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,36 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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>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 - 2014 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.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Category;
|
||||
@ -45,13 +47,8 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>LessonMenuService class.</p>
|
||||
* LessonMenuService class.
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
@ -60,72 +57,68 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
public class LessonMenuService {
|
||||
|
||||
public static final String URL_LESSONMENU_MVC = "/service/lessonmenu.mvc";
|
||||
private final Course course;
|
||||
private final WebSession webSession;
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
public static final String URL_LESSONMENU_MVC = "/service/lessonmenu.mvc";
|
||||
private final Course course;
|
||||
private final WebSession webSession;
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
|
||||
@Value("#{'${exclude.categories}'.split(',')}")
|
||||
private List<String> excludeCategories;
|
||||
@Value("#{'${exclude.categories}'.split(',')}")
|
||||
private List<String> excludeCategories;
|
||||
|
||||
@Value("#{'${exclude.lessons}'.split(',')}")
|
||||
private List<String> excludeLessons;
|
||||
@Value("#{'${exclude.lessons}'.split(',')}")
|
||||
private List<String> excludeLessons;
|
||||
|
||||
/**
|
||||
* Returns the lesson menu which is used to build the left nav
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
@RequestMapping(path = URL_LESSONMENU_MVC, produces = "application/json")
|
||||
public
|
||||
@ResponseBody
|
||||
List<LessonMenuItem> showLeftNav() {
|
||||
List<LessonMenuItem> menu = new ArrayList<>();
|
||||
List<Category> categories = course.getCategories();
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
/**
|
||||
* Returns the lesson menu which is used to build the left nav
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
@RequestMapping(path = URL_LESSONMENU_MVC, produces = "application/json")
|
||||
public @ResponseBody List<LessonMenuItem> showLeftNav() {
|
||||
List<LessonMenuItem> menu = new ArrayList<>();
|
||||
List<Category> categories = course.getCategories();
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
|
||||
for (Category category : categories) {
|
||||
if (excludeCategories.contains(category.name())) {
|
||||
continue;
|
||||
}
|
||||
LessonMenuItem categoryItem = new LessonMenuItem();
|
||||
categoryItem.setName(category.getName());
|
||||
categoryItem.setType(LessonMenuItemType.CATEGORY);
|
||||
// check for any lessons for this category
|
||||
List<Lesson> lessons = course.getLessons(category);
|
||||
lessons = lessons.stream().sorted(Comparator.comparing(Lesson::getTitle)).toList();
|
||||
for (Lesson lesson : lessons) {
|
||||
if (excludeLessons.contains(lesson.getName())) {
|
||||
continue;
|
||||
}
|
||||
LessonMenuItem lessonItem = new LessonMenuItem();
|
||||
lessonItem.setName(lesson.getTitle());
|
||||
lessonItem.setLink(lesson.getLink());
|
||||
lessonItem.setType(LessonMenuItemType.LESSON);
|
||||
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
||||
boolean lessonSolved = lessonCompleted(lessonTracker.getLessonOverview(), lesson);
|
||||
lessonItem.setComplete(lessonSolved);
|
||||
categoryItem.addChild(lessonItem);
|
||||
}
|
||||
categoryItem.getChildren().sort((o1, o2) -> o1.getRanking() - o2.getRanking());
|
||||
menu.add(categoryItem);
|
||||
for (Category category : categories) {
|
||||
if (excludeCategories.contains(category.name())) {
|
||||
continue;
|
||||
}
|
||||
LessonMenuItem categoryItem = new LessonMenuItem();
|
||||
categoryItem.setName(category.getName());
|
||||
categoryItem.setType(LessonMenuItemType.CATEGORY);
|
||||
// check for any lessons for this category
|
||||
List<Lesson> lessons = course.getLessons(category);
|
||||
lessons = lessons.stream().sorted(Comparator.comparing(Lesson::getTitle)).toList();
|
||||
for (Lesson lesson : lessons) {
|
||||
if (excludeLessons.contains(lesson.getName())) {
|
||||
continue;
|
||||
}
|
||||
return menu;
|
||||
|
||||
LessonMenuItem lessonItem = new LessonMenuItem();
|
||||
lessonItem.setName(lesson.getTitle());
|
||||
lessonItem.setLink(lesson.getLink());
|
||||
lessonItem.setType(LessonMenuItemType.LESSON);
|
||||
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
||||
boolean lessonSolved = lessonCompleted(lessonTracker.getLessonOverview(), lesson);
|
||||
lessonItem.setComplete(lessonSolved);
|
||||
categoryItem.addChild(lessonItem);
|
||||
}
|
||||
categoryItem.getChildren().sort((o1, o2) -> o1.getRanking() - o2.getRanking());
|
||||
menu.add(categoryItem);
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
private boolean lessonCompleted(Map<Assignment, Boolean> map, Lesson currentLesson) {
|
||||
boolean result = true;
|
||||
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
|
||||
Assignment storedAssignment = entry.getKey();
|
||||
for (Assignment lessonAssignment : currentLesson.getAssignments()) {
|
||||
if (lessonAssignment.getName().equals(storedAssignment.getName())) {
|
||||
result = result && entry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean lessonCompleted(Map<Assignment, Boolean> map, Lesson currentLesson) {
|
||||
boolean result = true;
|
||||
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
|
||||
Assignment storedAssignment = entry.getKey();
|
||||
for (Assignment lessonAssignment : currentLesson.getAssignments()) {
|
||||
if (lessonAssignment.getName().equals(storedAssignment.getName())) {
|
||||
result = result && entry.getValue();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -10,11 +11,8 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>LessonProgressService class.</p>
|
||||
* LessonProgressService class.
|
||||
*
|
||||
* @author webgoat
|
||||
*/
|
||||
@ -22,38 +20,38 @@ import java.util.List;
|
||||
@RequiredArgsConstructor
|
||||
public class LessonProgressService {
|
||||
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final WebSession webSession;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final WebSession webSession;
|
||||
|
||||
/**
|
||||
* Endpoint for fetching the complete lesson overview which informs the user about whether all the assignments are solved.
|
||||
* Used as the last page of the lesson to generate a lesson overview.
|
||||
*
|
||||
* @return list of assignments
|
||||
*/
|
||||
@RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public List<LessonOverview> lessonOverview() {
|
||||
var userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
var currentLesson = webSession.getCurrentLesson();
|
||||
/**
|
||||
* Endpoint for fetching the complete lesson overview which informs the user about whether all the
|
||||
* assignments are solved. Used as the last page of the lesson to generate a lesson overview.
|
||||
*
|
||||
* @return list of assignments
|
||||
*/
|
||||
@RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public List<LessonOverview> lessonOverview() {
|
||||
var userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
var currentLesson = webSession.getCurrentLesson();
|
||||
|
||||
if (currentLesson != null) {
|
||||
var lessonTracker = userTracker.getLessonTracker(currentLesson);
|
||||
return lessonTracker.getLessonOverview().entrySet().stream()
|
||||
.map(entry -> new LessonOverview(entry.getKey(), entry.getValue()))
|
||||
.toList();
|
||||
}
|
||||
return List.of();
|
||||
if (currentLesson != null) {
|
||||
var lessonTracker = userTracker.getLessonTracker(currentLesson);
|
||||
return lessonTracker.getLessonOverview().entrySet().stream()
|
||||
.map(entry -> new LessonOverview(entry.getKey(), entry.getValue()))
|
||||
.toList();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
//Jackson does not really like returning a map of <Assignment, Boolean> directly, see http://stackoverflow.com/questions/11628698/can-we-make-object-as-key-in-map-when-using-json
|
||||
//so creating intermediate object is the easiest solution
|
||||
private static class LessonOverview {
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
// Jackson does not really like returning a map of <Assignment, Boolean> directly, see
|
||||
// http://stackoverflow.com/questions/11628698/can-we-make-object-as-key-in-map-when-using-json
|
||||
// so creating intermediate object is the easiest solution
|
||||
private static class LessonOverview {
|
||||
|
||||
private Assignment assignment;
|
||||
private Boolean solved;
|
||||
|
||||
}
|
||||
private Assignment assignment;
|
||||
private Boolean solved;
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,8 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
|
||||
/**
|
||||
* <p>LessonTitleService class.</p>
|
||||
* LessonTitleService class.
|
||||
*
|
||||
* @author dm
|
||||
* @version $Id: $Id
|
||||
@ -16,23 +15,20 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@Controller
|
||||
public class LessonTitleService {
|
||||
|
||||
private final WebSession webSession;
|
||||
private final WebSession webSession;
|
||||
|
||||
public LessonTitleService(final WebSession webSession) {
|
||||
this.webSession = webSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title for the current attack
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
@RequestMapping(path = "/service/lessontitle.mvc", produces = "application/html")
|
||||
public
|
||||
@ResponseBody
|
||||
String showPlan() {
|
||||
Lesson lesson = webSession.getCurrentLesson();
|
||||
return lesson != null ? lesson.getTitle() : "";
|
||||
}
|
||||
public LessonTitleService(final WebSession webSession) {
|
||||
this.webSession = webSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title for the current attack
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
@RequestMapping(path = "/service/lessontitle.mvc", produces = "application/html")
|
||||
public @ResponseBody String showPlan() {
|
||||
Lesson lesson = webSession.getCurrentLesson();
|
||||
return lesson != null ? lesson.getTitle() : "";
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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>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 - 2014 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.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@ -43,11 +43,8 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>ReportCardService</p>
|
||||
* ReportCardService
|
||||
*
|
||||
* @author nbaars
|
||||
* @version $Id: $Id
|
||||
@ -56,52 +53,53 @@ import java.util.List;
|
||||
@AllArgsConstructor
|
||||
public class ReportCardService {
|
||||
|
||||
private final WebSession webSession;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final Course course;
|
||||
private final PluginMessages pluginMessages;
|
||||
private final WebSession webSession;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final Course course;
|
||||
private final PluginMessages pluginMessages;
|
||||
|
||||
/**
|
||||
* Endpoint which generates the report card for the current use to show the stats on the solved lessons
|
||||
*/
|
||||
@GetMapping(path = "/service/reportcard.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public ReportCard reportCard() {
|
||||
final ReportCard reportCard = new ReportCard();
|
||||
reportCard.setTotalNumberOfLessons(course.getTotalOfLessons());
|
||||
reportCard.setTotalNumberOfAssignments(course.getTotalOfAssignments());
|
||||
/**
|
||||
* Endpoint which generates the report card for the current use to show the stats on the solved
|
||||
* lessons
|
||||
*/
|
||||
@GetMapping(path = "/service/reportcard.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public ReportCard reportCard() {
|
||||
final ReportCard reportCard = new ReportCard();
|
||||
reportCard.setTotalNumberOfLessons(course.getTotalOfLessons());
|
||||
reportCard.setTotalNumberOfAssignments(course.getTotalOfAssignments());
|
||||
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
reportCard.setNumberOfAssignmentsSolved(userTracker.numberOfAssignmentsSolved());
|
||||
reportCard.setNumberOfLessonsSolved(userTracker.numberOfLessonsSolved());
|
||||
for (Lesson lesson : course.getLessons()) {
|
||||
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
||||
final LessonStatistics lessonStatistics = new LessonStatistics();
|
||||
lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle()));
|
||||
lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts());
|
||||
lessonStatistics.setSolved(lessonTracker.isLessonSolved());
|
||||
reportCard.lessonStatistics.add(lessonStatistics);
|
||||
}
|
||||
return reportCard;
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
reportCard.setNumberOfAssignmentsSolved(userTracker.numberOfAssignmentsSolved());
|
||||
reportCard.setNumberOfLessonsSolved(userTracker.numberOfLessonsSolved());
|
||||
for (Lesson lesson : course.getLessons()) {
|
||||
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
||||
final LessonStatistics lessonStatistics = new LessonStatistics();
|
||||
lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle()));
|
||||
lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts());
|
||||
lessonStatistics.setSolved(lessonTracker.isLessonSolved());
|
||||
reportCard.lessonStatistics.add(lessonStatistics);
|
||||
}
|
||||
return reportCard;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private final class ReportCard {
|
||||
@Getter
|
||||
@Setter
|
||||
private final class ReportCard {
|
||||
|
||||
private int totalNumberOfLessons;
|
||||
private int totalNumberOfAssignments;
|
||||
private int solvedLessons;
|
||||
private int numberOfAssignmentsSolved;
|
||||
private int numberOfLessonsSolved;
|
||||
private List<LessonStatistics> lessonStatistics = new ArrayList<>();
|
||||
}
|
||||
private int totalNumberOfLessons;
|
||||
private int totalNumberOfAssignments;
|
||||
private int solvedLessons;
|
||||
private int numberOfAssignmentsSolved;
|
||||
private int numberOfLessonsSolved;
|
||||
private List<LessonStatistics> lessonStatistics = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private final class LessonStatistics {
|
||||
private String name;
|
||||
private boolean solved;
|
||||
private int numberOfAttempts;
|
||||
}
|
||||
@Setter
|
||||
@Getter
|
||||
private final class LessonStatistics {
|
||||
private String name;
|
||||
private boolean solved;
|
||||
private int numberOfAttempts;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flywaydb.core.Flyway;
|
||||
@ -37,33 +39,30 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Controller
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class RestartLessonService {
|
||||
|
||||
private final WebSession webSession;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final Function<String, Flyway> flywayLessons;
|
||||
private final List<Initializeable> lessonsToInitialize;
|
||||
private final WebSession webSession;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final Function<String, Flyway> flywayLessons;
|
||||
private final List<Initializeable> lessonsToInitialize;
|
||||
|
||||
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public void restartLesson() {
|
||||
Lesson al = webSession.getCurrentLesson();
|
||||
log.debug("Restarting lesson: " + al);
|
||||
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public void restartLesson() {
|
||||
Lesson al = webSession.getCurrentLesson();
|
||||
log.debug("Restarting lesson: " + al);
|
||||
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
userTracker.reset(al);
|
||||
userTrackerRepository.save(userTracker);
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
userTracker.reset(al);
|
||||
userTrackerRepository.save(userTracker);
|
||||
|
||||
var flyway = flywayLessons.apply(webSession.getUserName());
|
||||
flyway.clean();
|
||||
flyway.migrate();
|
||||
var flyway = flywayLessons.apply(webSession.getUserName());
|
||||
flyway.clean();
|
||||
flyway.migrate();
|
||||
|
||||
lessonsToInitialize.forEach(i -> i.initialize(webSession.getUser()));
|
||||
}
|
||||
lessonsToInitialize.forEach(i -> i.initialize(webSession.getUser()));
|
||||
}
|
||||
}
|
||||
|
@ -17,17 +17,17 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@RequiredArgsConstructor
|
||||
public class SessionService {
|
||||
|
||||
private final WebSession webSession;
|
||||
private final RestartLessonService restartLessonService;
|
||||
private final Messages messages;
|
||||
private final WebSession webSession;
|
||||
private final RestartLessonService restartLessonService;
|
||||
private final Messages messages;
|
||||
|
||||
@RequestMapping(path = "/service/enable-security.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public String applySecurity() {
|
||||
webSession.toggleSecurity();
|
||||
restartLessonService.restartLesson();
|
||||
@RequestMapping(path = "/service/enable-security.mvc", produces = "application/json")
|
||||
@ResponseBody
|
||||
public String applySecurity() {
|
||||
webSession.toggleSecurity();
|
||||
restartLessonService.restartLesson();
|
||||
|
||||
var msg = webSession.isSecurityEnabled() ? "security.enabled" : "security.disabled";
|
||||
return messages.getMessage(msg);
|
||||
}
|
||||
var msg = webSession.isSecurityEnabled() ? "security.enabled" : "security.disabled";
|
||||
return messages.getMessage(msg);
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,36 @@
|
||||
package org.owasp.webgoat.container.session;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.lessons.Category;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @version $Id: $Id
|
||||
@ -39,60 +39,61 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class Course {
|
||||
|
||||
private List<Lesson> lessons;
|
||||
private List<Lesson> lessons;
|
||||
|
||||
public Course(List<Lesson> lessons) {
|
||||
this.lessons = lessons;
|
||||
}
|
||||
public Course(List<Lesson> lessons) {
|
||||
this.lessons = lessons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the categories attribute of the Course object
|
||||
*
|
||||
* @return The categories value
|
||||
*/
|
||||
public List<Category> getCategories() {
|
||||
return lessons.parallelStream().map(Lesson::getCategory).distinct().sorted().toList();
|
||||
}
|
||||
/**
|
||||
* Gets the categories attribute of the Course object
|
||||
*
|
||||
* @return The categories value
|
||||
*/
|
||||
public List<Category> getCategories() {
|
||||
return lessons.parallelStream().map(Lesson::getCategory).distinct().sorted().toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the firstLesson attribute of the Course object
|
||||
*
|
||||
* @return The firstLesson value
|
||||
*/
|
||||
public Lesson getFirstLesson() {
|
||||
// Category 0 is the admin function. We want the first real category
|
||||
// to be returned. This is normally the General category and the Http Basics lesson
|
||||
return getLessons(getCategories().get(0)).get(0);
|
||||
}
|
||||
/**
|
||||
* Gets the firstLesson attribute of the Course object
|
||||
*
|
||||
* @return The firstLesson value
|
||||
*/
|
||||
public Lesson getFirstLesson() {
|
||||
// Category 0 is the admin function. We want the first real category
|
||||
// to be returned. This is normally the General category and the Http Basics lesson
|
||||
return getLessons(getCategories().get(0)).get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>lessons</code>.</p>
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
public List<Lesson> getLessons() {
|
||||
return this.lessons;
|
||||
}
|
||||
/**
|
||||
* Getter for the field <code>lessons</code>.
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
public List<Lesson> getLessons() {
|
||||
return this.lessons;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>lessons</code>.</p>
|
||||
*
|
||||
* @param category a {@link org.owasp.webgoat.container.lessons.Category} object.
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
public List<Lesson> getLessons(Category category) {
|
||||
return this.lessons.stream().filter(l -> l.getCategory() == category).toList();
|
||||
}
|
||||
/**
|
||||
* Getter for the field <code>lessons</code>.
|
||||
*
|
||||
* @param category a {@link org.owasp.webgoat.container.lessons.Category} object.
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
public List<Lesson> getLessons(Category category) {
|
||||
return this.lessons.stream().filter(l -> l.getCategory() == category).toList();
|
||||
}
|
||||
|
||||
public void setLessons(List<Lesson> lessons) {
|
||||
this.lessons = lessons;
|
||||
}
|
||||
public void setLessons(List<Lesson> lessons) {
|
||||
this.lessons = lessons;
|
||||
}
|
||||
|
||||
public int getTotalOfLessons() {
|
||||
return this.lessons.size();
|
||||
}
|
||||
public int getTotalOfLessons() {
|
||||
return this.lessons.size();
|
||||
}
|
||||
|
||||
public int getTotalOfAssignments() {
|
||||
return this.lessons.stream().reduce(0, (total, lesson) -> lesson.getAssignments().size() + total, Integer::sum);
|
||||
}
|
||||
public int getTotalOfAssignments() {
|
||||
return this.lessons.stream()
|
||||
.reduce(0, (total, lesson) -> lesson.getAssignments().size() + total, Integer::sum);
|
||||
}
|
||||
}
|
||||
|
@ -3,44 +3,40 @@ package org.owasp.webgoat.container.session;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>LabelDebugger class.</p>
|
||||
* LabelDebugger class.
|
||||
*
|
||||
* @author dm
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
public class LabelDebugger implements Serializable {
|
||||
|
||||
private boolean enabled = false;
|
||||
private boolean enabled = false;
|
||||
|
||||
/**
|
||||
* <p>isEnabled.</p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
/**
|
||||
* isEnabled.
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Enables label debugging</p>
|
||||
*/
|
||||
public void enable() {
|
||||
this.enabled = true;
|
||||
}
|
||||
/** Enables label debugging */
|
||||
public void enable() {
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Disables label debugging</p>
|
||||
*/
|
||||
public void disable() {
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the status to enabled</p>
|
||||
* @param enabled {@link org.owasp.webgoat.container.session.LabelDebugger} object
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
/** Disables label debugging */
|
||||
public void disable() {
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status to enabled
|
||||
*
|
||||
* @param enabled {@link org.owasp.webgoat.container.session.LabelDebugger} object
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
@ -2,35 +2,31 @@ package org.owasp.webgoat.container.session;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by jason on 1/4/17.
|
||||
*/
|
||||
/** Created by jason on 1/4/17. */
|
||||
public class UserSessionData {
|
||||
|
||||
private HashMap<String,Object> userSessionData = new HashMap<>();
|
||||
private HashMap<String, Object> userSessionData = new HashMap<>();
|
||||
|
||||
public UserSessionData() {
|
||||
public UserSessionData() {}
|
||||
|
||||
public UserSessionData(String key, String value) {
|
||||
setValue(key, value);
|
||||
}
|
||||
|
||||
// GETTERS & SETTERS
|
||||
public Object getValue(String key) {
|
||||
if (!userSessionData.containsKey(key)) {
|
||||
return null;
|
||||
}
|
||||
// else
|
||||
return userSessionData.get(key);
|
||||
}
|
||||
|
||||
public UserSessionData(String key, String value) {
|
||||
setValue(key,value);
|
||||
public void setValue(String key, Object value) {
|
||||
if (userSessionData.containsKey(key)) {
|
||||
userSessionData.replace(key, value);
|
||||
} else {
|
||||
userSessionData.put(key, value);
|
||||
}
|
||||
|
||||
//GETTERS & SETTERS
|
||||
public Object getValue(String key) {
|
||||
if (!userSessionData.containsKey(key)) {
|
||||
return null;
|
||||
}
|
||||
// else
|
||||
return userSessionData.get(key);
|
||||
}
|
||||
|
||||
public void setValue(String key, Object value) {
|
||||
if (userSessionData.containsKey(key)) {
|
||||
userSessionData.replace(key,value);
|
||||
} else {
|
||||
userSessionData.put(key,value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,36 @@
|
||||
package org.owasp.webgoat.container.session;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* 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 - 2014 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>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 - 2014 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.
|
||||
*
|
||||
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
@ -37,51 +39,52 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class WebSession implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4270066103101711560L;
|
||||
private final WebGoatUser currentUser;
|
||||
private transient Lesson currentLesson;
|
||||
private boolean securityEnabled;
|
||||
private static final long serialVersionUID = -4270066103101711560L;
|
||||
private final WebGoatUser currentUser;
|
||||
private transient Lesson currentLesson;
|
||||
private boolean securityEnabled;
|
||||
|
||||
public WebSession() {
|
||||
this.currentUser = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
}
|
||||
public WebSession() {
|
||||
this.currentUser =
|
||||
(WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Setter for the field <code>currentScreen</code>. </p>
|
||||
*
|
||||
* @param lesson current lesson
|
||||
*/
|
||||
public void setCurrentLesson(Lesson lesson) {
|
||||
this.currentLesson = lesson;
|
||||
}
|
||||
/**
|
||||
* Setter for the field <code>currentScreen</code>.
|
||||
*
|
||||
* @param lesson current lesson
|
||||
*/
|
||||
public void setCurrentLesson(Lesson lesson) {
|
||||
this.currentLesson = lesson;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> getCurrentLesson. </p>
|
||||
*
|
||||
* @return a {@link Lesson} object.
|
||||
*/
|
||||
public Lesson getCurrentLesson() {
|
||||
return this.currentLesson;
|
||||
}
|
||||
/**
|
||||
* getCurrentLesson.
|
||||
*
|
||||
* @return a {@link Lesson} object.
|
||||
*/
|
||||
public Lesson getCurrentLesson() {
|
||||
return this.currentLesson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the userName attribute of the WebSession object
|
||||
*
|
||||
* @return The userName value
|
||||
*/
|
||||
public String getUserName() {
|
||||
return currentUser.getUsername();
|
||||
}
|
||||
/**
|
||||
* Gets the userName attribute of the WebSession object
|
||||
*
|
||||
* @return The userName value
|
||||
*/
|
||||
public String getUserName() {
|
||||
return currentUser.getUsername();
|
||||
}
|
||||
|
||||
public WebGoatUser getUser() {
|
||||
return currentUser;
|
||||
}
|
||||
public WebGoatUser getUser() {
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
public void toggleSecurity() {
|
||||
this.securityEnabled = !this.securityEnabled;
|
||||
}
|
||||
public void toggleSecurity() {
|
||||
this.securityEnabled = !this.securityEnabled;
|
||||
}
|
||||
|
||||
public boolean isSecurityEnabled() {
|
||||
return securityEnabled;
|
||||
}
|
||||
public boolean isSecurityEnabled() {
|
||||
return securityEnabled;
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,38 @@
|
||||
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.*;
|
||||
import lombok.Getter;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @version $Id: $Id
|
||||
@ -43,72 +41,69 @@ import java.util.stream.Collectors;
|
||||
@Entity
|
||||
public class LessonTracker {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
@Getter
|
||||
private String lessonName;
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private final Set<Assignment> solvedAssignments = new HashSet<>();
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private final Set<Assignment> allAssignments = new HashSet<>();
|
||||
@Getter
|
||||
private int numberOfAttempts = 0;
|
||||
@Version
|
||||
private Integer version;
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private LessonTracker() {
|
||||
//JPA
|
||||
}
|
||||
@Getter private String lessonName;
|
||||
|
||||
public LessonTracker(Lesson lesson) {
|
||||
lessonName = lesson.getId();
|
||||
allAssignments.addAll(lesson.getAssignments() == null ? List.of() : lesson.getAssignments());
|
||||
}
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private final Set<Assignment> solvedAssignments = new HashSet<>();
|
||||
|
||||
public Optional<Assignment> getAssignment(String name) {
|
||||
return allAssignments.stream().filter(a -> a.getName().equals(name)).findFirst();
|
||||
}
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private final Set<Assignment> allAssignments = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Mark an assignment as solved
|
||||
*
|
||||
* @param solvedAssignment the assignment which the user solved
|
||||
*/
|
||||
public void assignmentSolved(String solvedAssignment) {
|
||||
getAssignment(solvedAssignment).ifPresent(solvedAssignments::add);
|
||||
}
|
||||
@Getter private int numberOfAttempts = 0;
|
||||
@Version private Integer version;
|
||||
|
||||
/**
|
||||
* @return did they user solved all solvedAssignments for the lesson?
|
||||
*/
|
||||
public boolean isLessonSolved() {
|
||||
return allAssignments.size() == solvedAssignments.size();
|
||||
}
|
||||
private LessonTracker() {
|
||||
// JPA
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the number attempts to solve the lesson
|
||||
*/
|
||||
public void incrementAttempts() {
|
||||
numberOfAttempts++;
|
||||
}
|
||||
public LessonTracker(Lesson lesson) {
|
||||
lessonName = lesson.getId();
|
||||
allAssignments.addAll(lesson.getAssignments() == null ? List.of() : lesson.getAssignments());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the tracker. We do not reset the number of attempts here!
|
||||
*/
|
||||
void reset() {
|
||||
solvedAssignments.clear();
|
||||
}
|
||||
public Optional<Assignment> getAssignment(String name) {
|
||||
return allAssignments.stream().filter(a -> a.getName().equals(name)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list containing all the assignments solved or not
|
||||
*/
|
||||
public Map<Assignment, Boolean> getLessonOverview() {
|
||||
List<Assignment> notSolved = allAssignments.stream()
|
||||
.filter(i -> !solvedAssignments.contains(i))
|
||||
.toList();
|
||||
Map<Assignment, Boolean> overview = notSolved.stream().collect(Collectors.toMap(a -> a, b -> false));
|
||||
overview.putAll(solvedAssignments.stream().collect(Collectors.toMap(a -> a, b -> true)));
|
||||
return overview;
|
||||
}
|
||||
/**
|
||||
* Mark an assignment as solved
|
||||
*
|
||||
* @param solvedAssignment the assignment which the user solved
|
||||
*/
|
||||
public void assignmentSolved(String solvedAssignment) {
|
||||
getAssignment(solvedAssignment).ifPresent(solvedAssignments::add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return did they user solved all solvedAssignments for the lesson?
|
||||
*/
|
||||
public boolean isLessonSolved() {
|
||||
return allAssignments.size() == solvedAssignments.size();
|
||||
}
|
||||
|
||||
/** Increase the number attempts to solve the lesson */
|
||||
public void incrementAttempts() {
|
||||
numberOfAttempts++;
|
||||
}
|
||||
|
||||
/** Reset the tracker. We do not reset the number of attempts here! */
|
||||
void reset() {
|
||||
solvedAssignments.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list containing all the assignments solved or not
|
||||
*/
|
||||
public Map<Assignment, Boolean> getLessonOverview() {
|
||||
List<Assignment> notSolved =
|
||||
allAssignments.stream().filter(i -> !solvedAssignments.contains(i)).toList();
|
||||
Map<Assignment, Boolean> overview =
|
||||
notSolved.stream().collect(Collectors.toMap(a -> a, b -> false));
|
||||
overview.putAll(solvedAssignments.stream().collect(Collectors.toMap(a -> a, b -> true)));
|
||||
return overview;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
@ -9,10 +12,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 3/19/17.
|
||||
@ -22,25 +21,29 @@ import javax.validation.Valid;
|
||||
@Slf4j
|
||||
public class RegistrationController {
|
||||
|
||||
private UserValidator userValidator;
|
||||
private UserService userService;
|
||||
private AuthenticationManager authenticationManager;
|
||||
private UserValidator userValidator;
|
||||
private UserService userService;
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@GetMapping("/registration")
|
||||
public String showForm(UserForm userForm) {
|
||||
return "registration";
|
||||
@GetMapping("/registration")
|
||||
public String showForm(UserForm userForm) {
|
||||
return "registration";
|
||||
}
|
||||
|
||||
@PostMapping("/register.mvc")
|
||||
public String registration(
|
||||
@ModelAttribute("userForm") @Valid UserForm userForm,
|
||||
BindingResult bindingResult,
|
||||
HttpServletRequest request)
|
||||
throws ServletException {
|
||||
userValidator.validate(userForm, bindingResult);
|
||||
|
||||
if (bindingResult.hasErrors()) {
|
||||
return "registration";
|
||||
}
|
||||
userService.addUser(userForm.getUsername(), userForm.getPassword());
|
||||
request.login(userForm.getUsername(), userForm.getPassword());
|
||||
|
||||
@PostMapping("/register.mvc")
|
||||
public String registration(@ModelAttribute("userForm") @Valid UserForm userForm, BindingResult bindingResult, HttpServletRequest request) throws ServletException {
|
||||
userValidator.validate(userForm, bindingResult);
|
||||
|
||||
if (bindingResult.hasErrors()) {
|
||||
return "registration";
|
||||
}
|
||||
userService.addUser(userForm.getUsername(), userForm.getPassword());
|
||||
request.login(userForm.getUsername(), userForm.getPassword());
|
||||
|
||||
return "redirect:/attack";
|
||||
}
|
||||
return "redirect:/attack";
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
||||
@ -8,10 +11,6 @@ import org.owasp.webgoat.container.session.Course;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Temp endpoint just for the CTF.
|
||||
*
|
||||
@ -22,52 +21,63 @@ import java.util.Optional;
|
||||
@AllArgsConstructor
|
||||
public class Scoreboard {
|
||||
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final Course course;
|
||||
private final PluginMessages pluginMessages;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final Course course;
|
||||
private final PluginMessages pluginMessages;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private class Ranking {
|
||||
private String username;
|
||||
private List<String> flagsCaptured;
|
||||
}
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private class Ranking {
|
||||
private String username;
|
||||
private List<String> flagsCaptured;
|
||||
}
|
||||
|
||||
@GetMapping("/scoreboard-data")
|
||||
public List<Ranking> getRankings() {
|
||||
List<WebGoatUser> allUsers = userRepository.findAll();
|
||||
List<Ranking> rankings = new ArrayList<>();
|
||||
for (WebGoatUser user : allUsers) {
|
||||
if (user.getUsername().startsWith("csrf-")) {
|
||||
//the csrf- assignment specific users do not need to be in the overview
|
||||
continue;
|
||||
}
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(user.getUsername());
|
||||
rankings.add(new Ranking(user.getUsername(), challengesSolved(userTracker)));
|
||||
}
|
||||
/* sort on number of captured flags to present an ordered ranking */
|
||||
rankings.sort((o1, o2) -> o2.getFlagsCaptured().size() - o1.getFlagsCaptured().size());
|
||||
return rankings;
|
||||
@GetMapping("/scoreboard-data")
|
||||
public List<Ranking> getRankings() {
|
||||
List<WebGoatUser> allUsers = userRepository.findAll();
|
||||
List<Ranking> rankings = new ArrayList<>();
|
||||
for (WebGoatUser user : allUsers) {
|
||||
if (user.getUsername().startsWith("csrf-")) {
|
||||
// the csrf- assignment specific users do not need to be in the overview
|
||||
continue;
|
||||
}
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(user.getUsername());
|
||||
rankings.add(new Ranking(user.getUsername(), challengesSolved(userTracker)));
|
||||
}
|
||||
/* sort on number of captured flags to present an ordered ranking */
|
||||
rankings.sort((o1, o2) -> o2.getFlagsCaptured().size() - o1.getFlagsCaptured().size());
|
||||
return rankings;
|
||||
}
|
||||
|
||||
private List<String> challengesSolved(UserTracker userTracker) {
|
||||
List<String> challenges = List.of("Challenge1", "Challenge2", "Challenge3", "Challenge4", "Challenge5", "Challenge6", "Challenge7", "Challenge8", "Challenge9");
|
||||
return challenges.stream()
|
||||
.map(userTracker::getLessonTracker)
|
||||
.flatMap(Optional::stream)
|
||||
.filter(LessonTracker::isLessonSolved)
|
||||
.map(LessonTracker::getLessonName)
|
||||
.map(this::toLessonTitle)
|
||||
.toList();
|
||||
}
|
||||
private List<String> challengesSolved(UserTracker userTracker) {
|
||||
List<String> challenges =
|
||||
List.of(
|
||||
"Challenge1",
|
||||
"Challenge2",
|
||||
"Challenge3",
|
||||
"Challenge4",
|
||||
"Challenge5",
|
||||
"Challenge6",
|
||||
"Challenge7",
|
||||
"Challenge8",
|
||||
"Challenge9");
|
||||
return challenges.stream()
|
||||
.map(userTracker::getLessonTracker)
|
||||
.flatMap(Optional::stream)
|
||||
.filter(LessonTracker::isLessonSolved)
|
||||
.map(LessonTracker::getLessonName)
|
||||
.map(this::toLessonTitle)
|
||||
.toList();
|
||||
}
|
||||
|
||||
private String toLessonTitle(String id) {
|
||||
String titleKey = course.getLessons().stream()
|
||||
.filter(l -> l.getId().equals(id))
|
||||
.findFirst()
|
||||
.map(Lesson::getTitle)
|
||||
.orElse("No title");
|
||||
return pluginMessages.getMessage(titleKey, titleKey);
|
||||
}
|
||||
private String toLessonTitle(String id) {
|
||||
String titleKey =
|
||||
course.getLessons().stream()
|
||||
.filter(l -> l.getId().equals(id))
|
||||
.findFirst()
|
||||
.map(Lesson::getTitle)
|
||||
.orElse("No title");
|
||||
return pluginMessages.getMessage(titleKey, titleKey);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
@ -15,16 +14,18 @@ import javax.validation.constraints.Size;
|
||||
@Setter
|
||||
public class UserForm {
|
||||
|
||||
@NotNull
|
||||
@Size(min = 6, max = 45)
|
||||
@Pattern(regexp = "[a-z0-9-]*", message = "can only contain lowercase letters, digits, and -")
|
||||
private String username;
|
||||
@NotNull
|
||||
@Size(min = 6, max = 10)
|
||||
private String password;
|
||||
@NotNull
|
||||
@Size(min = 6, max = 10)
|
||||
private String matchingPassword;
|
||||
@NotNull
|
||||
private String agree;
|
||||
@NotNull
|
||||
@Size(min = 6, max = 45)
|
||||
@Pattern(regexp = "[a-z0-9-]*", message = "can only contain lowercase letters, digits, and -")
|
||||
private String username;
|
||||
|
||||
@NotNull
|
||||
@Size(min = 6, max = 10)
|
||||
private String password;
|
||||
|
||||
@NotNull
|
||||
@Size(min = 6, max = 10)
|
||||
private String matchingPassword;
|
||||
|
||||
@NotNull private String agree;
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
@ -10,10 +9,9 @@ import java.util.List;
|
||||
*/
|
||||
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
|
||||
|
||||
WebGoatUser findByUsername(String username);
|
||||
WebGoatUser findByUsername(String username);
|
||||
|
||||
List<WebGoatUser> findAll();
|
||||
|
||||
boolean existsByUsername(String username);
|
||||
List<WebGoatUser> findAll();
|
||||
|
||||
boolean existsByUsername(String username);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.owasp.webgoat.container.lessons.Initializeable;
|
||||
@ -8,9 +10,6 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 3/19/17.
|
||||
@ -19,42 +18,42 @@ import java.util.function.Function;
|
||||
@AllArgsConstructor
|
||||
public class UserService implements UserDetailsService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final Function<String, Flyway> flywayLessons;
|
||||
private final List<Initializeable> lessonInitializables;
|
||||
private final UserRepository userRepository;
|
||||
private final UserTrackerRepository userTrackerRepository;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final Function<String, Flyway> flywayLessons;
|
||||
private final List<Initializeable> lessonInitializables;
|
||||
|
||||
@Override
|
||||
public WebGoatUser loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
WebGoatUser webGoatUser = userRepository.findByUsername(username);
|
||||
if (webGoatUser == null) {
|
||||
throw new UsernameNotFoundException("User not found");
|
||||
} else {
|
||||
webGoatUser.createUser();
|
||||
lessonInitializables.forEach(l -> l.initialize(webGoatUser));
|
||||
}
|
||||
return webGoatUser;
|
||||
@Override
|
||||
public WebGoatUser loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
WebGoatUser webGoatUser = userRepository.findByUsername(username);
|
||||
if (webGoatUser == null) {
|
||||
throw new UsernameNotFoundException("User not found");
|
||||
} else {
|
||||
webGoatUser.createUser();
|
||||
lessonInitializables.forEach(l -> l.initialize(webGoatUser));
|
||||
}
|
||||
return webGoatUser;
|
||||
}
|
||||
|
||||
public void addUser(String username, String password) {
|
||||
//get user if there exists one by the name
|
||||
var userAlreadyExists = userRepository.existsByUsername(username);
|
||||
var webGoatUser = userRepository.save(new WebGoatUser(username, password));
|
||||
public void addUser(String username, String password) {
|
||||
// get user if there exists one by the name
|
||||
var userAlreadyExists = userRepository.existsByUsername(username);
|
||||
var webGoatUser = userRepository.save(new WebGoatUser(username, password));
|
||||
|
||||
if (!userAlreadyExists) {
|
||||
userTrackerRepository.save(new UserTracker(username)); //if user previously existed it will not get another tracker
|
||||
createLessonsForUser(webGoatUser);
|
||||
}
|
||||
if (!userAlreadyExists) {
|
||||
userTrackerRepository.save(
|
||||
new UserTracker(username)); // if user previously existed it will not get another tracker
|
||||
createLessonsForUser(webGoatUser);
|
||||
}
|
||||
}
|
||||
|
||||
private void createLessonsForUser(WebGoatUser webGoatUser) {
|
||||
jdbcTemplate.execute("CREATE SCHEMA \"" + webGoatUser.getUsername() + "\" authorization dba");
|
||||
flywayLessons.apply(webGoatUser.getUsername()).migrate();
|
||||
}
|
||||
|
||||
public List<WebGoatUser> getAllUsers() {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
private void createLessonsForUser(WebGoatUser webGoatUser) {
|
||||
jdbcTemplate.execute("CREATE SCHEMA \"" + webGoatUser.getUsername() + "\" authorization dba");
|
||||
flywayLessons.apply(webGoatUser.getUsername()).migrate();
|
||||
}
|
||||
|
||||
public List<WebGoatUser> getAllUsers() {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import org.springframework.data.annotation.Id;
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class UserSession {
|
||||
|
||||
private WebGoatUser webGoatUser;
|
||||
@Id
|
||||
private String sessionId;
|
||||
private WebGoatUser webGoatUser;
|
||||
@Id private String sessionId;
|
||||
}
|
||||
|
@ -1,43 +1,41 @@
|
||||
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
*
|
||||
* <p>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 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 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
|
||||
*
|
||||
* <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>Getting Source ==============
|
||||
*
|
||||
* <p>Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @version $Id: $Id
|
||||
@ -47,80 +45,83 @@ import java.util.stream.Collectors;
|
||||
@Entity
|
||||
public class UserTracker {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
@Column(name = "username")
|
||||
private String user;
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private Set<LessonTracker> lessonTrackers = new HashSet<>();
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private UserTracker() {}
|
||||
@Column(name = "username")
|
||||
private String user;
|
||||
|
||||
public UserTracker(final String user) {
|
||||
this.user = user;
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private Set<LessonTracker> lessonTrackers = new HashSet<>();
|
||||
|
||||
private UserTracker() {}
|
||||
|
||||
public UserTracker(final String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing lesson tracker or create a new one based on the lesson
|
||||
*
|
||||
* @param lesson the lesson
|
||||
* @return a lesson tracker created if not already present
|
||||
*/
|
||||
public LessonTracker getLessonTracker(Lesson lesson) {
|
||||
Optional<LessonTracker> lessonTracker =
|
||||
lessonTrackers.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst();
|
||||
if (!lessonTracker.isPresent()) {
|
||||
LessonTracker newLessonTracker = new LessonTracker(lesson);
|
||||
lessonTrackers.add(newLessonTracker);
|
||||
return newLessonTracker;
|
||||
} else {
|
||||
return lessonTracker.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing lesson tracker or create a new one based on the lesson
|
||||
*
|
||||
* @param lesson the lesson
|
||||
* @return a lesson tracker created if not already present
|
||||
*/
|
||||
public LessonTracker getLessonTracker(Lesson lesson) {
|
||||
Optional<LessonTracker> lessonTracker = lessonTrackers
|
||||
.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst();
|
||||
if (!lessonTracker.isPresent()) {
|
||||
LessonTracker newLessonTracker = new LessonTracker(lesson);
|
||||
lessonTrackers.add(newLessonTracker);
|
||||
return newLessonTracker;
|
||||
} else {
|
||||
return lessonTracker.get();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Query method for finding a specific lesson tracker based on id
|
||||
*
|
||||
* @param id the id of the lesson
|
||||
* @return optional due to the fact we can only create a lesson tracker based on a lesson
|
||||
*/
|
||||
public Optional<LessonTracker> getLessonTracker(String id) {
|
||||
return lessonTrackers.stream().filter(l -> l.getLessonName().equals(id)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query method for finding a specific lesson tracker based on id
|
||||
*
|
||||
* @param id the id of the lesson
|
||||
* @return optional due to the fact we can only create a lesson tracker based on a lesson
|
||||
*/
|
||||
public Optional<LessonTracker> getLessonTracker(String id) {
|
||||
return lessonTrackers.stream().filter(l -> l.getLessonName().equals(id)).findFirst();
|
||||
}
|
||||
public void assignmentSolved(Lesson lesson, String assignmentName) {
|
||||
LessonTracker lessonTracker = getLessonTracker(lesson);
|
||||
lessonTracker.incrementAttempts();
|
||||
lessonTracker.assignmentSolved(assignmentName);
|
||||
}
|
||||
|
||||
public void assignmentSolved(Lesson lesson, String assignmentName) {
|
||||
LessonTracker lessonTracker = getLessonTracker(lesson);
|
||||
lessonTracker.incrementAttempts();
|
||||
lessonTracker.assignmentSolved(assignmentName);
|
||||
}
|
||||
public void assignmentFailed(Lesson lesson) {
|
||||
LessonTracker lessonTracker = getLessonTracker(lesson);
|
||||
lessonTracker.incrementAttempts();
|
||||
}
|
||||
|
||||
public void assignmentFailed(Lesson lesson) {
|
||||
LessonTracker lessonTracker = getLessonTracker(lesson);
|
||||
lessonTracker.incrementAttempts();
|
||||
}
|
||||
public void reset(Lesson al) {
|
||||
LessonTracker lessonTracker = getLessonTracker(al);
|
||||
lessonTracker.reset();
|
||||
}
|
||||
|
||||
public void reset(Lesson al) {
|
||||
LessonTracker lessonTracker = getLessonTracker(al);
|
||||
lessonTracker.reset();
|
||||
public int numberOfLessonsSolved() {
|
||||
int numberOfLessonsSolved = 0;
|
||||
for (LessonTracker lessonTracker : lessonTrackers) {
|
||||
if (lessonTracker.isLessonSolved()) {
|
||||
numberOfLessonsSolved = numberOfLessonsSolved + 1;
|
||||
}
|
||||
}
|
||||
return numberOfLessonsSolved;
|
||||
}
|
||||
|
||||
public int numberOfLessonsSolved() {
|
||||
int numberOfLessonsSolved = 0;
|
||||
for (LessonTracker lessonTracker : lessonTrackers) {
|
||||
if (lessonTracker.isLessonSolved()) {
|
||||
numberOfLessonsSolved = numberOfLessonsSolved + 1;
|
||||
}
|
||||
}
|
||||
return numberOfLessonsSolved;
|
||||
}
|
||||
|
||||
public int numberOfAssignmentsSolved() {
|
||||
int numberOfAssignmentsSolved = 0;
|
||||
for (LessonTracker lessonTracker : lessonTrackers) {
|
||||
Map<Assignment, Boolean> lessonOverview = lessonTracker.getLessonOverview();
|
||||
numberOfAssignmentsSolved = lessonOverview.values().stream().filter(b -> b).collect(Collectors.counting()).intValue();
|
||||
}
|
||||
return numberOfAssignmentsSolved;
|
||||
public int numberOfAssignmentsSolved() {
|
||||
int numberOfAssignmentsSolved = 0;
|
||||
for (LessonTracker lessonTracker : lessonTrackers) {
|
||||
Map<Assignment, Boolean> lessonOverview = lessonTracker.getLessonOverview();
|
||||
numberOfAssignmentsSolved =
|
||||
lessonOverview.values().stream().filter(b -> b).collect(Collectors.counting()).intValue();
|
||||
}
|
||||
return numberOfAssignmentsSolved;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
*/
|
||||
public interface UserTrackerRepository extends JpaRepository<UserTracker, String> {
|
||||
|
||||
UserTracker findByUser(String user);
|
||||
|
||||
UserTracker findByUser(String user);
|
||||
}
|
||||
|
@ -13,23 +13,23 @@ import org.springframework.validation.Validator;
|
||||
@AllArgsConstructor
|
||||
public class UserValidator implements Validator {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return UserForm.class.equals(clazz);
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return UserForm.class.equals(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Object o, Errors errors) {
|
||||
UserForm userForm = (UserForm) o;
|
||||
|
||||
if (userRepository.findByUsername(userForm.getUsername()) != null) {
|
||||
errors.rejectValue("username", "username.duplicate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Object o, Errors errors) {
|
||||
UserForm userForm = (UserForm) o;
|
||||
|
||||
if (userRepository.findByUsername(userForm.getUsername()) != null) {
|
||||
errors.rejectValue("username", "username.duplicate");
|
||||
}
|
||||
|
||||
if (!userForm.getMatchingPassword().equals(userForm.getPassword())) {
|
||||
errors.rejectValue("matchingPassword", "password.diff");
|
||||
}
|
||||
if (!userForm.getMatchingPassword().equals(userForm.getPassword())) {
|
||||
errors.rejectValue("matchingPassword", "password.diff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Transient;
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Transient;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 3/19/17.
|
||||
@ -20,79 +19,72 @@ import java.util.Collections;
|
||||
@Entity
|
||||
public class WebGoatUser implements UserDetails {
|
||||
|
||||
public static final String ROLE_USER = "WEBGOAT_USER";
|
||||
public static final String ROLE_ADMIN = "WEBGOAT_ADMIN";
|
||||
public static final String ROLE_USER = "WEBGOAT_USER";
|
||||
public static final String ROLE_ADMIN = "WEBGOAT_ADMIN";
|
||||
|
||||
@Id
|
||||
private String username;
|
||||
private String password;
|
||||
private String role = ROLE_USER;
|
||||
@Transient
|
||||
private User user;
|
||||
@Id private String username;
|
||||
private String password;
|
||||
private String role = ROLE_USER;
|
||||
@Transient private User user;
|
||||
|
||||
protected WebGoatUser() {
|
||||
}
|
||||
protected WebGoatUser() {}
|
||||
|
||||
public WebGoatUser(String username, String password) {
|
||||
this(username, password, ROLE_USER);
|
||||
}
|
||||
public WebGoatUser(String username, String password) {
|
||||
this(username, password, ROLE_USER);
|
||||
}
|
||||
|
||||
public WebGoatUser(String username, String password, String role) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.role = role;
|
||||
createUser();
|
||||
}
|
||||
public WebGoatUser(String username, String password, String role) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.role = role;
|
||||
createUser();
|
||||
}
|
||||
|
||||
public void createUser() {
|
||||
this.user = new User(username, password, getAuthorities());
|
||||
}
|
||||
|
||||
public void createUser() {
|
||||
this.user = new User(username, password, getAuthorities());
|
||||
}
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return Collections.singleton(new SimpleGrantedAuthority(getRole()));
|
||||
}
|
||||
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return Collections.singleton(new SimpleGrantedAuthority(getRole()));
|
||||
}
|
||||
public String getRole() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return this.role;
|
||||
}
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.user.isAccountNonExpired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.user.isAccountNonExpired();
|
||||
}
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.user.isAccountNonLocked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.user.isAccountNonLocked();
|
||||
}
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return this.user.isCredentialsNonExpired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return this.user.isCredentialsNonExpired();
|
||||
}
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.user.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.user.isEnabled();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof WebGoatUser webGoatUser && this.user.equals(webGoatUser.user);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return user.hashCode();
|
||||
}
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof WebGoatUser webGoatUser && this.user.equals(webGoatUser.user);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return user.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user