This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new db919ff991 Ensure RealmBase finds all matching extension based
constraints
db919ff991 is described below
commit db919ff9912b4d61d1b702a1342b8bde39270031
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Apr 22 12:05:25 2026 +0100
Ensure RealmBase finds all matching extension based constraints
---
java/org/apache/catalina/realm/RealmBase.java | 18 +++--
test/org/apache/catalina/realm/TestRealmBase.java | 82 ++++++++++++++++++++++
test/org/apache/tomcat/unittest/TesterRequest.java | 10 +++
webapps/docs/changelog.xml | 4 ++
4 files changed, 104 insertions(+), 10 deletions(-)
diff --git a/java/org/apache/catalina/realm/RealmBase.java
b/java/org/apache/catalina/realm/RealmBase.java
index ae9108f2ef..bb3771f231 100644
--- a/java/org/apache/catalina/realm/RealmBase.java
+++ b/java/org/apache/catalina/realm/RealmBase.java
@@ -666,8 +666,6 @@ public abstract class RealmBase extends LifecycleMBeanBase
implements Realm {
constraints[i].included(uri, method));
}
- boolean matched = false;
- int pos = -1;
for (int j = 0; j < collection.length; j++) {
String[] patterns = collection[j].findPatterns();
@@ -677,6 +675,7 @@ public abstract class RealmBase extends LifecycleMBeanBase
implements Realm {
continue;
}
+ boolean matched = false;
for (int k = 0; k < patterns.length && !matched; k++) {
String pattern = patterns[k];
if (pattern.startsWith("*.")) {
@@ -686,19 +685,18 @@ public abstract class RealmBase extends
LifecycleMBeanBase implements Realm {
uri.length() - dot == pattern.length() - 1) {
if (pattern.regionMatches(1, uri, dot,
uri.length() - dot)) {
matched = true;
- pos = j;
}
}
}
}
- }
- if (matched) {
- found = true;
- if (collection[pos].findMethod(method)) {
- if (results == null) {
- results = new ArrayList<>();
+ if (matched) {
+ found = true;
+ if (collection[j].findMethod(method)) {
+ if (results == null) {
+ results = new ArrayList<>();
+ }
+ results.add(constraints[i]);
}
- results.add(constraints[i]);
}
}
}
diff --git a/test/org/apache/catalina/realm/TestRealmBase.java
b/test/org/apache/catalina/realm/TestRealmBase.java
index d49676e42e..06d00b81ff 100644
--- a/test/org/apache/catalina/realm/TestRealmBase.java
+++ b/test/org/apache/catalina/realm/TestRealmBase.java
@@ -790,4 +790,86 @@ public class TestRealmBase {
Assert.assertFalse(mapRealm.hasResourcePermission(
request, response, constraintsDelete, null));
}
+
+
+ @Test
+ public void testUncoveredMethods() throws IOException {
+ // Create a constraint for ROLE1
+ SecurityConstraint constraint = new SecurityConstraint();
+ constraint.addAuthRole(ROLE1);
+ // Add a collection for GET
+ SecurityCollection getCollection = new SecurityCollection();
+ getCollection.addMethod(Method.GET);
+ getCollection.addPatternDecoded("*.html");
+ constraint.addCollection(getCollection);
+ // Add a collection for POST
+ SecurityCollection postCollection = new SecurityCollection();
+ postCollection.addMethod(Method.POST);
+ postCollection.addPatternDecoded("*.html");
+ constraint.addCollection(postCollection);
+
+ TesterMapRealm mapRealm = new TesterMapRealm();
+
+ // Set up the mock request and response
+ TesterRequest request = new TesterRequest();
+ Response response = new TesterResponse();
+ Context context = request.getContext();
+ context.addSecurityRole(ROLE1);
+ context.addSecurityRole(ROLE2);
+ request.getMappingData().context = context;
+
+ // Create the principals
+ List<String> userRoles1 = new ArrayList<>();
+ userRoles1.add(ROLE1);
+ GenericPrincipal gp1 = new GenericPrincipal(USER1, userRoles1);
+
+ List<String> userRoles2 = new ArrayList<>();
+ userRoles2.add(ROLE2);
+ GenericPrincipal gp2 = new GenericPrincipal(USER2, userRoles2);
+
+ List<String> userRoles99 = new ArrayList<>();
+ GenericPrincipal gp99 = new GenericPrincipal(USER99, userRoles99);
+
+ // Add the constraint to the context
+ context.addConstraint(constraint);
+
+
+ // Only user1 should be able to perform a GET
+ request.setMethod(Method.GET);
+
+ SecurityConstraint[] constraintsGet =
+ mapRealm.findSecurityConstraints(request, context);
+
+ request.setUserPrincipal(null);
+ Assert.assertFalse(mapRealm.hasResourcePermission(
+ request, response, constraintsGet, null));
+ request.setUserPrincipal(gp1);
+ Assert.assertTrue(mapRealm.hasResourcePermission(
+ request, response, constraintsGet, null));
+ request.setUserPrincipal(gp2);
+ Assert.assertFalse(mapRealm.hasResourcePermission(
+ request, response, constraintsGet, null));
+ request.setUserPrincipal(gp99);
+ Assert.assertFalse(mapRealm.hasResourcePermission(
+ request, response, constraintsGet, null));
+
+ // Only user1 should be able to perform a POST
+ request.setMethod(Method.POST);
+
+ SecurityConstraint[] constraintsPost =
+ mapRealm.findSecurityConstraints(request, context);
+
+ request.setUserPrincipal(null);
+ Assert.assertFalse(mapRealm.hasResourcePermission(
+ request, response, constraintsPost, null));
+ request.setUserPrincipal(gp1);
+ Assert.assertTrue(mapRealm.hasResourcePermission(
+ request, response, constraintsPost, null));
+ request.setUserPrincipal(gp2);
+ Assert.assertFalse(mapRealm.hasResourcePermission(
+ request, response, constraintsPost, null));
+ request.setUserPrincipal(gp99);
+ Assert.assertFalse(mapRealm.hasResourcePermission(
+ request, response, constraintsPost, null));
+ }
}
diff --git a/test/org/apache/tomcat/unittest/TesterRequest.java
b/test/org/apache/tomcat/unittest/TesterRequest.java
index 8de33c7e9b..7635ef6d7d 100644
--- a/test/org/apache/tomcat/unittest/TesterRequest.java
+++ b/test/org/apache/tomcat/unittest/TesterRequest.java
@@ -31,6 +31,7 @@ import javax.servlet.SessionTrackingMode;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Request;
import org.apache.catalina.session.StandardSession;
+import org.apache.tomcat.util.buf.MessageBytes;
public class TesterRequest extends Request {
@@ -81,6 +82,15 @@ public class TesterRequest extends Request {
return "/level1/level2/foo.html";
}
+
+ @Override
+ public MessageBytes getRequestPathMB() {
+ MessageBytes result = MessageBytes.newInstance();
+ result.setString(getRequestURI());
+ return result;
+ }
+
+
@Override
public String getDecodedRequestURI() {
// Decoding not required
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 73ccc8c9e3..ab18831560 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -172,6 +172,10 @@
<fix>
Correct the handling of invalid users with DIGEST authentication.
(markt)
</fix>
+ <fix>
+ Ensure <code>RealmBase</code> finds all matching extension based
+ security constraints. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]