This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 32b6e5c452 Fix from further review
32b6e5c452 is described below

commit 32b6e5c4525bd23355a852a05faf44c208b92c55
Author: remm <[email protected]>
AuthorDate: Fri Jul 10 18:25:14 2026 +0200

    Fix from further review
    
    Add a test for the minimal option (name, password), since I had
    forgotten this deployment option existed.
---
 .../catalina/users/DataSourceUserDatabase.java     | 67 ++++++++++++++--------
 .../apache/catalina/users/LocalStrings.properties  |  2 +-
 .../catalina/users/TestDataSourceUserDatabase.java | 43 ++++++++++++++
 3 files changed, 88 insertions(+), 24 deletions(-)

diff --git a/java/org/apache/catalina/users/DataSourceUserDatabase.java 
b/java/org/apache/catalina/users/DataSourceUserDatabase.java
index 6412161d18..56ed9bfb47 100644
--- a/java/org/apache/catalina/users/DataSourceUserDatabase.java
+++ b/java/org/apache/catalina/users/DataSourceUserDatabase.java
@@ -832,7 +832,7 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
                     return null;
                 }
 
-                if (userRoleTable != null && roleNameCol != null) {
+                if (isUserRoleStoreDefined()) {
                     Connection dbConnection = openConnection();
                     if (dbConnection == null) {
                         return null;
@@ -969,7 +969,7 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
         }
 
         ArrayList<Role> roles = new ArrayList<>();
-        if (userRoleTable != null && roleNameCol != null) {
+        if (isUserRoleStoreDefined()) {
             try (PreparedStatement stmt = 
dbConnection.prepareStatement(preparedUserRoles)) {
                 stmt.setString(1, userName);
                 try (ResultSet rs = stmt.executeQuery()) {
@@ -1052,13 +1052,13 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
         if (log.isDebugEnabled()) {
             // As there are lots of parameters to configure, log some debug to 
help out
             log.debug(sm.getString("dataSourceUserDatabase.features",
-                    Boolean.toString(userRoleTable != null && roleNameCol != 
null),
+                    Boolean.toString(isUserRoleStoreDefined()),
                     Boolean.toString(isRoleStoreDefined()), 
Boolean.toString(isGroupStoreDefined())));
         }
 
         if (!isUserStoreDefined()) {
             throw new 
IllegalArgumentException(sm.getString("dataSourceUserDatabase.noUserConfiguration",
-                    userTable, userNameCol, userCredCol, userRoleTable, 
roleNameCol));
+                    userTable, userNameCol, userCredCol));
         }
 
         dbWriteLock.lock();
@@ -1085,14 +1085,16 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
             temp.append(userTable);
             preparedAllUsers = temp.toString();
 
-            temp = new StringBuilder("SELECT ");
-            temp.append(roleNameCol);
-            temp.append(" FROM ");
-            temp.append(userRoleTable);
-            temp.append(" WHERE ");
-            temp.append(userNameCol);
-            temp.append(" = ?");
-            preparedUserRoles = temp.toString();
+            if (isUserRoleStoreDefined()) {
+                temp = new StringBuilder("SELECT ");
+                temp.append(roleNameCol);
+                temp.append(" FROM ");
+                temp.append(userRoleTable);
+                temp.append(" WHERE ");
+                temp.append(userNameCol);
+                temp.append(" = ?");
+                preparedUserRoles = temp.toString();
+            }
 
             if (isGroupStoreDefined()) {
                 temp = new StringBuilder("SELECT ");
@@ -1151,7 +1153,7 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
                 temp.append(" FROM ");
                 temp.append(roleTable);
                 preparedAllRoles = temp.toString();
-            } else if (userRoleTable != null && roleNameCol != null) {
+            } else if (isUserRoleStoreDefined()) {
                 // Validate roles existence from the user <-> roles table
                 temp = new StringBuilder("SELECT ");
                 temp.append(roleNameCol);
@@ -1239,6 +1241,14 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
             try {
                 dbConnection.setAutoCommit(false);
                 Exception exception = saveInternal(dbConnection);
+                // Commit all changes to the database
+                if (exception.getSuppressed().length == 0) {
+                    try {
+                        dbConnection.commit();
+                    } catch (SQLException e) {
+                        exception.addSuppressed(e);
+                    }
+                }
                 if (exception.getSuppressed().length > 0) {
                     // Some exception occurred so rollback everything
                     try {
@@ -1249,13 +1259,13 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
                     
log.error(sm.getString("dataSourceUserDatabase.exception"), exception);
                     throw exception;
                 }
-                // Commit all changes to the database
-                dbConnection.commit();
                 // Everything is committed successfully, we can now clear all 
un-persisted changes
-                removedRoles.clear();
-                if (isRoleStoreDefined()) {
-                    createdRoles.clear();
-                    modifiedRoles.clear();
+                if (isUserRoleStoreDefined()) {
+                    removedRoles.clear();
+                    if (isRoleStoreDefined()) {
+                        createdRoles.clear();
+                        modifiedRoles.clear();
+                    }
                 }
                 if (isGroupStoreDefined()) {
                     removedGroups.clear();
@@ -1380,7 +1390,7 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
                 }
             }
 
-        } else {
+        } else if (isUserRoleStoreDefined()) {
             // Only remove role from users
             tempRelationDelete = new StringBuilder("DELETE FROM ");
             tempRelationDelete.append(userRoleTable);
@@ -1526,7 +1536,7 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
 
         String userRoleRelation = null;
         String userRoleRelationDelete = null;
-        if (userRoleTable != null && roleNameCol != null) {
+        if (isUserRoleStoreDefined()) {
             tempRelation = new StringBuilder("INSERT INTO ");
             tempRelation.append(userRoleTable);
             tempRelation.append('(').append(userNameCol).append(", ");
@@ -1728,9 +1738,20 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
      * @return true when users are properly configured
      */
     protected boolean isUserStoreDefined() {
-        return userTable != null && userNameCol != null && userCredCol != null 
&& userRoleTable != null && roleNameCol != null;
+        return userTable != null && userNameCol != null && userCredCol != null;
     }
 
+
+    /**
+     * User role relationship storage.
+     *
+     * @return true when user roles relationship are properly configured
+     */
+    protected boolean isUserRoleStoreDefined() {
+        return userRoleTable != null && roleNameCol != null;
+    }
+
+
     /**
      * Only use groups if the tables are fully defined.
      *
@@ -1748,7 +1769,7 @@ public class DataSourceUserDatabase extends 
SparseUserDatabase {
      * @return true when roles are used
      */
     protected boolean isRoleStoreDefined() {
-        return roleTable != null && userRoleTable != null && roleNameCol != 
null;
+        return roleTable != null && isUserRoleStoreDefined();
     }
 
 
diff --git a/java/org/apache/catalina/users/LocalStrings.properties 
b/java/org/apache/catalina/users/LocalStrings.properties
index 902730208b..74812ef16c 100644
--- a/java/org/apache/catalina/users/LocalStrings.properties
+++ b/java/org/apache/catalina/users/LocalStrings.properties
@@ -15,7 +15,7 @@
 
 dataSourceUserDatabase.exception=Exception accessing the database
 dataSourceUserDatabase.features=DataSource UserDatabase features: User <-> 
Role [{0}], Roles [{1}], Groups [{2}]
-dataSourceUserDatabase.noUserConfiguration=DataSource UserDatabase has no 
properly configured user storage defined: userTable [{0}] userNameCol [{1}] 
userCredCol [{2}] userRoleTable [{3}] roleNameCol [{4}]
+dataSourceUserDatabase.noUserConfiguration=DataSource UserDatabase has no 
properly configured user storage defined: userTable [{0}] userNameCol [{1}] 
userCredCol [{2}]
 
 memoryUserDatabase.fileClose=Failed to close [{0}]
 memoryUserDatabase.fileDelete=Failed to delete [{0}]
diff --git a/test/org/apache/catalina/users/TestDataSourceUserDatabase.java 
b/test/org/apache/catalina/users/TestDataSourceUserDatabase.java
index 326bf45bd2..627f6e915b 100644
--- a/test/org/apache/catalina/users/TestDataSourceUserDatabase.java
+++ b/test/org/apache/catalina/users/TestDataSourceUserDatabase.java
@@ -31,6 +31,12 @@ import org.apache.catalina.startup.LoggingBaseTest;
 
 public class TestDataSourceUserDatabase extends LoggingBaseTest {
 
+    public static final String MINIMAL_SCHEMA =
+            "create table users (\n"
+            + "  user_name         varchar(15) not null primary key,\n"
+            + "  user_pass         varchar(15) not null\n"
+            + ");";
+
     public static final String SIMPLE_SCHEMA =
             "create table users (\n"
             + "  user_name         varchar(15) not null primary key,\n"
@@ -109,6 +115,43 @@ public class TestDataSourceUserDatabase extends 
LoggingBaseTest {
 
     private DerbyUserDatabase db;
 
+    @Test
+    public void testMinimalUserRoleDatabase()
+        throws Exception {
+        // Test functionality with the DataSourceRealm schema
+
+        db = new DerbyUserDatabase("minimal");
+        db.setReadonly(false);
+        db.setUserTable("users");
+        db.setUserNameCol("user_name");
+        db.setUserCredCol("user_pass");
+        db.open();
+        // First create the DB tables
+        Connection connection = db.getConnection();
+        for (String sql: MINIMAL_SCHEMA.split(";")) {
+            try (Statement statement = connection.createStatement()) {
+                statement.execute(sql);
+            }
+        }
+
+        Iterator<User> users = db.getUsers();
+        Assert.assertFalse("Some users found", users.hasNext());
+
+        User tomcatUser = db.createUser("tomcat", "password", "A new user");
+        db.save();
+
+        users = db.getUsers();
+        Assert.assertTrue("No users found", users.hasNext());
+        tomcatUser = users.next();
+        Assert.assertTrue("Wrong user", 
tomcatUser.getUsername().equals("tomcat"));
+        Assert.assertTrue("Wrong password", 
tomcatUser.getPassword().equals("password"));
+        // Cannot save the user full name
+        Assert.assertNull("Wrong user fullname", tomcatUser.getFullName());
+
+        db.close();
+
+    }
+
     @Test
     public void testBasicUserRoleDatabase()
         throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to