#961: Give each user its own schema for the lessons

This way we can reset a lesson using the database for each user and not for all users at once.
Also solves the issue that when someone solves the lesson it is solved for all users on the same WebGoat instance
This commit is contained in:
Nanne Baars
2021-04-10 09:47:07 +02:00
committed by Nanne Baars
parent 04d065fd87
commit e49f5d610f
30 changed files with 281 additions and 170 deletions

View File

@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
@ -14,14 +15,19 @@ import java.sql.SQLException;
@SpringBootApplication
public class TestApplication {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
/**
* We define our own datasource, otherwise we end up with Hikari one which for some lessons will
* throw an error (feature not supported)
*/
@Bean
@ConditionalOnProperty(prefix = "webgoat.start", name = "hsqldb", havingValue = "false")
@Primary
public DataSource dataSource(@Value("${spring.datasource.url}") String url) throws SQLException {
DriverManager.registerDriver(new JDBCDriver());
return new DriverManagerDataSource(url);
}
}

View File

@ -1,5 +1,7 @@
package org.owasp.webgoat.plugins;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.configuration.FluentConfiguration;
import org.junit.jupiter.api.BeforeEach;
import org.owasp.webgoat.i18n.Language;
import org.owasp.webgoat.i18n.PluginMessages;
@ -12,7 +14,9 @@ import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import javax.annotation.PostConstruct;
import java.util.Locale;
import java.util.function.Function;
import static org.mockito.Mockito.when;
@ -31,6 +35,8 @@ public abstract class LessonTest {
protected WebApplicationContext wac;
@Autowired
protected PluginMessages messages;
@Autowired
private Function<String, Flyway> flywayLessons;
@MockBean
protected WebSession webSession;
@ -43,4 +49,11 @@ public abstract class LessonTest {
when(language.getLocale()).thenReturn(Locale.getDefault());
}
@PostConstruct
public void createFlywayLessonTables() {
flywayLessons.apply("PUBLIC").migrate();
}
}

View File

@ -1,12 +1,18 @@
package org.owasp.webgoat.users;
import org.assertj.core.api.Assertions;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.configuration.FluentConfiguration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.function.Function;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ -17,11 +23,15 @@ class UserServiceTest {
private UserRepository userRepository;
@Mock
private UserTrackerRepository userTrackerRepository;
@Mock
private JdbcTemplate jdbcTemplate;
@Mock
private Function<String, Flyway> flywayLessons;
@Test
void shouldThrowExceptionWhenUserIsNotFound() {
when(userRepository.findByUsername(any())).thenReturn(null);
UserService userService = new UserService(userRepository, userTrackerRepository);
UserService userService = new UserService(userRepository, userTrackerRepository, jdbcTemplate, flywayLessons);
Assertions.assertThatThrownBy(() -> userService.loadUserByUsername("unknown")).isInstanceOf(UsernameNotFoundException.class);
}
}