WebWolf DataSource Discovery
This commit is contained in:
parent
8e567b0f86
commit
9af514f3eb
@ -16,8 +16,6 @@ java \
|
||||
--add-opens java.base/java.io=ALL-UNNAMED \
|
||||
-jar webgoat.jar --webgoat.build.version="$1" --server.address=0.0.0.0 > webgoat.log &
|
||||
|
||||
sleep 30
|
||||
|
||||
echo "Starting WebWolf..."
|
||||
java -Duser.home=/home/webgoat -Dfile.encoding=UTF-8 -jar webwolf.jar --webgoat.build.version=$1 --server.address=0.0.0.0 > webwolf.log &
|
||||
|
||||
|
@ -58,7 +58,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry security = http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/css/**", "/images/**", "/js/**", "fonts/**", "/plugins/**", "/registration", "/register.mvc").permitAll()
|
||||
.antMatchers("/css/**", "/images/**", "/js/**", "fonts/**", "/plugins/**", "/registration", "/register.mvc", "/actuator/**").permitAll()
|
||||
.anyRequest().authenticated();
|
||||
security.and()
|
||||
.formLogin()
|
||||
|
@ -55,4 +55,8 @@ exclude.categories=${EXCLUDE_CATEGORIES:none,none}
|
||||
#exclude based on the enum of the Category
|
||||
|
||||
exclude.lessons=${EXCLUDE_LESSONS:none,none}
|
||||
#exclude based on the class name of a lesson e.g.: LessonTemplate
|
||||
#exclude based on the class name of a lesson e.g.: LessonTemplate
|
||||
|
||||
management.health.db.enabled=true
|
||||
management.endpoint.health.show-details=always
|
||||
management.endpoints.web.exposure.include=health,configprops
|
||||
|
@ -67,6 +67,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
|
@ -22,18 +22,14 @@
|
||||
|
||||
package org.owasp.webwolf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import org.owasp.webwolf.requests.WebWolfTraceRepository;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@SpringBootApplication
|
||||
public class WebWolf {
|
||||
@ -45,26 +41,20 @@ public class WebWolf {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("spring.config.name", "application-webwolf");
|
||||
|
||||
|
||||
String webwolfPort = System.getenv("WEBWOLF_PORT");
|
||||
String databasePort = System.getenv("WEBGOAT_HSQLPORT");
|
||||
String webGoatHost = null==System.getenv("WEBGOAT_HOST")?"127.0.0.1":System.getenv("WEBGOAT_HOST");
|
||||
String webWolfHost = null==System.getenv("WEBWOLF_HOST")?"127.0.0.1":System.getenv("WEBWOLF_HOST");
|
||||
String fileEncoding = System.getProperty("file.encoding");
|
||||
|
||||
int wolfPort = webwolfPort == null?9090:Integer.parseInt(webwolfPort);
|
||||
int dbPort = databasePort == null?9001:Integer.parseInt(databasePort);
|
||||
|
||||
if (null==fileEncoding || !fileEncoding.equals("UTF-8")) {
|
||||
System.out.println("It seems the application is startd on a OS with non default UTF-8 encoding:"+fileEncoding);
|
||||
System.out.println("Please add: -Dfile.encoding=UTF-8");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
if (!isAlreadyRunning(webGoatHost, dbPort)) {
|
||||
System.out.println("It seems that the required database is not running. Please start WebGoat with the integrated or standalone database first.");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
if (isAlreadyRunning(webGoatHost, wolfPort)) {
|
||||
System.out.println("Port "+webWolfHost+":"+wolfPort+" is in use. Use environment value WEBWOLF_PORT to set a different value.");
|
||||
System.exit(-1);
|
||||
@ -72,13 +62,6 @@ public class WebWolf {
|
||||
SpringApplication.run(WebWolf.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource(@Value("${spring.datasource.url}") String url, @Value("${spring.datasource.driver-class-name}") String driverClassName) {
|
||||
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(url);
|
||||
driverManagerDataSource.setDriverClassName(driverClassName);
|
||||
return driverManagerDataSource;
|
||||
}
|
||||
|
||||
private static boolean isAlreadyRunning(String host, int port) {
|
||||
try (var ignored = new Socket(host, port)) {
|
||||
return true;
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 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.webwolf.db;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public final class ActuatorDsJsonParser {
|
||||
|
||||
protected static final String getDsPropertyFromConfigProps(JsonNode node, String propertyName) {
|
||||
return node
|
||||
.get("application")
|
||||
.get("beans")
|
||||
.get("spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties")
|
||||
.get("properties")
|
||||
.get(propertyName)
|
||||
.asText();
|
||||
}
|
||||
|
||||
protected static final String getDsHealthStatus(JsonNode node) {
|
||||
return node
|
||||
.get("components")
|
||||
.get("db")
|
||||
.get("components")
|
||||
.get("dataSource")
|
||||
.get("status")
|
||||
.asText();
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 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.webwolf.db;
|
||||
|
||||
import static org.owasp.webwolf.db.ActuatorDsJsonParser.getDsPropertyFromConfigProps;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class DataSourceProperties implements Serializable {
|
||||
private static final long serialVersionUID = -5897408528235134090L;
|
||||
private String url;
|
||||
private String driverClassName;
|
||||
|
||||
@JsonProperty("contexts")
|
||||
protected void props(JsonNode node) {
|
||||
url = getDsPropertyFromConfigProps(node, "url");
|
||||
driverClassName = getDsPropertyFromConfigProps(node, "driverClassName");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 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.webwolf.db;
|
||||
|
||||
import static org.owasp.webwolf.db.ActuatorDsJsonParser.getDsHealthStatus;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.retry.annotation.Backoff;
|
||||
import org.springframework.retry.annotation.EnableRetry;
|
||||
import org.springframework.retry.annotation.Recover;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@EnableRetry
|
||||
public class DataSourceResolver {
|
||||
|
||||
@Value("${webgoat.actuator.base.url}")
|
||||
private String baseUrl;
|
||||
|
||||
@Value("${webgoat.actuator.health.db.path:/health}")
|
||||
private String dbHealthPath;
|
||||
|
||||
@Value("${webgoat.actuator.configprops.path:/configprops}")
|
||||
private String configPropsPath;
|
||||
|
||||
@Autowired
|
||||
ApplicationContext ctx;
|
||||
|
||||
@Bean
|
||||
@DependsOn("dsConfigDiscovery")
|
||||
public DataSource dataSource(DataSourceProperties dataSourceProperties) {
|
||||
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(dataSourceProperties.getUrl());
|
||||
driverManagerDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
|
||||
return driverManagerDataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Retryable(maxAttemptsExpression = "${webwolf.datasource-discovery.retry.max-attempts:5}",
|
||||
value = Exception.class,
|
||||
backoff = @Backoff(
|
||||
multiplierExpression = "${webwolf.datasource-discovery.retry.backoff.multiplier:1.5}",
|
||||
maxDelayExpression = "${webwolf.datasource-discovery.retry.backoff.max-delay:30000}",
|
||||
delayExpression = "${webwolf.datasource-discovery.retry.backoff.delay:5000}"))
|
||||
public DataSourceProperties dsConfigDiscovery(RestTemplate restTemplate) {
|
||||
healthCheck(restTemplate);
|
||||
return restTemplate.getForObject(baseUrl + configPropsPath, DataSourceProperties.class);
|
||||
}
|
||||
|
||||
public void healthCheck(RestTemplate restTemplate) {
|
||||
log.info("Checking database availability.");
|
||||
JsonNode json = restTemplate.getForObject(baseUrl + dbHealthPath, JsonNode.class);
|
||||
String status = getDsHealthStatus(json);
|
||||
if (!status.equals("UP")) {
|
||||
throw new ResourceUnavailableException();
|
||||
}
|
||||
}
|
||||
|
||||
@Recover
|
||||
public DataSourceProperties exitOnResourceUnavailable(Exception e, RestTemplate restTemplate) {
|
||||
log.error("It seems that the required database is not running. Please start WebGoat with the integrated or standalone database first.");
|
||||
System.exit(SpringApplication.exit(ctx, () -> 1));
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.owasp.webwolf.db;
|
||||
|
||||
public class ResourceUnavailableException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ResourceUnavailableException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ResourceUnavailableException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ResourceUnavailableException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ResourceUnavailableException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -7,8 +7,6 @@ server.address=${WEBWOLF_HOST:127.0.0.1}
|
||||
server.servlet.session.cookie.name=WEBWOLFSESSION
|
||||
server.servlet.session.timeout=6000
|
||||
|
||||
spring.datasource.url=jdbc:hsqldb:hsql://${WEBGOAT_HOST:127.0.0.1}:${WEBGOAT_HSQLPORT:9001}/webgoat
|
||||
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||
spring.jpa.properties.hibernate.default_schema=CONTAINER
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
@ -32,9 +30,11 @@ multipart.max-file-size=1Mb
|
||||
multipart.max-request-size=1Mb
|
||||
|
||||
webgoat.build.version=@project.version@
|
||||
webgoat.actuator.base.url=http://${WEBGOAT_HOST:127.0.0.1}:${WEBGOAT_PORT:8080}/WebGoat/actuator
|
||||
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||
webwolf.fileserver.location=${java.io.tmpdir}/webwolf-fileserver
|
||||
|
||||
|
||||
spring.jackson.serialization.indent_output=true
|
||||
spring.jackson.serialization.write-dates-as-timestamps=false
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user