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;
}