Fix Bug: Match All Tags giving a NPE with the resource doesn't have tags (#22937)

(cherry picked from commit 5c76e78ff56964c0a4bba6e783fc1bf62a3ec2a4)
This commit is contained in:
Ram Narayan Balaji 2025-08-14 18:46:39 +05:30 committed by Ram Narayan Balaji
parent e07d4dcf07
commit 274dc0882f
2 changed files with 34 additions and 0 deletions

View File

@ -110,6 +110,10 @@ public class RuleEvaluator {
return false;
}
List<TagLabel> tags = resourceContext.getTags();
if (nullOrEmpty(tags)) {
LOG.debug("No Tags found for resource");
return false;
}
LOG.debug(
"matchAllTags {} resourceTags {}",
Arrays.toString(tagFQNs),

View File

@ -1,6 +1,7 @@
package org.openmetadata.service.security.policyevaluator;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@ -138,6 +139,8 @@ class RuleEvaluatorTest {
Mockito.when(dataProductRepository.getEntityType()).thenReturn(Entity.DATA_PRODUCT);
Mockito.when(dataProductRepository.isSupportsOwners()).thenReturn(Boolean.TRUE);
Entity.registerEntity(DataProduct.class, Entity.DATA_PRODUCT, dataProductRepository);
Mockito.when(dataProductRepository.getParentEntity(any(DataProduct.class), anyString()))
.thenReturn(null); // DataProduct doesn't have direct parent, should use domains
user = new User().withId(UUID.randomUUID()).withName("user");
ownerUser = new User().withId(UUID.randomUUID()).withName("owner");
@ -328,6 +331,33 @@ class RuleEvaluatorTest {
assertTrue(evaluateExpression("!matchAllTags('tag4')"));
}
@Test
void test_matchAllTags_withNullTags() {
// Test the scenario where getTags() returns null (e.g., due to deny policies)
// Set table tags to null to simulate the deny policy scenario
table.setTags(null);
// Create a mock ResourceContext that returns null for getTags()
ResourceContext<?> nullTagsResourceContext = Mockito.spy(resourceContext);
Mockito.when(nullTagsResourceContext.getTags()).thenReturn(null);
// Create RuleEvaluator with the mock context
RuleEvaluator ruleEvaluator = new RuleEvaluator(null, subjectContext, nullTagsResourceContext);
EvaluationContext testEvaluationContext = new StandardEvaluationContext(ruleEvaluator);
// Test that matchAllTags handles null tags gracefully without throwing NPE
// Before the fix, this would throw: "Cannot invoke \"java.util.List.toArray()\" because
// \"tags\" is null"
Boolean result =
parseExpression("matchAllTags('tag1', 'tag2')")
.getValue(testEvaluationContext, Boolean.class);
assertNotEquals(Boolean.TRUE, result, "matchAllTags should return false when tags is null");
// Test with single tag
result = parseExpression("matchAllTags('tag1')").getValue(testEvaluationContext, Boolean.class);
assertNotEquals(Boolean.TRUE, result, "matchAllTags should return false when tags is null");
}
@Test
void test_matchAnyTag() {
table.withTags(getTags("tag1", "tag2", "tag3"));