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

mneethiraj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 9bf7a9364 RANGER-5667: fixes in support for actions in Ozone policies 
(#1053)
9bf7a9364 is described below

commit 9bf7a9364f0f646b8d5d8e1a8244ca4cdf7a797f
Author: fmorg-git <[email protected]>
AuthorDate: Wed Jul 8 18:28:12 2026 -0700

    RANGER-5667: fixes in support for actions in Ozone policies (#1053)
---
 .../conditionevaluator/RangerActionMatcher.java    |  6 ++--
 .../plugin/util/RangerActionListMatcher.java       | 39 ++++++++++++----------
 .../RangerActionMatcherTest.java                   |  8 ++---
 .../plugin/util/RangerActionListMatcherTest.java   | 32 +++++++++++++++---
 .../test_inline_policies_ozone.json                |  4 +--
 .../authorizer/TestRangerOzoneAuthorizer.java      |  6 ++--
 .../src/hooks/usePruneStaleConditions.js           |  2 +-
 7 files changed, 62 insertions(+), 35 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcher.java
index 31d522899..9342ea68b 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcher.java
@@ -26,7 +26,7 @@
 public class RangerActionMatcher extends RangerAbstractConditionEvaluator {
     private static final Logger LOG = 
LoggerFactory.getLogger(RangerActionMatcher.class);
 
-    private RangerActionListMatcher actionMatcher = new 
RangerActionListMatcher(null);
+    private RangerActionListMatcher actionMatcher;
 
     @Override
     public void init() {
@@ -43,7 +43,9 @@ public void init() {
     public boolean isMatched(final RangerAccessRequest request) {
         LOG.debug("==> RangerActionMatcher.isMatched({})", request);
 
-        final boolean ret = actionMatcher.isMatch(request != null ? 
request.getAction() : null);
+        final RangerActionListMatcher matcher = actionMatcher;
+        final String                  action  = request != null ? 
request.getAction() : null;
+        final boolean                 ret     = matcher == null || 
matcher.isMatch(action);
 
         LOG.debug("<== RangerActionMatcher.isMatched({}): {}", request, ret);
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerActionListMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerActionListMatcher.java
index 507de29cf..db7807b70 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerActionListMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerActionListMatcher.java
@@ -68,6 +68,10 @@ public RangerActionListMatcher(Collection<String> actions) {
                     exactActions.add(action.toLowerCase(Locale.ROOT));
                 }
             }
+
+            if (!allowAny && exactActions.isEmpty() && 
tempPrefixList.isEmpty()) {
+                allowAny = true;
+            }
         }
 
         this.allowAnyAction = allowAny;
@@ -95,28 +99,27 @@ public RangerActionListMatcher(Collection<String> actions) {
     }
 
     public boolean isMatch(String requestAction) {
-        boolean ret = allowAnyAction;
+        if (allowAnyAction) {
+            return true;
+        }
 
-        if (!ret) {
-            // if action is not available, don't enforce action restrictions
-            if (StringUtils.isBlank(requestAction)) {
-                ret = true;
-            } else {
-                final String actionLower = 
requestAction.toLowerCase(Locale.ROOT);
+        // Action restrictions exist; missing request action is not a match.
+        if (StringUtils.isBlank(requestAction)) {
+            return false;
+        }
 
-                if (exactActions.contains(actionLower)) {
-                    ret = true;
-                } else {
-                    for (String prefix : prefixActions) {
-                        if (actionLower.startsWith(prefix)) {
-                            ret = true;
-                            break;
-                        }
-                    }
-                }
+        final String actionLower = requestAction.toLowerCase(Locale.ROOT);
+
+        if (exactActions.contains(actionLower)) {
+            return true;
+        }
+
+        for (String prefix : prefixActions) {
+            if (actionLower.startsWith(prefix)) {
+                return true;
             }
         }
 
-        return ret;
+        return false;
     }
 }
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcherTest.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcherTest.java
index 5b617308f..5e23c0f55 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcherTest.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerActionMatcherTest.java
@@ -55,12 +55,12 @@ void testWildcardMatchesAll() {
     }
 
     @Test
-    void testNoRequestActionDoesNotEnforce() {
+    void testNoRequestActionDoesNotMatchWhenActionsSpecified() {
         final RangerActionMatcher matcher = createMatcher(new String[] 
{"PutObject"});
 
-        assertTrue(matcher.isMatched(createRequest(null)));
-        assertTrue(matcher.isMatched(createRequest("")));
-        assertTrue(matcher.isMatched(createRequest("   ")));
+        assertFalse(matcher.isMatched(createRequest(null)));
+        assertFalse(matcher.isMatched(createRequest("")));
+        assertFalse(matcher.isMatched(createRequest("   ")));
     }
 
     @Test
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/util/RangerActionListMatcherTest.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/util/RangerActionListMatcherTest.java
index 70ef452e5..b6bdfebf9 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/util/RangerActionListMatcherTest.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/util/RangerActionListMatcherTest.java
@@ -166,14 +166,25 @@ void testDuplicatePrefixes() {
     }
 
     @Test
-    void testBlankRequestActionBypassesRestriction() {
+    void testBlankRequestActionDoesNotMatchWhenActionsSpecified() {
         final RangerActionListMatcher matcher = new RangerActionListMatcher(
                 Arrays.asList("PutObject"));
 
-        // When no action is provided, action restrictions are not enforced
-        assertTrue(matcher.isMatch(null));
-        assertTrue(matcher.isMatch(""));
-        assertTrue(matcher.isMatch("   "));
+        // When action restrictions exist, missing action is not a match
+        assertFalse(matcher.isMatch(null));
+        assertFalse(matcher.isMatch(""));
+        assertFalse(matcher.isMatch("   "));
+    }
+
+    @Test
+    void testBlankRequestActionStillMatchesWhenNoActionsSpecified() {
+        final RangerActionListMatcher matcherNull = new 
RangerActionListMatcher(null);
+        assertTrue(matcherNull.isMatch(null));
+        assertTrue(matcherNull.isMatch(""));
+
+        final RangerActionListMatcher matcherEmpty = new 
RangerActionListMatcher(Collections.emptyList());
+        assertTrue(matcherEmpty.isMatch(null));
+        assertTrue(matcherEmpty.isMatch("   "));
     }
 
     @Test
@@ -185,6 +196,17 @@ void testBlankEntriesInActionsIgnored() {
         assertFalse(matcher.isMatch("GetObject"));
     }
 
+    @Test
+    void testAllBlankActionsMatchAll() {
+        final RangerActionListMatcher matcher = new RangerActionListMatcher(
+                Arrays.asList("", "  ", "   "));
+
+        assertTrue(matcher.isMatch("PutObject"));
+        assertTrue(matcher.isMatch("GetObject"));
+        assertTrue(matcher.isMatch(null));
+        assertTrue(matcher.isMatch("   "));
+    }
+
     @Test
     void testPrefixWildcardCaseInsensitive() {
         final RangerActionListMatcher matcher = new 
RangerActionListMatcher(Arrays.asList("Put*"));
diff --git 
a/agents-common/src/test/resources/policyevaluator/test_inline_policies_ozone.json
 
b/agents-common/src/test/resources/policyevaluator/test_inline_policies_ozone.json
index 4c185453d..1aa81f63e 100644
--- 
a/agents-common/src/test/resources/policyevaluator/test_inline_policies_ozone.json
+++ 
b/agents-common/src/test/resources/policyevaluator/test_inline_policies_ozone.json
@@ -295,7 +295,7 @@
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": -1 }
     },
-    { "name": "ALLOW 'write s3v/iceberg/key2;' for user=svc-etl; no action in 
request bypasses action restriction",
+    { "name": "DENY 'write s3v/iceberg/key2;' for user=svc-etl; no action in 
request does not satisfy action restriction",
       "request": {
         "resource": { "elements": { "volume": "s3v", "bucket": "iceberg", 
"key": "key2" } }, "user": "svc-etl", "accessType": "write",
         "inlinePolicy": { "grantor":  "r:data-all-access", "mode": "INLINE",
@@ -304,7 +304,7 @@
           ]
         }
       },
-      "result": { "isAudited": true, "isAllowed": true, "policyId": -1 }
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
     },
     { "name": "ALLOW 'read s3v/iceberg/key2;' for user=svc-etl; 
action=GetObject matches second entry in multi-action grant",
       "request": {
diff --git 
a/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
 
b/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
index 3cfc282a4..a715e9c6f 100644
--- 
a/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
+++ 
b/plugin-ozone/src/test/java/org/apache/ranger/authorization/ozone/authorizer/TestRangerOzoneAuthorizer.java
@@ -262,7 +262,7 @@ public void testCheckAccessWithS3Action() throws Exception {
         assertFalse(ozoneAuthorizer.checkAccess(key1, ctxWriteGetObject),
                 "session-policy should deny write on key1 when S3 action is 
GetObject (not in grant)");
 
-        // No S3 action specified should bypass action restriction (allow 
through)
+        // No S3 action specified should be denied when the grant has 
S3-action restrictions
         RequestContext ctxWriteNoAction = reqCtxBuilder
                 .setAclRights(IAccessAuthorizer.ACLType.WRITE)
                 .setRecursiveAccessCheck(false)
@@ -270,7 +270,7 @@ public void testCheckAccessWithS3Action() throws Exception {
                 .setS3Action(null)
                 .build();
 
-        assertTrue(ozoneAuthorizer.checkAccess(key1, ctxWriteNoAction),
-                "session-policy should allow write on key1 when no S3 action 
is specified (bypass)");
+        assertFalse(ozoneAuthorizer.checkAccess(key1, ctxWriteNoAction),
+                "session-policy should deny write on key1 when no S3 action is 
specified and grant has S3 actions");
     }
 }
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/hooks/usePruneStaleConditions.js
 
b/security-admin/src/main/webapp/react-webapp/src/hooks/usePruneStaleConditions.js
index 35cdcc8fb..6cb1cb0ed 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/hooks/usePruneStaleConditions.js
+++ 
b/security-admin/src/main/webapp/react-webapp/src/hooks/usePruneStaleConditions.js
@@ -70,7 +70,7 @@ export const usePruneStaleConditions = ({
     const newItems = [...items];
 
     newItems.forEach((item, index) => {
-      if (!item.conditions) {
+      if (!item?.conditions) {
         return;
       }
 

Reply via email to