diff --git a/pom.xml b/pom.xml
index 8cbfd57a5..59d176c27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -140,6 +140,11 @@
activation
1.1
+
+ com.h2database
+ h2
+ 1.4.187
+
axis
axis
diff --git a/src/main/java/org/owasp/webgoat/session/Role.java b/src/main/java/org/owasp/webgoat/session/Role.java
new file mode 100644
index 000000000..0b7310ccd
--- /dev/null
+++ b/src/main/java/org/owasp/webgoat/session/Role.java
@@ -0,0 +1,13 @@
+package org.owasp.webgoat.session;
+
+public class Role {
+ private String rolename;
+
+ public Role(String rolename) {
+ this.rolename = rolename;
+ }
+
+ public String getRolename() {
+ return this.rolename;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/owasp/webgoat/session/User.java b/src/main/java/org/owasp/webgoat/session/User.java
new file mode 100644
index 000000000..ff9940d86
--- /dev/null
+++ b/src/main/java/org/owasp/webgoat/session/User.java
@@ -0,0 +1,26 @@
+package org.owasp.webgoat.session;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class User {
+ private String username;
+ private ArrayList roles;
+
+ public User(String username) {
+ this.username = username;
+ this.roles = new ArrayList();
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public Iterator getRoles() {
+ return roles.iterator();
+ }
+
+ public void addRole(String rolename) {
+ roles.add(new Role(rolename));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/owasp/webgoat/session/UserDatabase.java b/src/main/java/org/owasp/webgoat/session/UserDatabase.java
new file mode 100644
index 000000000..d383c7e79
--- /dev/null
+++ b/src/main/java/org/owasp/webgoat/session/UserDatabase.java
@@ -0,0 +1,214 @@
+package org.owasp.webgoat.session;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.File;
+
+class UserDatabase {
+ private Connection userDB;
+ private final String USER_DB_URI = "jdbc:h2:" + System.getProperty("user.dir") + File.separator + "UserDatabase";
+
+ private final String CREATE_USERS_TABLE = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL UNIQUE);";
+ private final String CREATE_ROLES_TABLE = "CREATE TABLE IF NOT EXISTS roles (id INTEGER PRIMARY KEY AUTO_INCREMENT, rolename VARCHAR(255) NOT NULL UNIQUE);";
+ private final String CREATE_USER_ROLES_TABLE = "CREATE TABLE IF NOT EXISTS user_roles (id INTEGER PRIMARY KEY AUTO_INCREMENT, user_id INTEGER NOT NULL, role_id INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (role_id) REFERENCES roles(id));";
+ private final String ADD_DEFAULT_USERS = "INSERT INTO users (username) VALUES ('webgoat'),('basic'),('guest');";
+ private final String ADD_DEFAULT_ROLES = "INSERT INTO roles (rolename) VALUES ('webgoat_basic'),('webgoat_admin'),('webgoat_user');";
+ private final String ADD_ROLE_TO_USER = "INSERT INTO user_roles (user_id, role_id) SELECT users.id, roles.id FROM users, roles WHERE users.username = ? AND roles.rolename = ?;";
+
+ private final String QUERY_ALL_USERS = "SELECT username FROM users;";
+ private final String QUERY_ALL_ROLES_FOR_USERNAME = "SELECT rolename FROM roles, user_roles, users WHERE roles.id = user_roles.role_id AND user_roles.user_id = users.id AND users.username = ?;";
+ private final String QUERY_TABLE_COUNT = "SELECT count(id) AS count FROM table;";
+
+ private final String DELETE_ALL_ROLES_FOR_USER = "DELETE FROM user_roles WHERE user_id IN (SELECT id FROM users WHERE username = ?);";
+ private final String DELETE_USER = "DELETE FROM users WHERE username = ?;";
+
+ public UserDatabase() {
+ createDefaultTables();
+ if (getTableCount("users") <= 0) {
+ createDefaultUsers();
+ }
+ if (getTableCount("roles") <= 0) {
+ createDefaultRoles();
+ }
+ if (getTableCount("user_roles") <= 0) {
+ addDefaultRolesToDefaultUsers();
+ }
+ }
+
+ public boolean open() {
+ try {
+ if (userDB == null || userDB.isClosed()) {
+ Class.forName("org.h2.Driver");
+ userDB = DriverManager.getConnection(USER_DB_URI, "webgoat_admin", "");
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean close() {
+ try {
+ if (userDB != null && !userDB.isClosed())
+ userDB.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public int getTableCount(String tableName) {
+ int count = 0;
+ try {
+ open();
+ Statement statement = userDB.createStatement();
+ ResultSet countResult = statement.executeQuery(QUERY_TABLE_COUNT.replace("table", tableName));
+ if (countResult.next()) {
+ count = countResult.getInt("count");
+ }
+ countResult.close();
+ statement.close();
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ count = -1;
+ }
+ return count;
+ }
+
+ public Iterator getUsers() {
+ ArrayList users = new ArrayList();
+ User currentUser;
+ ResultSet userResults, roleResults;
+
+ try {
+ open();
+ Statement statement = userDB.createStatement();
+ PreparedStatement rolesForUsers = userDB.prepareStatement(QUERY_ALL_ROLES_FOR_USERNAME);
+
+ userResults = statement.executeQuery(QUERY_ALL_USERS);
+ while (userResults.next()) {
+ currentUser = new User(userResults.getString("username"));
+ rolesForUsers.setString(1, currentUser.getUsername());
+ roleResults = rolesForUsers.executeQuery();
+ while (roleResults.next()) {
+ currentUser.addRole(roleResults.getString("rolename"));
+ }
+ roleResults.close();
+ }
+ rolesForUsers.close();
+ userResults.close();
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ users = new ArrayList();
+ }
+
+ return users.iterator();
+ }
+
+ public boolean addRoleToUser(String username, String rolename) {
+ try {
+ open();
+ PreparedStatement statement = userDB.prepareStatement(ADD_ROLE_TO_USER);
+ statement.setString(1, username);
+ statement.setString(2, rolename);
+ statement.execute();
+ statement.close();
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean removeUser(User user) {
+ return removeUser(user.getUsername());
+ }
+
+ public boolean removeUser(String username) {
+ try {
+ open();
+
+ PreparedStatement deleteUserRoles = userDB.prepareStatement(DELETE_ALL_ROLES_FOR_USER);
+ PreparedStatement deleteUser = userDB.prepareStatement(DELETE_USER);
+
+ deleteUserRoles.setString(1, username);
+ deleteUser.setString(1, username);
+
+ deleteUserRoles.execute();
+ deleteUser.execute();
+
+ deleteUserRoles.close();
+ deleteUser.close();
+
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * Methods to initialise the default state of the database.
+ */
+
+ private boolean createDefaultTables() {
+ try {
+ open();
+ Statement statement = userDB.createStatement();
+ statement.execute(CREATE_USERS_TABLE);
+ statement.execute(CREATE_ROLES_TABLE);
+ statement.execute(CREATE_USER_ROLES_TABLE);
+ statement.close();
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ private boolean createDefaultUsers() {
+ try {
+ open();
+ Statement statement = userDB.createStatement();
+ statement.execute(ADD_DEFAULT_USERS);
+ statement.close();
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ private boolean createDefaultRoles() {
+ try {
+ open();
+ Statement statement = userDB.createStatement();
+ statement.execute(ADD_DEFAULT_ROLES);
+ statement.close();
+ close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ private void addDefaultRolesToDefaultUsers() {
+ addRoleToUser("webgoat", "webgoat_admin");
+ addRoleToUser("basic", "webgoat_user");
+ addRoleToUser("basic", "webgoat_basic");
+ addRoleToUser("guest", "webgoat_user");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/owasp/webgoat/session/UserTracker.java b/src/main/java/org/owasp/webgoat/session/UserTracker.java
index ebafe60b6..5ef2004ea 100644
--- a/src/main/java/org/owasp/webgoat/session/UserTracker.java
+++ b/src/main/java/org/owasp/webgoat/session/UserTracker.java
@@ -6,9 +6,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import org.apache.catalina.Role;
-import org.apache.catalina.User;
-import org.apache.catalina.users.MemoryUserDatabase;
/***************************************************************************************************
@@ -51,7 +48,7 @@ public class UserTracker
private static HashMap> storage = new HashMap>();
- private static MemoryUserDatabase usersDB = new MemoryUserDatabase();
+ private static UserDatabase usersDB = new UserDatabase();
/**
* Constructor for the UserTracker object