diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerAbstractConditionEvaluator.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerAbstractConditionEvaluator.java new file mode 100644 index 0000000000..2f743bcea8 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerAbstractConditionEvaluator.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.Mockito.mock; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAbstractConditionEvaluator { + @Test + public void test01_settersAndAlwaysMatchPaths() { + RangerSimpleMatcher matcher = new RangerSimpleMatcher(); + + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + matcher.setServiceDef(serviceDef); + + RangerPolicyItemCondition condition = new RangerPolicyItemCondition("__simple", null); + matcher.setPolicyItemCondition(condition); + matcher.setConditionDef(null); + matcher.init(); + + Assertions.assertEquals(condition, matcher.getPolicyItemCondition()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerAccessedFromClusterConditions.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerAccessedFromClusterConditions.java new file mode 100644 index 0000000000..df94276104 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerAccessedFromClusterConditions.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.Collections; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAccessedFromClusterConditions { + @Test + public void test01_fromCluster_withEmptyList_isAlwaysTrue() { + RangerAccessedFromClusterCondition evaluator = new RangerAccessedFromClusterCondition(); + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Collections.emptyList()); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + RangerAccessRequest req = mock(RangerAccessRequest.class); + Assertions.assertTrue(evaluator.isMatched(req)); + + Assertions.assertTrue(evaluator.isMatched(req)); + } + + @Test + public void test02_fromCluster_withValues_matchesOnlyIfContained() { + RangerAccessedFromClusterCondition evaluator = new RangerAccessedFromClusterCondition(); + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("c1", "c2")); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + RangerAccessRequest req = mock(RangerAccessRequest.class); + when(req.getClusterName()).thenReturn("c2"); + Assertions.assertTrue(evaluator.isMatched(req)); + when(req.getClusterName()).thenReturn("c3"); + Assertions.assertFalse(evaluator.isMatched(req)); + } + + @Test + public void test03_notFromCluster_withEmptyList_alwaysTrue() { + RangerAccessedNotFromClusterCondition evaluator = new RangerAccessedNotFromClusterCondition(); + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Collections.emptyList()); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + RangerAccessRequest req = mock(RangerAccessRequest.class); + Assertions.assertTrue(evaluator.isMatched(req)); + } + + @Test + public void test04_notFromCluster_withValues_trueWhenNotContained() { + RangerAccessedNotFromClusterCondition evaluator = new RangerAccessedNotFromClusterCondition(); + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("c1", "c2")); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + RangerAccessRequest req = mock(RangerAccessRequest.class); + when(req.getClusterName()).thenReturn("c3"); + Assertions.assertTrue(evaluator.isMatched(req)); + when(req.getClusterName()).thenReturn("c1"); + Assertions.assertFalse(evaluator.isMatched(req)); + } + + @Test + public void test05_fromClusterType_withValues() { + RangerAccessedFromClusterTypeCondition evaluator = new RangerAccessedFromClusterTypeCondition(); + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("onprem", "cloud")); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + RangerAccessRequest req = mock(RangerAccessRequest.class); + when(req.getClusterType()).thenReturn("cloud"); + Assertions.assertTrue(evaluator.isMatched(req)); + when(req.getClusterType()).thenReturn("edge"); + Assertions.assertFalse(evaluator.isMatched(req)); + } + + @Test + public void test06_notFromClusterType_withValues() { + RangerAccessedNotFromClusterTypeCondition evaluator = new RangerAccessedNotFromClusterTypeCondition(); + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("onprem", "cloud")); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + RangerAccessRequest req = mock(RangerAccessRequest.class); + when(req.getClusterType()).thenReturn("edge"); + Assertions.assertTrue(evaluator.isMatched(req)); + when(req.getClusterType()).thenReturn("cloud"); + Assertions.assertFalse(evaluator.isMatched(req)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerContextAttributeValueConditions.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerContextAttributeValueConditions.java new file mode 100644 index 0000000000..2c35649a5f --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerContextAttributeValueConditions.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerContextAttributeValueConditions { + @Test + public void test01_inCondition_attributeMissing_returnsTrue() { + RangerContextAttributeValueInCondition evaluator = new RangerContextAttributeValueInCondition(); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.singletonMap("attributeName", "site")); + evaluator.setConditionDef(conditionDef); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("10", "20")); + evaluator.setPolicyItemCondition(condition); + + evaluator.init(); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getContext()).thenReturn(new HashMap<>()); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + + @Test + public void test02_inCondition_attributePresent_withMatch_returnsTrue() { + RangerContextAttributeValueInCondition evaluator = new RangerContextAttributeValueInCondition(); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.singletonMap("attributeName", "dept")); + evaluator.setConditionDef(conditionDef); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("ENGG", "PROD")); + evaluator.setPolicyItemCondition(condition); + + evaluator.init(); + + Map ctx = new HashMap<>(); + ctx.put("dept", "ENGG"); + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getContext()).thenReturn(ctx); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + + @Test + public void test03_inCondition_attributePresent_noMatch_returnsFalse() { + RangerContextAttributeValueInCondition evaluator = new RangerContextAttributeValueInCondition(); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.singletonMap("attributeName", "dept")); + evaluator.setConditionDef(conditionDef); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("ENGG", "PROD")); + evaluator.setPolicyItemCondition(condition); + + evaluator.init(); + + Map ctx = new HashMap<>(); + ctx.put("dept", "SALES"); + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getContext()).thenReturn(ctx); + + Assertions.assertFalse(evaluator.isMatched(request)); + } + + @Test + public void test04_notInCondition_attributeMissing_returnsTrue() { + RangerContextAttributeValueNotInCondition evaluator = new RangerContextAttributeValueNotInCondition(); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.singletonMap("attributeName", "site")); + evaluator.setConditionDef(conditionDef); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("10", "20")); + evaluator.setPolicyItemCondition(condition); + + evaluator.init(); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getContext()).thenReturn(new HashMap<>()); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + + @Test + public void test05_notInCondition_attributePresent_withMatch_returnsFalse() { + RangerContextAttributeValueNotInCondition evaluator = new RangerContextAttributeValueNotInCondition(); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.singletonMap("attributeName", "dept")); + evaluator.setConditionDef(conditionDef); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("ENGG", "PROD")); + evaluator.setPolicyItemCondition(condition); + + evaluator.init(); + + Map ctx = new HashMap<>(); + ctx.put("dept", "PROD"); + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getContext()).thenReturn(ctx); + + Assertions.assertFalse(evaluator.isMatched(request)); + } + + @Test + public void test06_notInCondition_attributePresent_noMatch_returnsTrue() { + RangerContextAttributeValueNotInCondition evaluator = new RangerContextAttributeValueNotInCondition(); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.singletonMap("attributeName", "dept")); + evaluator.setConditionDef(conditionDef); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Arrays.asList("ENGG", "PROD")); + evaluator.setPolicyItemCondition(condition); + + evaluator.init(); + + Map ctx = new HashMap<>(); + ctx.put("dept", "SALES"); + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getContext()).thenReturn(ctx); + + Assertions.assertTrue(evaluator.isMatched(request)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerHiveResourcesAccessConditions.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerHiveResourcesAccessConditions.java new file mode 100644 index 0000000000..145c3fd812 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerHiveResourcesAccessConditions.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl; +import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil; +import org.apache.ranger.plugin.util.RangerAccessRequestUtil; +import org.apache.ranger.plugin.util.RangerRequestedResources; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerHiveResourcesAccessConditions { + @Test + public void test01_accessedTogether_initialized_and_matchesWhenNotMutuallyExcluded() throws Exception { + RangerHiveResourcesAccessedTogetherCondition evaluator = new RangerHiveResourcesAccessedTogetherCondition(); + + RangerServiceDef hiveDef = EmbeddedServiceDefsUtil.instance() + .getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME); + evaluator.setServiceDef(hiveDef); + evaluator.setPolicyItemCondition( + new RangerPolicyItemCondition("together", Arrays.asList("db1.tbl1.col1", "db1.tbl2.col2"))); + evaluator.init(); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + Map ctx = new HashMap<>(); + RangerRequestedResources requested = new RangerRequestedResources(); + + RangerAccessResourceImpl res1 = new RangerAccessResourceImpl(new HashMap<>(), null); + res1.setServiceDef(hiveDef); + res1.setValue("database", "db1"); + res1.setValue("table", "tbl1"); + res1.setValue("column", "col1"); + requested.addRequestedResource(res1); + + RangerAccessResourceImpl res2 = new RangerAccessResourceImpl(new HashMap<>(), null); + res2.setServiceDef(hiveDef); + res2.setValue("database", "db1"); + res2.setValue("table", "tbl2"); + res2.setValue("column", "col2"); + requested.addRequestedResource(res2); + + RangerAccessRequestUtil.setRequestedResourcesInContext(ctx, requested); + when(request.getContext()).thenReturn(ctx); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + + @Test + public void test02_notAccessedTogether_initialized_and_matchesWhenMutuallyExcluded() throws Exception { + RangerHiveResourcesNotAccessedTogetherCondition evaluator = new RangerHiveResourcesNotAccessedTogetherCondition(); + + RangerServiceDef hiveDef = EmbeddedServiceDefsUtil.instance() + .getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME); + evaluator.setServiceDef(hiveDef); + evaluator.setPolicyItemCondition( + new RangerPolicyItemCondition("notTogether", Arrays.asList("db1.tbl1.col1", "db1.tbl2.col2"))); + evaluator.init(); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + Map ctx = new HashMap<>(); + RangerRequestedResources requested = new RangerRequestedResources(); + + RangerAccessResourceImpl res1 = new RangerAccessResourceImpl(new HashMap<>(), null); + res1.setServiceDef(hiveDef); + res1.setValue("database", "db1"); + res1.setValue("table", "tbl1"); + res1.setValue("column", "col1"); + requested.addRequestedResource(res1); + + RangerAccessResourceImpl res3 = new RangerAccessResourceImpl(new HashMap<>(), null); + res3.setServiceDef(hiveDef); + res3.setValue("database", "dbX"); + res3.setValue("table", "tblZ"); + res3.setValue("column", "colZ"); + requested.addRequestedResource(res3); + + RangerAccessRequestUtil.setRequestedResourcesInContext(ctx, requested); + when(request.getContext()).thenReturn(ctx); + + Assertions.assertTrue(evaluator.isMatched(request)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerScriptConditionEvaluator.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerScriptConditionEvaluator.java new file mode 100644 index 0000000000..570fc837e3 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerScriptConditionEvaluator.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.util.ScriptEngineUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.SimpleBindings; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerScriptConditionEvaluator { + @Test + public void test01_isMatched_withValidScript_returnsEvaluatorResult() throws Exception { + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("hive"); + + Map evalOptions = new HashMap<>(); + evalOptions.put("engineName", "JavaScript"); + evalOptions.put("enableJsonCtx", "false"); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(evalOptions); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Collections.singletonList("true")); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getReadOnlyCopy()).thenReturn(request); + + ScriptEngine engine = mock(ScriptEngine.class); + + try (MockedStatic ignored = mockStatic(ScriptEngineUtil.class)) { + when(ScriptEngineUtil.createScriptEngine("hive")).thenReturn(engine); + when(engine.createBindings()).thenReturn(new SimpleBindings()); + when(engine.eval(anyString(), any(Bindings.class))).thenReturn(Boolean.TRUE); + + RangerScriptConditionEvaluator evaluator = new RangerScriptConditionEvaluator(); + evaluator.setServiceDef(serviceDef); + evaluator.setConditionDef(conditionDef); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + } + + @Test + public void test02_isMatched_withEmptyScript_logsErrorAndReturnsTrue() { + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("hive"); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(Collections.emptyMap()); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Collections.singletonList(" \t ")); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + + try (MockedStatic ignored = mockStatic(ScriptEngineUtil.class)) { + ScriptEngine engine = mock(ScriptEngine.class); + when(ScriptEngineUtil.createScriptEngine("hive")).thenReturn(engine); + + RangerScriptConditionEvaluator evaluator = new RangerScriptConditionEvaluator(); + evaluator.setServiceDef(serviceDef); + evaluator.setConditionDef(conditionDef); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + } + + @Test + public void test03_isMatched_whenEngineNotAvailable_returnsTrue() { + RangerScriptConditionEvaluator evaluator = new RangerScriptConditionEvaluator(); + RangerAccessRequest request = mock(RangerAccessRequest.class); + + Assertions.assertTrue(evaluator.isMatched(request)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerScriptTemplateConditionEvaluator.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerScriptTemplateConditionEvaluator.java new file mode 100644 index 0000000000..3c3856618f --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerScriptTemplateConditionEvaluator.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.util.ScriptEngineUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.SimpleBindings; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerScriptTemplateConditionEvaluator { + @Test + public void test01_isMatched_withTemplate_trueExpected_noReverse() throws Exception { + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("hive"); + + Map evalOptions = new HashMap<>(); + evalOptions.put("scriptTemplate", "true"); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(evalOptions); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Collections.singletonList("true")); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getReadOnlyCopy()).thenReturn(request); + + ScriptEngine engine = mock(ScriptEngine.class); + + try (MockedStatic ignored = mockStatic(ScriptEngineUtil.class)) { + when(ScriptEngineUtil.createScriptEngine("hive")).thenReturn(engine); + when(engine.createBindings()).thenReturn(new SimpleBindings()); + when(engine.eval(anyString(), any(Bindings.class))).thenReturn(Boolean.TRUE); + + RangerScriptTemplateConditionEvaluator evaluator = new RangerScriptTemplateConditionEvaluator(); + evaluator.setServiceDef(serviceDef); + evaluator.setConditionDef(conditionDef); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + Assertions.assertTrue(evaluator.isMatched(request)); + } + } + + @Test + public void test02_isMatched_withTemplate_falseExpected_reverseTrue() throws Exception { + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("hive"); + + Map evalOptions = new HashMap<>(); + evalOptions.put("scriptTemplate", "true"); + + RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class); + when(conditionDef.getEvaluatorOptions()).thenReturn(evalOptions); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + when(condition.getValues()).thenReturn(Collections.singletonList("false")); + + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getReadOnlyCopy()).thenReturn(request); + + ScriptEngine engine = mock(ScriptEngine.class); + + try (MockedStatic ignored = mockStatic(ScriptEngineUtil.class)) { + when(ScriptEngineUtil.createScriptEngine("hive")).thenReturn(engine); + when(engine.createBindings()).thenReturn(new SimpleBindings()); + when(engine.eval(anyString(), any(Bindings.class))).thenReturn(Boolean.TRUE); + + RangerScriptTemplateConditionEvaluator evaluator = new RangerScriptTemplateConditionEvaluator(); + evaluator.setServiceDef(serviceDef); + evaluator.setConditionDef(conditionDef); + evaluator.setPolicyItemCondition(condition); + evaluator.init(); + + Assertions.assertFalse(evaluator.isMatched(request)); + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerTagConditions.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerTagConditions.java new file mode 100644 index 0000000000..91a9477c8f --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/TestRangerTagConditions.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.contextenricher.RangerTagForEval; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerTag; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.policyengine.RangerAccessResource; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +import org.apache.ranger.plugin.util.RangerAccessRequestUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.mockito.Mockito.mock; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerTagConditions { + @Test + public void test01_anyOfExpectedTags_present() { + RangerAnyOfExpectedTagsPresentConditionEvaluator evaluator = new RangerAnyOfExpectedTagsPresentConditionEvaluator(); + evaluator.setPolicyItemCondition(new RangerPolicyItemCondition( + "__tagsAny", Arrays.asList("PCI", "PII"))); + evaluator.init(); + + RangerAccessRequest request = buildRequestWithTags(new HashSet<>(Arrays.asList("PCI", "PHI"))); + Assertions.assertTrue(evaluator.isMatched(request)); + } + + @Test + public void test02_anyOfExpectedTags_absent() { + RangerAnyOfExpectedTagsPresentConditionEvaluator evaluator = new RangerAnyOfExpectedTagsPresentConditionEvaluator(); + evaluator.setPolicyItemCondition(new RangerPolicyItemCondition( + "__tagsAny", Arrays.asList("PCI", "PII"))); + evaluator.init(); + + RangerAccessRequest request = buildRequestWithTags(new HashSet<>(Arrays.asList("PHI"))); + Assertions.assertFalse(evaluator.isMatched(request)); + } + + @Test + public void test03_allExpectedTags_present() { + RangerTagsAllPresentConditionEvaluator evaluator = new RangerTagsAllPresentConditionEvaluator(); + evaluator.setPolicyItemCondition(new RangerPolicyItemCondition( + "__tagsAll", Arrays.asList("PCI", "PII"))); + evaluator.init(); + + RangerAccessRequest request = buildRequestWithTags(new HashSet<>(Arrays.asList("PCI", "PII", "PHI"))); + Assertions.assertTrue(evaluator.isMatched(request)); + } + + @Test + public void test04_allExpectedTags_missing() { + RangerTagsAllPresentConditionEvaluator evaluator = new RangerTagsAllPresentConditionEvaluator(); + evaluator.setPolicyItemCondition(new RangerPolicyItemCondition( + "__tagsAll", Arrays.asList("PCI", "PII"))); + evaluator.init(); + + RangerAccessRequest request = buildRequestWithTags(new HashSet<>(Collections.singletonList("PCI"))); + Assertions.assertFalse(evaluator.isMatched(request)); + } + + @Test + public void test05_noneOfExpectedTags_present_returnsFalse() { + RangerNoneOfExpectedTagsPresentConditionEvaluator evaluator = new RangerNoneOfExpectedTagsPresentConditionEvaluator(); + evaluator.setPolicyItemCondition(new RangerPolicyItemCondition( + "__tagsNone", Arrays.asList("PCI", "PII"))); + evaluator.init(); + + RangerAccessRequest request = buildRequestWithTags(new HashSet<>(Collections.singletonList("PII"))); + Assertions.assertFalse(evaluator.isMatched(request)); + } + + @Test + public void test06_noneOfExpectedTags_absent_returnsTrue() { + RangerNoneOfExpectedTagsPresentConditionEvaluator evaluator = new RangerNoneOfExpectedTagsPresentConditionEvaluator(); + evaluator.setPolicyItemCondition(new RangerPolicyItemCondition( + "__tagsNone", Arrays.asList("PCI", "PII"))); + evaluator.init(); + + RangerAccessRequest request = buildRequestWithTags(new HashSet<>(Collections.singletonList("PHI"))); + Assertions.assertTrue(evaluator.isMatched(request)); + } + + private RangerAccessRequest buildRequestWithTags(Set tagTypes) { + RangerAccessResource resource = mock(RangerAccessResource.class); + + RangerAccessRequestImpl request = new RangerAccessRequestImpl(); + request.setResource(resource); + + Set rangerTagForEvals = new HashSet<>(); + for (String type : tagTypes) { + RangerTag tag = new RangerTag(type, Collections.singletonMap("attr1", type + "_v")); + rangerTagForEvals.add(new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.SELF)); + } + + Map ctx = request.getContext(); + RangerAccessRequestUtil.setRequestTagsInContext(ctx, rangerTagForEvals); + return request; + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAbstractContextEnricher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAbstractContextEnricher.java new file mode 100644 index 0000000000..d2f2dfc231 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAbstractContextEnricher.java @@ -0,0 +1,184 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; +import org.apache.ranger.plugin.service.RangerAuthContext; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.File; +import java.net.URL; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAbstractContextEnricher { + public static class DummyEnricher extends RangerAbstractContextEnricher { + @Override + public void enrich(RangerAccessRequest rangerAccessRequest) { + } + } + + @Test + public void test01_Init_And_PreCleanup_With_AuthContext() { + DummyEnricher enricher = new DummyEnricher(); + + RangerAuthContext authContext = Mockito.mock(RangerAuthContext.class); + doNothing().when(authContext).addOrReplaceRequestContextEnricher(any(RangerContextEnricher.class), any()); + doNothing().when(authContext).cleanupRequestContextEnricher(any(RangerContextEnricher.class)); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, new RangerPolicyEngineOptions()); + RangerPluginContext pluginContext = Mockito.spy(new RangerPluginContext(pluginConfig)); + pluginContext.setAuthContext(authContext); + + enricher.setPluginContext(pluginContext); + enricher.init(); + + boolean ret = enricher.preCleanup(); + assertTrue(ret); + verify(authContext, times(1)).cleanupRequestContextEnricher(enricher); + } + + @Test + public void test02_Init_With_Null_AuthContext() { + DummyEnricher enricher = new DummyEnricher(); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, new RangerPolicyEngineOptions()); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + // no authContext + enricher.setPluginContext(pluginContext); + + enricher.init(); + boolean ret = enricher.preCleanup(); + assertTrue(ret); + } + + @Test + public void test03_Getters_Setters_And_GetName() { + DummyEnricher enricher = new DummyEnricher(); + RangerContextEnricherDef def = new RangerContextEnricherDef(1L, "MyEnricher", DummyEnricher.class.getName(), new HashMap<>()); + enricher.setEnricherDef(def); + enricher.setServiceName("svc"); + enricher.setServiceDef(new RangerServiceDef()); + enricher.setAppId("appid"); + + assertEquals("MyEnricher", enricher.getName()); + assertEquals("svc", enricher.getServiceName()); + assertEquals("appid", enricher.getAppId()); + assertNotNull(enricher.getServiceDef()); + + RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions(); + opts.optimizeTagTrieForSpace = true; + enricher.setPolicyEngineOptions(opts); + assertEquals(opts, enricher.getPolicyEngineOptions()); + } + + @Test + public void test04_Options_And_Config_Defaults() { + DummyEnricher enricher = new DummyEnricher(); + Map options = new HashMap<>(); + options.put("opt1", "val1"); + RangerContextEnricherDef def = new RangerContextEnricherDef(1L, "E", DummyEnricher.class.getName(), options); + enricher.setEnricherDef(def); + + assertEquals("val1", enricher.getOption("opt1")); + assertEquals("def", enricher.getOption("missing", "def")); + assertTrue(enricher.getBooleanOption("missingBool", true)); + assertFalse(enricher.getBooleanOption("missingBool", false)); + assertEquals('x', enricher.getCharOption("missingChar", 'x')); + assertEquals(42L, enricher.getLongOption("missingLong", 42L)); + + // plugin config absent -> getConfig/int/bool should return defaults + assertEquals("dflt", enricher.getConfig("x", "dflt")); + assertEquals(7, enricher.getIntConfig("x", 7)); + assertTrue(enricher.getBooleanConfig("x", true)); + } + + @Test + public void test05_GetPropertyPrefix_And_PluginConfig() { + DummyEnricher enricher = new DummyEnricher(); + RangerServiceDef svcDef = new RangerServiceDef(); + svcDef.setName("svcType"); + enricher.setServiceDef(svcDef); + + // No plugin context + assertEquals("ranger.plugin.svcType", enricher.getPropertyPrefix()); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, new RangerPolicyEngineOptions()); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + enricher.setPluginContext(pluginContext); + + assertEquals(pluginConfig, enricher.getPluginConfig()); + assertEquals(pluginContext, enricher.getPluginContext()); + assertEquals(pluginConfig.getPropertyPrefix(), enricher.getPropertyPrefix()); + } + + @Test + public void test06_ReadProperties_From_Resource_And_File() throws Exception { + DummyEnricher enricher = new DummyEnricher(); + + // Resource on classpath (use this test's class as reference): should return null for non-existent + Properties noProps = enricher.readProperties("/non-existent-file.properties"); + assertNull(noProps); + + // Create a temp properties file and read + File tmp = File.createTempFile("ranger-test", ".properties"); + Files.write(tmp.toPath(), Arrays.asList("key=value")); + Properties props = enricher.readProperties(tmp.getAbsolutePath()); + assertNotNull(props); + assertEquals("value", props.getProperty("key")); + + // Also verify resource loading via getResource (write to temp dir and use URL) + URL url = tmp.toURI().toURL(); + assertNotNull(url); + + // cleanup + //noinspection ResultOfMethodCallIgnored + tmp.delete(); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminGdsInfoRetriever.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminGdsInfoRetriever.java new file mode 100644 index 0000000000..0847fe1175 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminGdsInfoRetriever.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.util.ServiceGdsInfo; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.nio.channels.ClosedByInterruptException; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAdminGdsInfoRetriever { + @Test + public void test01_Init_UsesProvidedAdminClient_And_NoDedup() throws Exception { + RangerAdminGdsInfoRetriever retriever = new RangerAdminGdsInfoRetriever(); + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + retriever.setServiceName("svc"); + retriever.setServiceDef(def); + retriever.setAppId("app"); + + RangerPluginConfig config = new RangerPluginConfig(def.getName(), "svc", "app", null, null, null); + RangerPluginContext pluginCtx = new RangerPluginContext(config); + RangerAdminClient admin = mock(RangerAdminClient.class); + pluginCtx.setAdminClient(admin); + retriever.setPluginContext(pluginCtx); + + Map opts = new HashMap<>(); + opts.put("deDupTags", "false"); + retriever.init(opts); + + ServiceGdsInfo info = mock(ServiceGdsInfo.class); + when(admin.getGdsInfoIfUpdated(anyLong(), anyLong())).thenReturn(info); + + ServiceGdsInfo out = retriever.retrieveGdsInfo(-1L, -1L); + assertNotNull(out); + verify(info, times(0)).dedupStrings(); + } + + @Test + public void test02_Init_CreatesAdminClient_WhenNotProvided_And_DedupTrue() throws Exception { + RangerAdminGdsInfoRetriever retriever = new RangerAdminGdsInfoRetriever(); + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + retriever.setServiceName("svc"); + retriever.setServiceDef(def); + retriever.setAppId("app"); + + RangerPluginConfig config = new RangerPluginConfig(def.getName(), "svc", "app", null, null, null); + RangerPluginContext pluginCtx = new RangerPluginContext(config); + RangerAdminClient admin = mock(RangerAdminClient.class); + pluginCtx.setAdminClient(admin); + retriever.setPluginContext(pluginCtx); + + Map opts = new HashMap<>(); + opts.put("deDupTags", "true"); + retriever.init(opts); + + ServiceGdsInfo info = mock(ServiceGdsInfo.class); + when(admin.getGdsInfoIfUpdated(anyLong(), anyLong())).thenReturn(info); + + ServiceGdsInfo out = retriever.retrieveGdsInfo(0L, 0L); + assertNotNull(out); + verify(info, times(1)).dedupStrings(); + } + + @Test + public void test03_Init_MissingService_LogsError_NoCrash() { + RangerAdminGdsInfoRetriever retriever = new RangerAdminGdsInfoRetriever(); + assertDoesNotThrow(() -> retriever.init(new HashMap<>())); + } + + @Test + public void test04_Retrieve_ClosedByInterrupt_ThrowsInterrupted() throws Exception { + RangerAdminGdsInfoRetriever retriever = new RangerAdminGdsInfoRetriever(); + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + retriever.setServiceName("svc"); + retriever.setServiceDef(def); + retriever.setAppId("app"); + + RangerPluginConfig config = new RangerPluginConfig(def.getName(), "svc", "app", null, null, null); + RangerPluginContext pluginCtx = new RangerPluginContext(config); + RangerAdminClient admin = mock(RangerAdminClient.class); + pluginCtx.setAdminClient(admin); + retriever.setPluginContext(pluginCtx); + + retriever.init(new HashMap<>()); + doThrow(new ClosedByInterruptException()).when(admin).getGdsInfoIfUpdated(anyLong(), anyLong()); + + assertThrows(InterruptedException.class, () -> retriever.retrieveGdsInfo(1L, 1L)); + } + + @Test + public void test05_Retrieve_OtherException_ReturnsNull() throws Exception { + RangerAdminGdsInfoRetriever retriever = new RangerAdminGdsInfoRetriever(); + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + retriever.setServiceName("svc"); + retriever.setServiceDef(def); + retriever.setAppId("app"); + + RangerPluginConfig config = new RangerPluginConfig(def.getName(), "svc", "app", null, null, null); + RangerPluginContext pluginCtx = new RangerPluginContext(config); + RangerAdminClient admin = mock(RangerAdminClient.class); + pluginCtx.setAdminClient(admin); + retriever.setPluginContext(pluginCtx); + + retriever.init(new HashMap<>()); + doThrow(new RuntimeException("boom")).when(admin).getGdsInfoIfUpdated(anyLong(), anyLong()); + + ServiceGdsInfo out = retriever.retrieveGdsInfo(2L, 2L); + assertNull(out); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminTagRetriever.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminTagRetriever.java new file mode 100644 index 0000000000..836d87788d --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminTagRetriever.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.util.ServiceTags; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.nio.channels.ClosedByInterruptException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAdminTagRetriever { + @Test + public void test01_Init_And_RetrieveTags_Normal_And_Exception() throws Exception { + RangerAdminClient adminClient = Mockito.mock(RangerAdminClient.class); + ServiceTags tags = new ServiceTags(); + when(adminClient.getServiceTagsIfUpdated(anyLong(), anyLong())).thenReturn(tags); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, null); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + pluginContext.setAdminClient(adminClient); + + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + + RangerAdminTagRetriever retriever = new RangerAdminTagRetriever(); + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + retriever.setPluginConfig(pluginConfig); + retriever.setPluginContext(pluginContext); + retriever.init(new HashMap<>()); + + ServiceTags out = retriever.retrieveTags(-1L, -1L); + assertNotNull(out); + + when(adminClient.getServiceTagsIfUpdated(anyLong(), anyLong())).thenThrow(new RuntimeException("boom")); + out = retriever.retrieveTags(-1L, -1L); + assertNull(out); + } + + @Test + public void test02_RetrieveTags_Interrupted() { + assertThrows(InterruptedException.class, () -> { + RangerAdminClient adminClient = Mockito.mock(RangerAdminClient.class); + when(adminClient.getServiceTagsIfUpdated(anyLong(), anyLong())).thenThrow(new ClosedByInterruptException()); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, null); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + pluginContext.setAdminClient(adminClient); + + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + + RangerAdminTagRetriever retriever = new RangerAdminTagRetriever(); + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + retriever.setPluginConfig(pluginConfig); + retriever.setPluginContext(pluginContext); + retriever.init(new HashMap<>()); + + retriever.retrieveTags(-1L, -1L); + }); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminUserStoreRetriever.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminUserStoreRetriever.java new file mode 100644 index 0000000000..2fc9dbe6a1 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerAdminUserStoreRetriever.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.util.RangerUserStore; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.nio.channels.ClosedByInterruptException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAdminUserStoreRetriever { + @Test + public void test01_Init_And_RetrieveUserStore_Normal_And_Exception() throws Exception { + RangerAdminClient adminClient = Mockito.mock(RangerAdminClient.class); + RangerUserStore userStore = new RangerUserStore(); + userStore.setUserStoreVersion(5L); + when(adminClient.getUserStoreIfUpdated(anyLong(), anyLong())).thenReturn(userStore); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, null); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + pluginContext.setAdminClient(adminClient); + + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + + RangerAdminUserStoreRetriever retriever = new RangerAdminUserStoreRetriever(); + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + retriever.setPluginConfig(pluginConfig); + retriever.setPluginContext(pluginContext); + retriever.init(new HashMap<>()); + + RangerUserStore out = retriever.retrieveUserStoreInfo(-1L, -1L); + assertNotNull(out); + assertEquals(5L, out.getUserStoreVersion()); + + when(adminClient.getUserStoreIfUpdated(anyLong(), anyLong())).thenThrow(new RuntimeException("boom")); + out = retriever.retrieveUserStoreInfo(-1L, -1L); + assertNull(out); + } + + @Test + public void test02_RetrieveUserStore_Interrupted() { + assertThrows(InterruptedException.class, () -> { + RangerAdminClient adminClient = Mockito.mock(RangerAdminClient.class); + when(adminClient.getUserStoreIfUpdated(anyLong(), anyLong())).thenThrow(new ClosedByInterruptException()); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, null); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + pluginContext.setAdminClient(adminClient); + + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + + RangerAdminUserStoreRetriever retriever = new RangerAdminUserStoreRetriever(); + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + retriever.setPluginConfig(pluginConfig); + retriever.setPluginContext(pluginContext); + retriever.init(new HashMap<>()); + + retriever.retrieveUserStoreInfo(-1L, -1L); + }); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerFileBasedGeolocationProvider.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerFileBasedGeolocationProvider.java new file mode 100644 index 0000000000..c2042adf43 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerFileBasedGeolocationProvider.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerFileBasedGeolocationProvider { + @Test + public void test01_Init_And_Enrich_SetsLocationKeys() { + RangerFileBasedGeolocationProvider provider = new RangerFileBasedGeolocationProvider(); + + RangerServiceDef svcDef = new RangerServiceDef(); + svcDef.setName("hive"); + + Map enricherOptions = new HashMap<>(); + enricherOptions.put(RangerAbstractGeolocationProvider.ENRICHER_OPTION_GEOLOCATION_META_PREFIX, ""); + // File-based store reads path using key "FilePath" + enricherOptions.put("FilePath", "/etc/ranger/geo/geo.txt"); + + RangerServiceDef.RangerContextEnricherDef def = new RangerServiceDef.RangerContextEnricherDef(1L, "Geo", provider.getClass().getName(), enricherOptions); + + provider.setServiceDef(svcDef); + provider.setServiceName("svc"); + provider.setAppId("appid"); + provider.setEnricherDef(def); + + RangerPluginConfig pluginConfig = new RangerPluginConfig("hive", "svc", "appid", null, null, null); + RangerPluginContext pluginContext = new RangerPluginContext(pluginConfig); + provider.setPluginContext(pluginContext); + + provider.init(); + + RangerAccessRequestImpl req = new RangerAccessRequestImpl(); + req.setClientIPAddress("20.0.100.85"); // present in default geo data resource range in geo.txt + + provider.enrich(req); + + Map ctx = req.getContext(); + // We expect country and city fields to be populated with LOCATION_ prefix + boolean hasAnyGeo = ctx.keySet().stream().anyMatch(k -> k.startsWith(RangerAbstractGeolocationProvider.KEY_CONTEXT_GEOLOCATION_PREFIX)); + assertTrue(hasAnyGeo); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerFileBasedTagRetriever.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerFileBasedTagRetriever.java new file mode 100644 index 0000000000..470a17c9c1 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerFileBasedTagRetriever.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.authorization.utils.JsonUtils; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.util.ServiceTags; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerFileBasedTagRetriever { + @Test + public void test01_Init_With_Options_And_Retrieve_From_Resource() throws Exception { + RangerFileBasedTagRetriever retriever = new RangerFileBasedTagRetriever(); + + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + + Map options = new HashMap<>(); + options.put("serviceTagsFileName", "/policyengine/resourceTags.json"); + + retriever.init(options); + + ServiceTags tags = retriever.retrieveTags(-1L, -1L); + assertNotNull(tags); + assertEquals("cl1_hive", tags.getServiceName()); + } + + @Test + public void test02_Init_With_Missing_File_Graceful() { + RangerFileBasedTagRetriever retriever = new RangerFileBasedTagRetriever(); + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + + Map options = new HashMap<>(); + options.put("serviceTagsFileName", "/does/not/exist.json"); + + retriever.init(options); + + ServiceTags out = retriever.retrieveTags(-1L, -1L); + assertNull(out); + } + + @Test + public void test03_Rotate_Tag_Files_When_Not_Initial() throws Exception { + // prepare temp directory with two tag files suffixed _0.json and _1.json + File dir = new File(System.getProperty("java.io.tmpdir"), "rtags-" + System.nanoTime()); + assertTrue(dir.mkdirs()); + File base = new File(dir, "tags.json"); + String basePath = base.getAbsolutePath(); + + ServiceTags t0 = new ServiceTags(); + t0.setServiceName("svc"); + t0.setTagVersion(100L); + ServiceTags t1 = new ServiceTags(); + t1.setServiceName("svc"); + t1.setTagVersion(101L); + + writeTags(new File(basePath + "_0.json"), t0); + writeTags(new File(basePath + "_1.json"), t1); + + RangerFileBasedTagRetriever retriever = new RangerFileBasedTagRetriever(); + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + + Map options = new HashMap<>(); + options.put("serviceTagsFileName", basePath); + options.put("tagFileCount", "2"); + retriever.init(options); + + // first retrieve uses initial file (basePath), which doesn't exist => null + assertNull(retriever.retrieveTags(-1L, -1L)); + + // simulate parsed tagFilesCount and non-initial state + retriever.tagFilesCount = 2; + retriever.currentTagFileIndex = 0; + retriever.isInitial = false; + + // subsequent retrieves rotate between _0 and _1 + ServiceTags r0 = retriever.retrieveTags(-1L, -1L); + ServiceTags r1 = retriever.retrieveTags(-1L, -1L); + assertNotNull(r0); + assertNotNull(r1); + assertTrue(r0.getTagVersion() == 100L || r0.getTagVersion() == 101L); + assertTrue(r1.getTagVersion() == 100L || r1.getTagVersion() == 101L); + } + + @Test + public void test04_GetTagFileURL_OpenStreamError_Graceful() { + RangerFileBasedTagRetriever retriever = new RangerFileBasedTagRetriever(); + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + retriever.setServiceName("svc"); + retriever.setServiceDef(serviceDef); + retriever.setAppId("appid"); + + Map options = new HashMap<>(); + // Provide a bogus path to force URL lookup to fail and log, returning null + options.put("serviceTagsFileName", "/this/path/does/not/exist/tags.json"); + retriever.init(options); + + ServiceTags out = retriever.retrieveTags(-1L, -1L); + assertNull(out); + } + + private static void writeTags(File file, ServiceTags tags) throws Exception { + try (FileWriter fw = new FileWriter(file)) { + fw.write(JsonUtils.objectToJson(tags)); + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerGdsEnricher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerGdsEnricher.java new file mode 100644 index 0000000000..843918767d --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerGdsEnricher.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.policyengine.gds.GdsAccessResult; +import org.apache.ranger.plugin.policyengine.gds.GdsPolicyEngine; +import org.apache.ranger.plugin.util.RangerAccessRequestUtil; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerGdsEnricher { + @Test + public void test01_Enrich_With_DataStore_And_Null() { + RangerGdsEnricher enricher = new RangerGdsEnricher(); + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + enricher.setServiceDef(serviceDef); + + GdsPolicyEngine engine = Mockito.mock(GdsPolicyEngine.class); + GdsAccessResult result = new GdsAccessResult(); + when(engine.evaluate(any())).thenReturn(result); + + RangerAccessRequestImpl request = new RangerAccessRequestImpl(); + + // With dataStore engine + enricher.enrich(request, engine); + assertEquals(result, RangerAccessRequestUtil.getGdsResultFromContext(request.getContext())); + + // Without dataStore, and internal engine null -> no NPE and null in context + RangerAccessRequestImpl request2 = new RangerAccessRequestImpl(); + enricher.enrich(request2, null); + assertNull(RangerAccessRequestUtil.getGdsResultFromContext(request2.getContext())); + } + + @Test + public void test02_SetGdsInfo_SetsEngine_And_PreCleanup() { + RangerGdsEnricher enricher = new RangerGdsEnricher(); + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + enricher.setServiceDef(serviceDef); + + // set plugin context and init so serviceDefHelper is initialized and pluginContext is non-null + RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "appid", null, null, null); + RangerPluginContext ctx = new RangerPluginContext(cfg); + enricher.setPluginContext(ctx); + enricher.init(); + + // No need to construct a real GdsPolicyEngine here; verify preCleanup path executes safely + assertTrue(enricher.preCleanup()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerServiceResourceMatcher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerServiceResourceMatcher.java new file mode 100644 index 0000000000..818a9f9113 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerServiceResourceMatcher.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.model.RangerServiceResource; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl; +import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceResourceMatcher { + @Test + public void test01_Id_IsLeaf_And_GetMatchType() { + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("hive"); + RangerResourceDef db = new RangerResourceDef(); + db.setItemId(1L); + db.setName("database"); + db.setType("string"); + db.setLevel(0); + db.setIsValidLeaf(true); + serviceDef.setResources(Collections.singletonList(db)); + + RangerServiceResource sr = new RangerServiceResource(); + sr.setId(100L); + sr.setServiceName("hive"); + Map res = new HashMap<>(); + res.put("database", new RangerPolicy.RangerPolicyResource(Collections.singletonList("db1"), false, false)); + sr.setResourceElements(res); + + RangerDefaultPolicyResourceMatcher matcher = new RangerDefaultPolicyResourceMatcher(); + matcher.setServiceDef(serviceDef); + matcher.setPolicyResources(res, RangerPolicy.POLICY_TYPE_ACCESS); + matcher.init(); + + RangerServiceResourceMatcher srm = new RangerServiceResourceMatcher(sr, matcher); + + assertEquals(100L, srm.getId()); + assertTrue(srm.isLeaf("database")); + + RangerAccessResourceImpl reqRes = new RangerAccessResourceImpl(); + reqRes.setServiceDef(serviceDef); + reqRes.setValue("database", Collections.singletonList("db1")); + RangerAccessRequestImpl req = new RangerAccessRequestImpl(); + req.setResource(reqRes); + + RangerPolicyResourceMatcher.MatchType mt = srm.getMatchType(reqRes, req.getResourceElementMatchingScopes(), req.getContext()); + assertNotEquals(RangerPolicyResourceMatcher.MatchType.NONE, mt); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerTagEnricher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerTagEnricher.java new file mode 100644 index 0000000000..bd1804dbf6 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerTagEnricher.java @@ -0,0 +1,741 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import org.apache.ranger.plugin.contextenricher.TestRangerTagEnricher.TagEnricherTestCase.TestData; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.model.RangerServiceResource; +import org.apache.ranger.plugin.model.RangerTag; +import org.apache.ranger.plugin.model.RangerTagDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.policyengine.RangerAccessResource; +import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl; +import org.apache.ranger.plugin.policyengine.RangerMutableResource; +import org.apache.ranger.plugin.policyengine.RangerResourceTrie; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType; +import org.apache.ranger.plugin.util.DownloadTrigger; +import org.apache.ranger.plugin.util.RangerAccessRequestUtil; +import org.apache.ranger.plugin.util.RangerServiceTagsDeltaUtil; +import org.apache.ranger.plugin.util.ServiceTags; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerTagEnricher { + static Gson gsonBuilder; + + @BeforeAll + public static void setUpBeforeClass() throws Exception { + gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z") + .setPrettyPrinting() + .registerTypeAdapter(RangerAccessResource.class, new RangerResourceDeserializer()) + .create(); + } + + @AfterAll + public static void tearDownAfterClass() throws Exception { + } + + @Test + public void test01_RangerTagsForEvalSort() { + List matchTypes = new ArrayList<>(); + + matchTypes.add(null); + matchTypes.add(MatchType.NONE); + matchTypes.add(MatchType.DESCENDANT); + matchTypes.add(MatchType.ANCESTOR); + matchTypes.add(MatchType.SELF_AND_ALL_DESCENDANTS); + matchTypes.add(MatchType.SELF); + + matchTypes.sort(RangerPolicyResourceMatcher.MATCH_TYPE_COMPARATOR); + + assertEquals(matchTypes.get(0), MatchType.SELF); + assertEquals(matchTypes.get(1), MatchType.SELF_AND_ALL_DESCENDANTS); + assertEquals(matchTypes.get(2), MatchType.ANCESTOR); + assertEquals(matchTypes.get(3), MatchType.DESCENDANT); + assertEquals(matchTypes.get(4), MatchType.NONE); + assertNull(matchTypes.get(5)); + } + + @Test + public void test02_TagEnricher_hive() { + String[] hiveTestResourceFiles = {"/contextenricher/test_tagenricher_hive.json"}; + + runTestsFromResourceFiles(hiveTestResourceFiles); + } + + private void runTestsFromResourceFiles(String[] resourceNames) { + for (String resourceName : resourceNames) { + InputStream inStream = this.getClass().getResourceAsStream(resourceName); + InputStreamReader reader = new InputStreamReader(inStream); + + runTests(reader, resourceName); + } + } + + private void runTests(InputStreamReader reader, String testName) { + TagEnricherTestCase testCase = gsonBuilder.fromJson(reader, TagEnricherTestCase.class); + + assertTrue(testCase != null && testCase.serviceDef != null && testCase.serviceResources != null && testCase.tests != null, testName); + + ServiceTags serviceTags = new ServiceTags(); + serviceTags.setServiceName(testCase.serviceName); + serviceTags.setTagDefinitions(testCase.tagDefinitions); + serviceTags.setTags(testCase.tags); + serviceTags.setServiceResources(testCase.serviceResources); + serviceTags.setResourceToTagIds(testCase.resourceToTagIds); + + RangerTagEnricher tagEnricher = new RangerTagEnricher(); + + tagEnricher.setServiceName(testCase.serviceName); + tagEnricher.setServiceDef(testCase.serviceDef); + tagEnricher.init(); + tagEnricher.setServiceTags(serviceTags); + + List expectedTags = new ArrayList<>(); + List resultTags = new ArrayList<>(); + + for (TestData test : testCase.tests) { + RangerAccessRequestImpl request = new RangerAccessRequestImpl(test.resource, test.accessType, "testUser", null, null); + + ((RangerMutableResource) request.getResource()).setServiceDef(testCase.serviceDef); + tagEnricher.enrich(request); + + List expected = test.result; + + Set result = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext()); + + expectedTags.clear(); + if (expected != null) { + for (RangerTag tag : expected) { + expectedTags.add(tag.getType()); + } + Collections.sort(expectedTags); + } + + resultTags.clear(); + if (result != null) { + for (RangerTagForEval tag : result) { + resultTags.add(tag.getType()); + } + Collections.sort(resultTags); + } + + assertEquals(expectedTags, resultTags, test.name); + } + } + + @Test + public void test03_Init_WithMissingRetrieverName_LogsError_NoCrash() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.setAppId("app"); + + RangerContextEnricherDef ed = new RangerContextEnricherDef(); + ed.setName("tags"); + ed.setEnricherOptions(Collections.emptyMap()); + enricher.setEnricherDef(ed); + + enricher.init(); + assertTrue(true); + } + + @Test + public void test04_SetServiceTags_Null_ClearsAndKeepsVersionMinusOne() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + assertEquals(-1L, enricher.getServiceTagsVersion()); + enricher.setServiceTags(null); + assertEquals(-1L, enricher.getServiceTagsVersion()); + } + + @Test + public void test05_SetServiceTags_NoResources_ReturnsNullEnriched() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = new ServiceTags(); + tags.setServiceName("svc"); + tags.setIsDelta(false); + tags.setTagVersion(1L); + + enricher.setServiceTags(tags); + assertEquals(-1L, enricher.getServiceTagsVersion()); + } + + @Test + public void test06_SetServiceTags_DisableTrieLookupPrefilter_BuildsMatchersOnly() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + assertEquals(1L, enricher.getServiceTagsVersion()); + assertNotNull(enricher.getEnrichedServiceTags()); + } + + @Test + public void test07_SetServiceTags_Delta_NoChange_UsesExisting() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags base = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(base); + assertEquals(1L, enricher.getServiceTagsVersion()); + + ServiceTags delta = new ServiceTags(); + delta.setServiceName("svc"); + delta.setIsDelta(true); + delta.setTagsChangeExtent(ServiceTags.TagsChangeExtent.NONE); + delta.setTagVersion(2L); + + enricher.setServiceTags(delta); + // For NONE extent, implementation retains existing enriched tags/version + assertEquals(1L, enricher.getServiceTagsVersion()); + } + + @Test + public void test08_PreCleanup_CancelsTimer_And_StopsRefresher() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + assertTrue(enricher.preCleanup()); + } + + @Test + public void test09_Enrich_With_Incorrect_DataStore_Fallbacks() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + + RangerAccessResourceImpl res = new RangerAccessResourceImpl(); + res.setServiceDef(def); + res.setValue("db", Arrays.asList("sales")); + RangerAccessRequestImpl req = new RangerAccessRequestImpl(); + req.setResource(res); + + enricher.enrich(req, new Object()); + assertNotNull(RangerAccessRequestUtil.getRequestTagsFromContext(req.getContext())); + } + + @Test + public void test10_SyncTagsWithAdmin_WaitsUntilSignaled() throws Exception { + RangerTagEnricher enricher = new RangerTagEnricher(); + DownloadTrigger token = new DownloadTrigger(); + + Thread signaller = new Thread(() -> { + try { + Thread.sleep(50L); + } catch (InterruptedException ignored) { + } + token.signalCompletion(); + }); + signaller.start(); + + enricher.syncTagsWithAdmin(token); + signaller.join(2000L); + assertTrue(!signaller.isAlive()); + } + + @Test + public void test11_GetResourceTrieVersion_BeforeAndAfterSet() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + assertEquals(-1L, enricher.getResourceTrieVersion()); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + assertEquals(1L, enricher.getResourceTrieVersion()); + } + + @Test + public void test12_CopyServiceResourceTrie_ReturnsDeepCopy() throws Exception { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + assertNotNull(enricher.getEnrichedServiceTags()); + + Method mCopy = RangerTagEnricher.class.getDeclaredMethod("copyServiceResourceTrie"); + mCopy.setAccessible(true); + @SuppressWarnings("unchecked") + Map> copy = (Map>) mCopy.invoke(enricher); + + Map> original = enricher.getEnrichedServiceTags().getServiceResourceTrie(); + assertNotNull(copy); + assertNotSame(original, copy); + for (Map.Entry> e : original.entrySet()) { + assertTrue(copy.containsKey(e.getKey())); + assertNotSame(e.getValue(), copy.get(e.getKey())); + } + } + + @Test + public void test13_RemoveOldServiceResource_RemovesMatcherAndReturnsAccessResource() throws Exception { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + assertNotNull(enricher.getEnrichedServiceTags()); + + RangerServiceResource serviceResource = enricher.getEnrichedServiceTags().getServiceTags().getServiceResources().get(0); + + Method mCopy = RangerTagEnricher.class.getDeclaredMethod("copyServiceResourceTrie"); + mCopy.setAccessible(true); + @SuppressWarnings("unchecked") + Map> resourceTries = (Map>) mCopy.invoke(enricher); + + List resourceMatchers = new ArrayList<>(enricher.getEnrichedServiceTags().getServiceResourceMatchers()); + int initialSize = resourceMatchers.size(); + + Method mRemove = RangerTagEnricher.class.getDeclaredMethod("removeOldServiceResource", RangerServiceResource.class, List.class, Map.class); + mRemove.setAccessible(true); + Object ret = mRemove.invoke(enricher, serviceResource, resourceMatchers, resourceTries); + + assertNotNull(ret); + assertEquals(initialSize - 1, resourceMatchers.size()); + } + + @Test + public void test14_ProcessServiceTagDeltas_SuccessfulUpdate_AddsMatcherAndUpdatesTrie() throws Exception { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags base = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(base); + + // Build delta that updates the existing resource (same id), with a new signature + RangerServiceResource updated = new RangerServiceResource(); + updated.setId(1L); + Map resElems = new HashMap<>(); + RangerPolicyResource policyRes = new RangerPolicyResource(Arrays.asList("sales"), null, null); + resElems.put("db", policyRes); + updated.setResourceElements(resElems); + updated.setResourceSignature("sig2"); + + ServiceTags deltas = new ServiceTags(); + deltas.setServiceName("svc"); + deltas.setIsDelta(true); + deltas.setTagsChangeExtent(ServiceTags.TagsChangeExtent.SERVICE_RESOURCE); + deltas.setTagVersion(2L); + List changed = new ArrayList<>(); + changed.add(updated); + deltas.setServiceResources(changed); + + ServiceTags allServiceTags = RangerServiceTagsDeltaUtil.applyDelta(new ServiceTags(base), deltas, false); + + Method mCopy = RangerTagEnricher.class.getDeclaredMethod("copyServiceResourceTrie"); + mCopy.setAccessible(true); + @SuppressWarnings("unchecked") + Map> trieMap = (Map>) mCopy.invoke(enricher); + + Set keysToRemoveFromCache = new HashSet<>(); + + Method mProcess = RangerTagEnricher.class.getDeclaredMethod("processServiceTagDeltas", ServiceTags.class, ServiceTags.class, Map.class, Set.class); + mProcess.setAccessible(true); + Object ret = mProcess.invoke(enricher, deltas, allServiceTags, trieMap, keysToRemoveFromCache); + + assertNotNull(ret); + assertTrue(!keysToRemoveFromCache.isEmpty()); + } + + @Test + public void test15_ProcessServiceTagDeltas_ErrorPath_ReturnsOldAndSetsVersionMinusOne() throws Exception { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags base = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(base); + + RangerServiceResource updated = new RangerServiceResource(); + updated.setId(1L); + Map resElems = new HashMap<>(); + RangerPolicyResource policyRes = new RangerPolicyResource(Arrays.asList("sales"), null, null); + resElems.put("db", policyRes); + updated.setResourceElements(resElems); + updated.setResourceSignature("sig2"); + + ServiceTags deltas = new ServiceTags(); + deltas.setServiceName("svc"); + deltas.setIsDelta(true); + deltas.setTagsChangeExtent(ServiceTags.TagsChangeExtent.SERVICE_RESOURCE); + deltas.setTagVersion(2L); + List changed = new ArrayList<>(); + changed.add(updated); + deltas.setServiceResources(changed); + + ServiceTags allServiceTags = RangerServiceTagsDeltaUtil.applyDelta(new ServiceTags(base), deltas, false); + + Map> emptyTrieMap = new HashMap<>(); + Set keysToRemoveFromCache = new HashSet<>(); + + Method mProcess = RangerTagEnricher.class.getDeclaredMethod("processServiceTagDeltas", ServiceTags.class, ServiceTags.class, Map.class, Set.class); + mProcess.setAccessible(true); + Object ret = mProcess.invoke(enricher, deltas, allServiceTags, emptyTrieMap, keysToRemoveFromCache); + + assertSame(enricher.getEnrichedServiceTags(), ret); + assertEquals(-1L, deltas.getTagVersion()); + assertTrue(keysToRemoveFromCache.isEmpty()); + } + + @Test + public void test16_FindMatchingTags_EmptyResourceAndAnyAccess_ReturnsAllTags() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + + RangerAccessRequestImpl request = new RangerAccessRequestImpl(); + request.setContext(new HashMap<>()); + request.setAccessType(null); // sets ANY + request.setResource(null); // empty resource + + enricher.enrich(request); + + Set result = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext()); + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals("T1", result.iterator().next().getType()); + } + + @Test + public void test17_DisableTrieLookupPrefilter_SkipsTrieBuild() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + + Map opts = new HashMap<>(); + opts.put("disableTrieLookupPrefilter", "true"); + RangerContextEnricherDef ed = new RangerContextEnricherDef(); + ed.setName("tags"); + ed.setEnricherOptions(opts); + enricher.setEnricherDef(ed); + + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(tags); + assertNotNull(enricher.getEnrichedServiceTags()); + assertNull(enricher.getEnrichedServiceTags().getServiceResourceTrie()); + } + + @Test + public void test18_Delta_TagsOnly_PreservesMatchersAndTrie() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags base = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(base); + RangerTagEnricher.EnrichedServiceTags before = enricher.getEnrichedServiceTags(); + assertNotNull(before); + + ServiceTags delta = new ServiceTags(); + delta.setServiceName("svc"); + delta.setIsDelta(true); + delta.setTagsChangeExtent(ServiceTags.TagsChangeExtent.TAGS); + delta.setTagVersion(2L); + + Map tagMap = new HashMap<>(base.getTags()); + RangerTag newTag = new RangerTag(); + newTag.setType("T2"); + tagMap.put(200L, newTag); + delta.setTags(tagMap); + + enricher.setServiceTags(delta); + + RangerTagEnricher.EnrichedServiceTags after = enricher.getEnrichedServiceTags(); + assertSame(before.getServiceResourceMatchers(), after.getServiceResourceMatchers()); + assertSame(before.getServiceResourceTrie(), after.getServiceResourceTrie()); + assertEquals(2L, after.getResourceTrieVersion()); + } + + @Test + public void test19_RemoveOldServiceResource_ErrorWhenTrieMissingKey_ReturnsNull() throws Exception { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags base = makeServiceTagsWithOneResource(def); + enricher.setServiceTags(base); + + RangerServiceResource serviceResource = enricher.getEnrichedServiceTags().getServiceTags().getServiceResources().get(0); + + Method mRemove = RangerTagEnricher.class.getDeclaredMethod("removeOldServiceResource", RangerServiceResource.class, List.class, Map.class); + mRemove.setAccessible(true); + + List resourceMatchers = new ArrayList<>(enricher.getEnrichedServiceTags().getServiceResourceMatchers()); + Map> resourceTries = new HashMap<>(); // missing key forces error path + + Object ret = mRemove.invoke(enricher, serviceResource, resourceMatchers, resourceTries); + assertNull(ret); + } + + @Test + public void test20_Init_WithInvalidRetrieverClass_NotFound() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.setAppId("app"); + + Map opts = new HashMap<>(); + opts.put("tagRetrieverClassName", "com.nonexistent.Foo"); + RangerContextEnricherDef ed = new RangerContextEnricherDef(); + ed.setName("tags"); + ed.setEnricherOptions(opts); + enricher.setEnricherDef(ed); + + enricher.init(); + assertTrue(true); + } + + public static class NotRetriever {} + + @Test + public void test21_Init_WithInvalidRetrieverClass_ClassCast() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.setAppId("app"); + + Map opts = new HashMap<>(); + opts.put("tagRetrieverClassName", NotRetriever.class.getName()); + RangerContextEnricherDef ed = new RangerContextEnricherDef(); + ed.setName("tags"); + ed.setEnricherOptions(opts); + enricher.setEnricherDef(ed); + + enricher.init(); + assertTrue(true); + } + + public abstract static class AbstractRetriever extends RangerTagRetriever {} + + @Test + public void test22_Init_WithAbstractRetriever_InstantiationError() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.setAppId("app"); + + Map opts = new HashMap<>(); + opts.put("tagRetrieverClassName", AbstractRetriever.class.getName()); + RangerContextEnricherDef ed = new RangerContextEnricherDef(); + ed.setName("tags"); + ed.setEnricherOptions(opts); + enricher.setEnricherDef(ed); + + enricher.init(); + assertTrue(true); + } + + @Test + public void test23_GetTagsForServiceResource_NullResourceId_YieldsNoTags() { + RangerTagEnricher enricher = new RangerTagEnricher(); + RangerServiceDef def = minimalSvcDef(); + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.init(); + + ServiceTags tags = makeServiceTagsWithOneResource(def); + // Add another service resource with null id that matches the request; it should not contribute tags + RangerServiceResource rs = new RangerServiceResource(); + rs.setId(null); + Map resElems = new HashMap<>(); + RangerPolicyResource policyRes = new RangerPolicyResource(Arrays.asList("sales"), null, null); + resElems.put("db", policyRes); + rs.setResourceElements(resElems); + rs.setResourceSignature("sig-null"); + tags.getServiceResources().add(rs); + + enricher.setServiceTags(tags); + + RangerAccessResourceImpl res = new RangerAccessResourceImpl(); + res.setServiceDef(def); + res.setValue("db", Arrays.asList("sales")); + RangerAccessRequestImpl req = new RangerAccessRequestImpl(res, "read", "u", null, null); + + enricher.enrich(req); + Set result = RangerAccessRequestUtil.getRequestTagsFromContext(req.getContext()); + assertNotNull(result); + assertEquals(1, result.size()); // only tag from id=1 resource + } + + private static RangerServiceDef minimalSvcDef() { + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + List resDefs = new ArrayList<>(); + RangerResourceDef r = new RangerResourceDef(); + r.setName("db"); + r.setMatcherOptions(Collections.emptyMap()); + r.setRecursiveSupported(true); + r.setExcludesSupported(true); + resDefs.add(r); + def.setResources(resDefs); + return def; + } + + private static ServiceTags makeServiceTagsWithOneResource(RangerServiceDef def) { + ServiceTags tags = new ServiceTags(); + tags.setServiceName("svc"); + tags.setTagVersion(1L); + tags.setIsDelta(false); + + RangerServiceResource rs = new RangerServiceResource(); + rs.setId(1L); + Map resElems = new HashMap<>(); + RangerPolicyResource policyRes = new RangerPolicyResource(Arrays.asList("sales"), null, null); + resElems.put("db", policyRes); + rs.setResourceElements(resElems); + rs.setResourceSignature("sig"); + + List list = new ArrayList<>(); + list.add(rs); + tags.setServiceResources(list); + Map> resToTags = new HashMap<>(); + resToTags.put(1L, Arrays.asList(100L)); + tags.setResourceToTagIds(resToTags); + Map tagMap = new HashMap<>(); + RangerTag t = new RangerTag(); + t.setType("T1"); + tagMap.put(100L, t); + tags.setTags(tagMap); + return tags; + } + + static class TagEnricherTestCase { + public String serviceName; + public RangerServiceDef serviceDef; + public Map tagDefinitions; + public Map tags; + public List serviceResources; + public Map> resourceToTagIds; + public List tests; + + static class TestData { + public String name; + public RangerAccessResource resource; + public String accessType; + public List result; + } + } + + static class RangerResourceDeserializer implements JsonDeserializer { + @Override + public RangerAccessResource deserialize(JsonElement jsonObj, Type type, + JsonDeserializationContext context) throws JsonParseException { + return gsonBuilder.fromJson(jsonObj, RangerAccessResourceImpl.class); + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerTagForEval.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerTagForEval.java new file mode 100644 index 0000000000..49872e583a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerTagForEval.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.plugin.model.RangerTag; +import org.apache.ranger.plugin.model.RangerValiditySchedule; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerTagForEval { + @Test + public void test01_IsApplicable_NoValidityPeriods_ReturnsTrue() { + RangerTag tag = new RangerTag(); + tag.setType("TYPE1"); + tag.setAttributes(new HashMap<>()); + tag.setOptions(new HashMap<>()); + tag.setValidityPeriods(new ArrayList<>()); + + RangerTagForEval forEval = new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.SELF); + + assertTrue(forEval.isApplicable(new Date())); + } + + @Test + public void test02_IsApplicable_WithSchedule_CoversTrueAndFalse() { + RangerValiditySchedule schedule = new RangerValiditySchedule(); + SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + schedule.setTimeZone(TimeZone.getDefault().getID()); + String nowMinus = fmt.format(new Date(System.currentTimeMillis() - 1000)); + String nowPlus = fmt.format(new Date(System.currentTimeMillis() + 1000)); + schedule.setStartTime(nowMinus); + schedule.setEndTime(nowPlus); + + List validity = new ArrayList<>(); + validity.add(schedule); + + RangerTag tag = new RangerTag(); + tag.setType("TYPE2"); + tag.setValidityPeriods(validity); + tag.setOptions(new HashMap<>()); + + RangerTagForEval forEval = new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.ANCESTOR); + + assertTrue(forEval.isApplicable(new Date())); + + // Outside window: set start in future and end in further future so now is outside + String futureStart = fmt.format(new Date(System.currentTimeMillis() + 600_000)); + String futureEnd = fmt.format(new Date(System.currentTimeMillis() + 1_200_000)); + schedule.setStartTime(futureStart); + schedule.setEndTime(futureEnd); + RangerTagForEval forEval2 = new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.ANCESTOR); + assertFalse(forEval2.isApplicable(new Date())); + } + + @Test + public void test03_IsApplicable_WithOptionsLazyInit() { + Map opts = new HashMap<>(); + // Put a validity period JSON string to trigger lazy init path in isApplicable + opts.put(RangerTag.OPTION_TAG_VALIDITY_PERIODS, "[{\"startTime\":\"1\",\"endTime\":\"4102444800000\"}]"); + + RangerTag tag = new RangerTag(); + tag.setType("TYPE3"); + tag.setOptions(opts); + + RangerTagForEval forEval = new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.DESCENDANT); + + assertTrue(forEval.isApplicable(new Date())); + } + + @Test + public void test04_Equals_HashCode_ToString() { + RangerTag tag1 = new RangerTag(); + tag1.setType("T"); + tag1.setAttributes(new HashMap<>()); + tag1.setOptions(new HashMap<>()); + + RangerTag tag2 = new RangerTag(); + tag2.setType("T"); + tag2.setAttributes(new HashMap<>()); + tag2.setOptions(new HashMap<>()); + + RangerTagForEval a = new RangerTagForEval(tag1, RangerPolicyResourceMatcher.MatchType.SELF); + RangerTagForEval b = new RangerTagForEval(tag2, RangerPolicyResourceMatcher.MatchType.SELF); + + assertEquals(a, b); + assertEquals(a.hashCode(), b.hashCode()); + assertTrue(a.toString().contains("RangerTagForEval")); + } + + @Test + public void test05_IsApplicable_NullAccessTime_ReturnsTrue() { + RangerTag tag = new RangerTag(); + tag.setType("T"); + RangerTagForEval forEval = new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.SELF); + assertTrue(forEval.isApplicable(null)); + } + + @Test + public void test06_IsApplicable_OptionsNonString_NoEvaluatorCreated_ReturnsTrue() { + Map opts = new HashMap<>(); + opts.put(RangerTag.OPTION_TAG_VALIDITY_PERIODS, 12345L); // non-string triggers empty evaluators + RangerTag tag = new RangerTag(); + tag.setType("T"); + tag.setOptions(opts); + RangerTagForEval forEval = new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.SELF); + assertTrue(forEval.isApplicable(new Date())); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerUserStoreEnricher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerUserStoreEnricher.java new file mode 100644 index 0000000000..1f5d84fea4 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerUserStoreEnricher.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.util.RangerAccessRequestUtil; +import org.apache.ranger.plugin.util.RangerUserStore; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerUserStoreEnricher { + @Test + public void test01_Enrich_With_DataStore_And_Fallback() { + RangerUserStoreEnricher enricher = new RangerUserStoreEnricher(); + + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(1L); + + RangerAccessRequestImpl request = new RangerAccessRequestImpl(); + + enricher.enrich(request, store); + assertEquals(store, RangerAccessRequestUtil.getRequestUserStoreFromContext(request.getContext())); + + // with wrong type, falls back to internal field (null) + enricher.enrich(request, new HashMap<>()); + assertNull(RangerAccessRequestUtil.getRequestUserStoreFromContext(request.getContext())); + } + + @Test + public void test02_SetRangerUserStore_Dedup_And_GetVersion() { + RangerUserStoreEnricher enricher = new RangerUserStoreEnricher(); + + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(42L); + + enricher.setRangerUserStore(store); + assertEquals(42L, enricher.getUserStoreVersion()); + assertEquals(store, enricher.getRangerUserStore()); + } + + @Test + public void test03_PreCleanup_Nulls_Timer_And_Refresher() { + RangerUserStoreEnricher enricher = Mockito.spy(new RangerUserStoreEnricher()); + + // Directly invoke preCleanup; no NPE should occur and returns true + assertTrue(enricher.preCleanup()); + } + + @Test + public void test04_Enrich_Without_DataStore_Delegates_To_Internal() { + RangerUserStoreEnricher enricher = new RangerUserStoreEnricher(); + + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(9L); + + RangerAccessRequestImpl request = new RangerAccessRequestImpl(); + + // set internal and call single-arg enrich + enricher.setRangerUserStore(store); + enricher.enrich(request); + assertEquals(store, RangerAccessRequestUtil.getRequestUserStoreFromContext(request.getContext())); + } + + @Test + public void test05_SetRangerUserStore_Null_Clears_Internal() { + RangerUserStoreEnricher enricher = new RangerUserStoreEnricher(); + + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(3L); + enricher.setRangerUserStore(store); + assertNotNull(enricher.getRangerUserStore()); + + enricher.setRangerUserStore(null); + assertNull(enricher.getRangerUserStore()); + assertNull(enricher.getUserStoreVersion()); + } + + @Test + public void test06_Init_With_RetrieverClass_Populates_And_PreCleanup() { + RangerUserStoreEnricher enricher = new RangerUserStoreEnricher(); + + RangerServiceDef def = new RangerServiceDef(); + def.setName("svcType"); + + enricher.setServiceName("svc"); + enricher.setServiceDef(def); + enricher.setAppId("app"); + + Map opts = new HashMap<>(); + opts.put(RangerUserStoreEnricher.USERSTORE_RETRIEVER_CLASSNAME_OPTION, DummyRetriever.class.getName()); + + // attach enricherDef options + RangerContextEnricherDef enricherDef = new RangerContextEnricherDef(); + enricherDef.setName("userstore"); + enricherDef.setEnricherOptions(opts); + enricher.setEnricherDef(enricherDef); + + enricher.init(); + + // Dummy retriever returns a store with version 1L + assertEquals(1L, enricher.getUserStoreVersion()); + assertNotNull(enricher.getRangerUserStore()); + + assertTrue(enricher.preCleanup()); + } + + public static class DummyRetriever extends RangerUserStoreRetriever { + @Override + public void init(Map options) { + // no-op + } + + @Override + public RangerUserStore retrieveUserStoreInfo(long lastKnownVersion, long lastActivationTimeInMillis) { + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(1L); + return store; + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerUserStoreRefresher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerUserStoreRefresher.java new file mode 100644 index 0000000000..34f44121ec --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestRangerUserStoreRefresher.java @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.contextenricher; + +import com.sun.jersey.api.client.ClientResponse; +import org.apache.ranger.plugin.util.DownloadTrigger; +import org.apache.ranger.plugin.util.JsonUtilsV2; +import org.apache.ranger.plugin.util.RangerRESTClient; +import org.apache.ranger.plugin.util.RangerServiceNotFoundException; +import org.apache.ranger.plugin.util.RangerUserStore; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.servlet.http.HttpServletResponse; + +import java.io.File; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerUserStoreRefresher { + @Test + public void test01_populateFromRetriever_savesCache_andUpdatesActivation() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + File cache = File.createTempFile("ruserstore-", ".json"); + cache.deleteOnExit(); + + RangerUserStoreRetriever retriever = mock(RangerUserStoreRetriever.class); + RangerUserStoreEnricher enricher = mock(RangerUserStoreEnricher.class); + + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(7L); + + when(retriever.getServiceName()).thenReturn("svc"); + when(retriever.retrieveUserStoreInfo(anyLong(), anyLong())).thenReturn(store); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retriever, enricher, null, -1L, queue, + cache.getAbsolutePath()); + + RangerUserStore ret = refresher.populateUserStoreInfo(); + + assertNotNull(ret); + verify(enricher, times(1)).setRangerUserStore(store); + assertTrue(cache.exists()); + assertTrue(refresher.getLastActivationTimeInMillis() > 0); + } + + @Test + public void test02_populateFromCache_whenRetrieverReturnsNull() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + File cache = File.createTempFile("ruserstore-", ".json"); + cache.deleteOnExit(); + + RangerUserStoreRetriever retrieverForSeed = mock(RangerUserStoreRetriever.class); + RangerUserStoreEnricher enricherForSeed = mock(RangerUserStoreEnricher.class); + when(retrieverForSeed.getServiceName()).thenReturn("svc"); + + RangerUserStoreRefresher seed = new RangerUserStoreRefresher(retrieverForSeed, enricherForSeed, null, -1L, + queue, cache.getAbsolutePath()); + RangerUserStore seedStore = new RangerUserStore(); + seedStore.setUserStoreVersion(10L); + seed.saveToCache(seedStore); + assertTrue(cache.exists()); + + RangerUserStoreRetriever retriever = mock(RangerUserStoreRetriever.class); + RangerUserStoreEnricher enricher = mock(RangerUserStoreEnricher.class); + when(retriever.getServiceName()).thenReturn("svc"); + when(retriever.retrieveUserStoreInfo(anyLong(), anyLong())).thenReturn(null); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retriever, enricher, null, -1L, queue, + cache.getAbsolutePath()); + + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNotNull(ret); + assertEquals(10L, ret.getUserStoreVersion()); + verify(enricher, times(1)).setRangerUserStore(ret); + } + + @Test + public void test03_serviceNotFound_disablesCache_andSetsActivation() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + File cache = File.createTempFile("ruserstore-", ".json"); + cache.deleteOnExit(); + + RangerUserStoreRetriever retriever = mock(RangerUserStoreRetriever.class); + RangerUserStoreEnricher enricher = mock(RangerUserStoreEnricher.class); + + when(retriever.getServiceName()).thenReturn("svc"); + when(enricher.isDisableCacheIfServiceNotFound()).thenReturn(true); + when(retriever.retrieveUserStoreInfo(anyLong(), anyLong())) + .thenThrow(new RangerServiceNotFoundException("svc")); + + // seed a cache file to be disabled + RangerUserStoreRefresher seed = new RangerUserStoreRefresher(retriever, enricher, null, -1L, queue, + cache.getAbsolutePath()); + RangerUserStore seedStore = new RangerUserStore(); + seedStore.setUserStoreVersion(5L); + seed.saveToCache(seedStore); + assertTrue(cache.exists()); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retriever, enricher, null, -1L, queue, + cache.getAbsolutePath()); + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNull(ret); + assertTrue(refresher.getLastActivationTimeInMillis() > 0); + assertTrue(!cache.exists()); + } + + @Test + public void test04_restClient_notModified_returnsNull() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + File cache = File.createTempFile("ruserstore-", ".json"); + cache.deleteOnExit(); + + RangerRESTClient restClient = mock(RangerRESTClient.class); + ClientResponse response = mock(ClientResponse.class); + when(response.getStatus()).thenReturn(HttpServletResponse.SC_NOT_MODIFIED); + when(restClient.get(anyString(), anyMap())).thenReturn(response); + + RangerUserStoreRetriever retrieverForName = mock(RangerUserStoreRetriever.class); + when(retrieverForName.getServiceName()).thenReturn("svc"); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retrieverForName, null, restClient, -1L, queue, + cache.getAbsolutePath()); + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNull(ret); + } + + @Test + public void test05_restClient_ok_readsAndSavesCache() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + File cache = File.createTempFile("ruserstore-", ".json"); + cache.deleteOnExit(); + + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(77L); + String json = JsonUtilsV2.objToJson(store); + + RangerRESTClient restClient = mock(RangerRESTClient.class); + ClientResponse response = mock(ClientResponse.class); + when(response.getStatus()).thenReturn(HttpServletResponse.SC_OK); + when(response.getEntity(String.class)).thenReturn(json); + when(restClient.get(anyString(), anyMap())).thenReturn(response); + RangerUserStoreRetriever retrieverForName = mock(RangerUserStoreRetriever.class); + when(retrieverForName.getServiceName()).thenReturn("svc"); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retrieverForName, null, restClient, -1L, queue, + cache.getAbsolutePath()); + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNotNull(ret); + assertEquals(77L, ret.getUserStoreVersion()); + assertTrue(cache.exists()); + assertTrue(refresher.getLastActivationTimeInMillis() > 0); + } + + @Test + public void test06_restClient_notFound_returnsNull() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + RangerRESTClient restClient = mock(RangerRESTClient.class); + ClientResponse response = mock(ClientResponse.class); + when(response.getStatus()).thenReturn(HttpServletResponse.SC_NOT_FOUND); + when(restClient.get(anyString(), anyMap())).thenReturn(response); + RangerUserStoreRetriever retrieverForName = mock(RangerUserStoreRetriever.class); + when(retrieverForName.getServiceName()).thenReturn("svc"); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retrieverForName, null, restClient, -1L, queue, null); + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNull(ret); + } + + @Test + public void test07_runLoop_processesTrigger_and_stopRefresher() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + RangerUserStoreRetriever retriever = mock(RangerUserStoreRetriever.class); + RangerUserStoreEnricher enricher = mock(RangerUserStoreEnricher.class); + when(retriever.getServiceName()).thenReturn("svc"); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retriever, enricher, null, -1L, queue, null); + refresher.setDaemon(true); + refresher.startRefresher(); + + DownloadTrigger token = new DownloadTrigger(); + queue.put(token); + token.waitForCompletion(); + + refresher.stopRefresher(); + assertTrue(true); + } + + @Test + public void test08_noReceiverNoRestClient_returnsNullAndLogsError() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + RangerUserStoreRetriever retrieverForName = mock(RangerUserStoreRetriever.class); + when(retrieverForName.getServiceName()).thenReturn("svc"); + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retrieverForName, null, null, -1L, queue, null); + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNull(ret); + } + + @Test + public void test09_restClient_internalServerError_returnsNull() throws Exception { + BlockingQueue queue = new LinkedBlockingQueue<>(); + RangerRESTClient restClient = mock(RangerRESTClient.class); + ClientResponse response = mock(ClientResponse.class); + when(response.getStatus()).thenReturn(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + when(restClient.get(anyString(), anyMap())).thenReturn(response); + RangerUserStoreRetriever retrieverForName = mock(RangerUserStoreRetriever.class); + when(retrieverForName.getServiceName()).thenReturn("svc"); + + RangerUserStoreRefresher refresher = new RangerUserStoreRefresher(retrieverForName, null, restClient, -1L, queue, null); + RangerUserStore ret = refresher.populateUserStoreInfo(); + assertNull(ret); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java deleted file mode 100644 index 4dc9452965..0000000000 --- a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.ranger.plugin.contextenricher; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import org.apache.ranger.plugin.contextenricher.TestTagEnricher.TagEnricherTestCase.TestData; -import org.apache.ranger.plugin.model.RangerServiceDef; -import org.apache.ranger.plugin.model.RangerServiceResource; -import org.apache.ranger.plugin.model.RangerTag; -import org.apache.ranger.plugin.model.RangerTagDef; -import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; -import org.apache.ranger.plugin.policyengine.RangerAccessResource; -import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl; -import org.apache.ranger.plugin.policyengine.RangerMutableResource; -import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; -import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType; -import org.apache.ranger.plugin.util.RangerAccessRequestUtil; -import org.apache.ranger.plugin.util.ServiceTags; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -public class TestTagEnricher { - static Gson gsonBuilder; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z") - .setPrettyPrinting() - .registerTypeAdapter(RangerAccessResource.class, new RangerResourceDeserializer()) - .create(); - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Test - public void testRangerTagsForEvalSort() { - List matchTypes = new ArrayList<>(); - - matchTypes.add(null); - matchTypes.add(MatchType.NONE); - matchTypes.add(MatchType.DESCENDANT); - matchTypes.add(MatchType.ANCESTOR); - matchTypes.add(MatchType.SELF_AND_ALL_DESCENDANTS); - matchTypes.add(MatchType.SELF); - - matchTypes.sort(RangerPolicyResourceMatcher.MATCH_TYPE_COMPARATOR); - - assertEquals(matchTypes.get(0), MatchType.SELF); - assertEquals(matchTypes.get(1), MatchType.SELF_AND_ALL_DESCENDANTS); - assertEquals(matchTypes.get(2), MatchType.ANCESTOR); - assertEquals(matchTypes.get(3), MatchType.DESCENDANT); - assertEquals(matchTypes.get(4), MatchType.NONE); - assertNull(matchTypes.get(5)); - } - - @Test - public void testTagEnricher_hive() { - String[] hiveTestResourceFiles = {"/contextenricher/test_tagenricher_hive.json"}; - - runTestsFromResourceFiles(hiveTestResourceFiles); - } - - private void runTestsFromResourceFiles(String[] resourceNames) { - for (String resourceName : resourceNames) { - InputStream inStream = this.getClass().getResourceAsStream(resourceName); - InputStreamReader reader = new InputStreamReader(inStream); - - runTests(reader, resourceName); - } - } - - private void runTests(InputStreamReader reader, String testName) { - TagEnricherTestCase testCase = gsonBuilder.fromJson(reader, TagEnricherTestCase.class); - - assertTrue("invalid input: " + testName, testCase != null && testCase.serviceDef != null && testCase.serviceResources != null && testCase.tests != null); - - ServiceTags serviceTags = new ServiceTags(); - serviceTags.setServiceName(testCase.serviceName); - serviceTags.setTagDefinitions(testCase.tagDefinitions); - serviceTags.setTags(testCase.tags); - serviceTags.setServiceResources(testCase.serviceResources); - serviceTags.setResourceToTagIds(testCase.resourceToTagIds); - - RangerTagEnricher tagEnricher = new RangerTagEnricher(); - - tagEnricher.setServiceName(testCase.serviceName); - tagEnricher.setServiceDef(testCase.serviceDef); - tagEnricher.init(); - tagEnricher.setServiceTags(serviceTags); - - List expectedTags = new ArrayList<>(); - List resultTags = new ArrayList<>(); - - for (TestData test : testCase.tests) { - RangerAccessRequestImpl request = new RangerAccessRequestImpl(test.resource, test.accessType, "testUser", null, null); - - ((RangerMutableResource) request.getResource()).setServiceDef(testCase.serviceDef); - tagEnricher.enrich(request); - - List expected = test.result; - - Set result = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext()); - - expectedTags.clear(); - if (expected != null) { - for (RangerTag tag : expected) { - expectedTags.add(tag.getType()); - } - Collections.sort(expectedTags); - } - - resultTags.clear(); - if (result != null) { - for (RangerTagForEval tag : result) { - resultTags.add(tag.getType()); - } - Collections.sort(resultTags); - } - - assertEquals(test.name, expectedTags, resultTags); - } - } - - static class TagEnricherTestCase { - public String serviceName; - public RangerServiceDef serviceDef; - public Map tagDefinitions; - public Map tags; - public List serviceResources; - public Map> resourceToTagIds; - public List tests; - - static class TestData { - public String name; - public RangerAccessResource resource; - public String accessType; - public List result; - } - } - - static class RangerResourceDeserializer implements JsonDeserializer { - @Override - public RangerAccessResource deserialize(JsonElement jsonObj, Type type, - JsonDeserializationContext context) throws JsonParseException { - return gsonBuilder.fromJson(jsonObj, RangerAccessResourceImpl.class); - } - } -} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestGetFromDataFile.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestGetFromDataFile.java new file mode 100644 index 0000000000..09a8980afd --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestGetFromDataFile.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ranger.plugin.contextenricher.externalretrievers; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.File; +import java.io.FileOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGetFromDataFile { + @Test + public void test01_getFromDataFile_readsPropertiesAndMapsToUserStore() throws Exception { + File tmp = File.createTempFile("userattrs", ".properties"); + try (FileOutputStream fos = new FileOutputStream(tmp)) { + String content = "alice=US\n" + "bob=EU\n"; + fos.write(content.getBytes(StandardCharsets.UTF_8)); + } + + GetFromDataFile gf = new GetFromDataFile(); + Map> out = gf.getFromDataFile(tmp.getAbsolutePath(), "region"); + assertEquals("US", out.get("alice").get("region")); + assertEquals("EU", out.get("bob").get("region")); + } + + @Test + public void test02_getFromDataFile_missingFile_returnsEmpty() { + GetFromDataFile gf = new GetFromDataFile(); + Map> out = gf.getFromDataFile("/path/does/not/exist.props", "attr"); + assertTrue(out.isEmpty()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestGetFromURL.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestGetFromURL.java new file mode 100644 index 0000000000..7a3d39919e --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestGetFromURL.java @@ -0,0 +1,272 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ranger.plugin.contextenricher.externalretrievers; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGetFromURL { + @Test + public void test01_toUserAttributes_flattensListsIntoCommaSeparated() throws Exception { + GetFromURL gu = new GetFromURL(); + Method m = GetFromURL.class.getDeclaredMethod("toUserAttributes", Map.class); + m.setAccessible(true); + + Map>> input = new HashMap<>(); + Map> attrs = new HashMap<>(); + attrs.put("region", new ArrayList() { + { + add("US"); + add("EU"); + } + }); + input.put("alice", attrs); + + @SuppressWarnings("unchecked") + Map> out = (Map>) m.invoke(gu, input); + assertEquals("US,EU", out.get("alice").get("region")); + } + + @Test + public void test02_verifyToken_missingFields_throwsIOException() throws Exception { + GetFromURL gu = new GetFromURL(); + Method decode = GetFromURL.class.getDeclaredMethod("decodeSecrets", String.class); + decode.setAccessible(true); + Method verify = GetFromURL.class.getDeclaredMethod("verifyToken", String.class); + verify.setAccessible(true); + + String bare = "{\"headers\":[],\"params\":[]}"; // missing tokenUrl + String encoded = (String) decode.invoke(gu, Base64.getEncoder().encodeToString(bare.getBytes())); + assertThrows(IOException.class, () -> { + try { + verify.invoke(gu, encoded); + } catch (Exception e) { + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } + throw new RuntimeException(e); + } + }); + } + + public static class Response { + final int status; + final String body; + + Response(int status, String body) { + this.status = status; + this.body = body == null ? "" : body; + } + } + + public static class MiniHttpServer implements AutoCloseable { + private final Map routes; + private ServerSocket server; + private Thread thread; + private volatile boolean running; + + MiniHttpServer(Map routes) { + this.routes = routes; + } + + int start() throws IOException { + server = new ServerSocket(0); + running = true; + thread = new Thread(() -> { + while (running && !server.isClosed()) { + try (Socket socket = server.accept(); + BufferedReader reader = new BufferedReader( + new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); + PrintWriter writer = new PrintWriter( + new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8), true)) { + String requestLine = reader.readLine(); + if (requestLine == null) { + continue; + } + String[] parts = requestLine.split(" "); + String path = parts.length >= 2 ? parts[1] : "/"; + // consume headers + String line; + while ((line = reader.readLine()) != null && !line.isEmpty()) { + /* ignore */ } + Response resp = routes.getOrDefault(path, new Response(404, "")); + byte[] bodyBytes = resp.body.getBytes(StandardCharsets.UTF_8); + writer.printf("HTTP/1.1 %d %s\r\n", resp.status, resp.status == 200 ? "OK" : "ERR"); + writer.printf("Content-Length: %d\r\n", bodyBytes.length); + writer.print("Content-Type: application/json\r\n"); + writer.print("Connection: close\r\n\r\n"); + writer.flush(); + socket.getOutputStream().write(bodyBytes); + socket.getOutputStream().flush(); + } catch (IOException e) { + if (running) { + // ignore transient errors while running + } + } + } + }, "mini-http"); + thread.setDaemon(true); + thread.start(); + return server.getLocalPort(); + } + + @Override + public void close() throws IOException { + running = false; + if (server != null && !server.isClosed()) { + server.close(); + } + try { + if (thread != null) { + thread.join(1000); + } + } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + } + } + } + + @Test + public void test03_getFromURL_withLocalServer_success() throws Exception { + Map routes = new HashMap<>(); + routes.put("/token", new Response(200, "{\"access_token\":\"t123\"}")); + routes.put("/user", new Response(200, "{\"body\":{\"alice\":{\"region\":[\"US\",\"EU\"]}}}")); + try (MiniHttpServer server = new MiniHttpServer(routes)) { + int port = server.start(); + File secrets = File.createTempFile("secrets", ".txt"); + try { + String json = "{\"tokenUrl\":\"http://127.0.0.1:" + port + + "/token\",\"headers\":[{\"Content-Type\":\"application/x-www-form-urlencoded\"}],\"params\":[]}"; + String encoded = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)); + Files.write(secrets.toPath(), encoded.getBytes(StandardCharsets.UTF_8)); + + GetFromURL gu = new GetFromURL(); + Map> out = gu.getFromURL("http://127.0.0.1:" + port + "/user", + secrets.getAbsolutePath()); + assertEquals("US,EU", out.get("alice").get("region")); + } finally { + secrets.delete(); + } + } + } + + @Test + public void test04_getFromURL_httpError_throws() throws Exception { + Map routes = new HashMap<>(); + routes.put("/token", new Response(200, "{\"access_token\":\"t123\"}")); + routes.put("/user", new Response(500, "")); + try (MiniHttpServer server = new MiniHttpServer(routes)) { + int port = server.start(); + File secrets = File.createTempFile("secrets", ".txt"); + try { + String json = "{\"tokenUrl\":\"http://127.0.0.1:" + port + + "/token\",\"headers\":[{\"Content-Type\":\"application/x-www-form-urlencoded\"}],\"params\":[]}"; + String encoded = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)); + Files.write(secrets.toPath(), encoded.getBytes(StandardCharsets.UTF_8)); + + GetFromURL gu = new GetFromURL(); + assertThrows(IOException.class, + () -> gu.getFromURL("http://127.0.0.1:" + port + "/user", secrets.getAbsolutePath())); + } finally { + secrets.delete(); + } + } + } + + @Test + public void test05_getBearerToken_httpError_throws() throws Exception { + Map routes = new HashMap<>(); + routes.put("/badtoken", new Response(400, "")); + routes.put("/user", new Response(200, "{\"body\":{}}")); + try (MiniHttpServer server = new MiniHttpServer(routes)) { + int port = server.start(); + File secrets = File.createTempFile("secrets", ".txt"); + try { + String json = "{\"tokenUrl\":\"http://127.0.0.1:" + port + + "/badtoken\",\"headers\":[{\"Content-Type\":\"application/x-www-form-urlencoded\"}],\"params\":[]}"; + String encoded = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)); + Files.write(secrets.toPath(), encoded.getBytes(StandardCharsets.UTF_8)); + + GetFromURL gu = new GetFromURL(); + assertThrows(IOException.class, + () -> gu.getFromURL("http://127.0.0.1:" + port + "/user", secrets.getAbsolutePath())); + } finally { + secrets.delete(); + } + } + } + + @Test + public void test06_verifyToken_invalidContentType_throws() throws Exception { + GetFromURL gu = new GetFromURL(); + Method verify = GetFromURL.class.getDeclaredMethod("verifyToken", String.class); + verify.setAccessible(true); + String bad = "{\"tokenUrl\":\"http://host/token\",\"headers\":[{\"Content-Type\":\"application/json\"}],\"params\":[]}"; + assertThrows(IOException.class, () -> { + try { + verify.invoke(gu, bad); + } catch (Exception e) { + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } + throw new RuntimeException(e); + } + }); + } + + @Test + public void test07_decodeSecrets_roundTrip() throws Exception { + GetFromURL gu = new GetFromURL(); + Method decode = GetFromURL.class.getDeclaredMethod("decodeSecrets", String.class); + decode.setAccessible(true); + String original = "hello"; + String b64 = Base64.getEncoder().encodeToString(original.getBytes(StandardCharsets.UTF_8)); + String decoded = (String) decode.invoke(gu, b64); + assertEquals(original, decoded); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestRangerMultiSourceUserStoreRetriever.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestRangerMultiSourceUserStoreRetriever.java new file mode 100644 index 0000000000..31890bc8c0 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/externalretrievers/TestRangerMultiSourceUserStoreRetriever.java @@ -0,0 +1,393 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ranger.plugin.contextenricher.externalretrievers; + +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerRole; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.util.RangerRoles; +import org.apache.ranger.plugin.util.RangerRolesUtil; +import org.apache.ranger.plugin.util.RangerUserStore; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerMultiSourceUserStoreRetriever { + @Test + public void test01_toRetrieverOptions_parsesKeyValuePairs() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("toRetrieverOptions", Map.class); + m.setAccessible(true); + Map opts = new HashMap<>(); + opts.put("retriever0_api", "attrName=region, userStoreURL=http://host"); + + @SuppressWarnings("unchecked") + Map> parsed = (Map>) m.invoke(r, opts); + assertEquals("region", parsed.get("retriever0_api").get("attrName")); + assertEquals("http://host", parsed.get("retriever0_api").get("userStoreURL")); + } + + @Test + public void test02_retrieveUserAttrFromRoles_filtersByPrefixAndFlattensValues() { + RangerRoles roles = new RangerRoles(); + Set roleSet = new HashSet<>(); + + RangerRole role1 = new RangerRole(); + role1.setName("region.US"); + role1.setUsers(Arrays.asList(new RangerRole.RoleMember("alice", true))); + roleSet.add(role1); + + RangerRole role2 = new RangerRole(); + role2.setName("region.EU"); + role2.setUsers(Arrays.asList(new RangerRole.RoleMember("alice", true))); + roleSet.add(role2); + + RangerRoles rr = new RangerRoles(); + rr.setRangerRoles(roleSet); + + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + RangerPluginConfig pc = Mockito.mock(RangerPluginConfig.class); + RangerPluginContext ctx = new RangerPluginContext(pc); + r.setPluginContext(ctx); + + Map options = new HashMap<>(); + options.put("attrName", "region"); + + try { + Field f = RangerMultiSourceUserStoreRetriever.class.getDeclaredField("rolesUtil"); + f.setAccessible(true); + f.set(r, new RangerRolesUtil(rr)); + } catch (Exception e) { + throw new RuntimeException(e); + } + + Map> out = r.retrieveUserAttrFromRoles("retriever0_role", options); + assertEquals("US,EU", out.get("alice").get("region")); + } + + @Test + public void test03_retrieveUserStoreInfo_fetchesRolesWhenRoleRetrieverConfigured() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Map enricherOptions = new HashMap<>(); + enricherOptions.put("retriever0_role", "attrName=region"); + + RangerPluginConfig pc = Mockito.mock(RangerPluginConfig.class); + when(pc.getServiceName()).thenReturn("svc"); + when(pc.getAppId()).thenReturn("app"); + when(pc.getPropertyPrefix()).thenReturn("ranger.plugin.svc"); + when(pc.get("ranger.plugin.svc.policy.rest.url")).thenReturn("http://localhost:6080"); + RangerPluginContext ctx = Mockito.spy(new RangerPluginContext(pc)); + + RangerAdminClient admin = Mockito.mock(RangerAdminClient.class); + Mockito.doReturn(admin).when(ctx).createAdminClient(pc); + when(admin.getRolesIfUpdated(Mockito.anyLong(), Mockito.anyLong())).thenReturn(new RangerRoles()); + + r.setPluginContext(ctx); + r.setPluginConfig(pc); + r.init(enricherOptions); + + RangerUserStore store = r.retrieveUserStoreInfo(-1, System.currentTimeMillis()); + assertNotNull(store); + assertNotNull(store.getUserAttrMapping()); + assertTrue(store.getUserAttrMapping().isEmpty()); + } + + @Test + public void test04_toRetrieverOptions_invalidOptions_parsesEmptyValue() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("toRetrieverOptions", String.class, + String.class); + m.setAccessible(true); + @SuppressWarnings("unchecked") + Map parsed = (Map) m.invoke(r, "retriever0_api", + "attrName=region, userStoreURL"); + assertEquals("region", parsed.get("attrName")); + assertTrue(parsed.containsKey("userStoreURL")); + assertEquals("", parsed.get("userStoreURL")); + } + + @Test + public void test05_retrieveAll_withUnknownSource_throws() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Map> opts = new HashMap<>(); + opts.put("retriever9_unknown", new HashMap()); + Field f = RangerMultiSourceUserStoreRetriever.class.getDeclaredField("retrieverOptions"); + f.setAccessible(true); + f.set(r, opts); + + Method retrieveAll = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("retrieveAll"); + retrieveAll.setAccessible(true); + assertThrows(Exception.class, () -> { + try { + retrieveAll.invoke(r); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Test + public void test06_mergeUserAttributes_mergesAndOverwrites() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method merge = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("mergeUserAttributes", Map.class, + Map.class); + merge.setAccessible(true); + Map> dest = new HashMap<>(); + Map alice = new HashMap<>(); + alice.put("region", "US"); + dest.put("alice", alice); + Map> src = new HashMap<>(); + Map alice2 = new HashMap<>(); + alice2.put("dept", "eng"); + alice2.put("region", "EU"); + src.put("alice", alice2); + + merge.invoke(r, src, dest); + assertEquals("EU", dest.get("alice").get("region")); + assertEquals("eng", dest.get("alice").get("dept")); + } + + @Test + public void test07_retrieveUserAttributes_fromDataFile_path() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("retrieveUserAttributes", String.class, + Map.class); + m.setAccessible(true); + File tmp = File.createTempFile("userattrs", ".properties"); + Files.write(tmp.toPath(), "alice=US\n".getBytes(StandardCharsets.UTF_8)); + Map options = new HashMap<>(); + options.put("attrName", "region"); + options.put("dataFile", tmp.getAbsolutePath()); + @SuppressWarnings("unchecked") + Map> out = (Map>) m.invoke(r, "retriever0_api", + options); + assertEquals("US", out.get("alice").get("region")); + } + + @Test + public void test08_retrieveUserAttributes_missingAttrName_throws() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("retrieveUserAttributes", String.class, + Map.class); + m.setAccessible(true); + Map options = new HashMap<>(); + options.put("userStoreURL", "http://host"); + assertThrows(Exception.class, () -> { + try { + m.invoke(r, "retriever0_api", options); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Test + public void test09_retrieveUserAttributes_missingUrlAndDataFile_throws() throws Exception { + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("retrieveUserAttributes", String.class, + Map.class); + m.setAccessible(true); + Map options = new HashMap<>(); + options.put("attrName", "region"); + assertThrows(Exception.class, () -> { + try { + m.invoke(r, "retriever0_api", options); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + public static class Response { + public final int status; + public final String body; + + public Response(int status, String body) { + this.status = status; + this.body = body == null ? "" : body; + } + } + + public static class MiniHttpServer implements AutoCloseable { + private final Map routes; + private ServerSocket server; + private Thread thread; + private volatile boolean running; + + public MiniHttpServer(Map routes) { + this.routes = routes; + } + + public int start() throws IOException { + server = new ServerSocket(0); + running = true; + thread = new Thread(() -> { + while (running && !server.isClosed()) { + try (Socket socket = server.accept(); + BufferedReader reader = new BufferedReader( + new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); + PrintWriter writer = new PrintWriter( + new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8), true)) { + String requestLine = reader.readLine(); + if (requestLine == null) { + continue; + } + String[] parts = requestLine.split(" "); + String path = parts.length >= 2 ? parts[1] : "/"; + String line; + while ((line = reader.readLine()) != null && !line.isEmpty()) { + /* ignore */ } + Response resp = routes.getOrDefault(path, new Response(404, "")); + byte[] bodyBytes = resp.body.getBytes(StandardCharsets.UTF_8); + writer.printf("HTTP/1.1 %d %s\r\n", resp.status, resp.status == 200 ? "OK" : "ERR"); + writer.printf("Content-Length: %d\r\n", bodyBytes.length); + writer.print("Content-Type: application/json\r\n"); + writer.print("Connection: close\r\n\r\n"); + writer.flush(); + socket.getOutputStream().write(bodyBytes); + socket.getOutputStream().flush(); + } catch (IOException e) { + if (running) { + // ignore + } + } + } + }, "mini-http"); + thread.setDaemon(true); + thread.start(); + return server.getLocalPort(); + } + + @Override + public void close() throws IOException { + running = false; + if (server != null && !server.isClosed()) { + server.close(); + } + try { + if (thread != null) { + thread.join(1000); + } + } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + } + } + } + + @Test + public void test10_retrieveUserAttributes_urlSuccess_and_httpError() throws Exception { + // success path + Map routes1 = new HashMap<>(); + routes1.put("/token", new Response(200, "{\"access_token\":\"t123\"}")); + routes1.put("/user", new Response(200, "{\"body\":{\"alice\":{\"region\":[\"US\",\"EU\"]}}}")); + try (MiniHttpServer server = new MiniHttpServer(routes1)) { + int port = server.start(); + File secrets = File.createTempFile("secrets", ".txt"); + try { + String json = "{\"tokenUrl\":\"http://127.0.0.1:" + port + + "/token\",\"headers\":[{\"Content-Type\":\"application/x-www-form-urlencoded\"}],\"params\":[]}"; + String encoded = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)); + Files.write(secrets.toPath(), encoded.getBytes(StandardCharsets.UTF_8)); + + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("retrieveUserAttributes", + String.class, Map.class); + m.setAccessible(true); + Map options = new HashMap<>(); + options.put("attrName", "region"); + options.put("userStoreURL", "http://127.0.0.1:" + port + "/user"); + options.put("configFile", secrets.getAbsolutePath()); + @SuppressWarnings("unchecked") + Map> out = (Map>) m.invoke(r, "retriever0_api", + options); + assertEquals("US,EU", out.get("alice").get("region")); + } finally { + secrets.delete(); + } + } + + // error path: token 400 + Map routes2 = new HashMap<>(); + routes2.put("/badtoken", new Response(400, "")); + routes2.put("/user", new Response(200, "{\"body\":{}}")); + try (MiniHttpServer server = new MiniHttpServer(routes2)) { + int port = server.start(); + File secrets = File.createTempFile("secrets", ".txt"); + try { + String json = "{\"tokenUrl\":\"http://127.0.0.1:" + port + + "/badtoken\",\"headers\":[{\"Content-Type\":\"application/x-www-form-urlencoded\"}],\"params\":[]}"; + String encoded = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)); + Files.write(secrets.toPath(), encoded.getBytes(StandardCharsets.UTF_8)); + + RangerMultiSourceUserStoreRetriever r = new RangerMultiSourceUserStoreRetriever(); + Method m = RangerMultiSourceUserStoreRetriever.class.getDeclaredMethod("retrieveUserAttributes", + String.class, Map.class); + m.setAccessible(true); + Map options = new HashMap<>(); + options.put("attrName", "region"); + options.put("userStoreURL", "http://127.0.0.1:" + port + "/user"); + options.put("configFile", secrets.getAbsolutePath()); + assertThrows(Exception.class, () -> { + try { + m.invoke(r, "retriever0_api", options); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } finally { + secrets.delete(); + } + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestBinarySearchTree.java b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestBinarySearchTree.java new file mode 100644 index 0000000000..4de916ebcf --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestBinarySearchTree.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.geo; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestBinarySearchTree { + @Test + public void test01_insert_and_find() { + BinarySearchTree tree = new BinarySearchTree<>(); + RangerGeolocationData a = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.3", "A"}, 0, true); + RangerGeolocationData b = RangerGeolocationData.create(new String[] {"1.1.1.4", "1.1.1.6", "B"}, 0, true); + RangerGeolocationData c = RangerGeolocationData.create(new String[] {"1.1.1.7", "1.1.1.9", "C"}, 0, true); + tree.insert(b); + tree.insert(a); + tree.insert(c); + + assertEquals("B", tree.find(RangerGeolocationData.ipAddressToLong("1.1.1.5")).getLocationData()[0]); + assertEquals("A", tree.find(RangerGeolocationData.ipAddressToLong("1.1.1.2")).getLocationData()[0]); + assertEquals("C", tree.find(RangerGeolocationData.ipAddressToLong("1.1.1.8")).getLocationData()[0]); + assertNull(tree.find(RangerGeolocationData.ipAddressToLong("1.1.1.10"))); + } + + @Test + public void test02_traversals_preOrder_and_inOrder() { + BinarySearchTree tree = new BinarySearchTree<>(); + RangerGeolocationData a = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.3", "A"}, 0, true); + RangerGeolocationData b = RangerGeolocationData.create(new String[] {"1.1.1.4", "1.1.1.6", "B"}, 0, true); + RangerGeolocationData c = RangerGeolocationData.create(new String[] {"1.1.1.0", "1.1.1.0", "C"}, 0, true); + tree.insert(a); + tree.insert(b); + tree.insert(c); + + List pre = new ArrayList<>(); + List in = new ArrayList<>(); + + tree.preOrderTraverseTree(value -> { + pre.add(value.getLocationData()[0]); + return value; + }); + tree.inOrderTraverseTree(value -> { + in.add(value.getLocationData()[0]); + return value; + }); + + assertEquals(3, pre.size()); + assertEquals(3, in.size()); + assertTrue(in.contains("A") && in.contains("B") && in.contains("C")); + } + + @Test + public void test03_rebalance_changes_structure_but_preserves_find() { + BinarySearchTree tree = new BinarySearchTree<>(); + for (int i = 0; i < 10; i++) { + String start = "10.0.0." + (i * 2 + 1); + String end = "10.0.0." + (i * 2 + 1); + RangerGeolocationData data = RangerGeolocationData.create(new String[] {start, end, "V" + i}, 0, true); + tree.insert(data); + } + + RangerGeolocationData before = tree.find(RangerGeolocationData.ipAddressToLong("10.0.0.1")); + assertNotNull(before); + + tree.rebalance(); + + RangerGeolocationData after = tree.find(RangerGeolocationData.ipAddressToLong("10.0.0.1")); + assertNotNull(after); + } + + @Test + public void test04_node_accessors_and_setRoot() { + BinarySearchTree tree = new BinarySearchTree<>(); + BinarySearchTree.Node node = new BinarySearchTree.Node<>(null); + tree.setRoot(node); + assertNotNull(tree.getRoot()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestGeolocationMetadata.java b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestGeolocationMetadata.java new file mode 100644 index 0000000000..f698b5b2e3 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestGeolocationMetadata.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.geo; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGeolocationMetadata { + @Test + public void test01_create_valid() { + String[] fields = new String[] {"FROM", "TO", "Country", "Region", "City"}; + GeolocationMetadata md = GeolocationMetadata.create(fields, 0); + assertNotNull(md); + assertEquals(3, md.getLocationDataItemNames().length); + assertEquals(0, md.getDataItemNameIndex("Country")); + assertEquals(1, md.getDataItemNameIndex("Region")); + assertEquals(2, md.getDataItemNameIndex("City")); + } + + @Test + public void test02_create_insufficient_returnsNull() { + String[] fields = new String[] {"FROM", "TO"}; + GeolocationMetadata md = GeolocationMetadata.create(fields, 10); + assertNull(md); + } + + @Test + public void test03_getDataItemNameIndex_blankOrAbsent() { + String[] fields = new String[] {"FROM", "TO", "Country"}; + GeolocationMetadata md = GeolocationMetadata.create(fields, 1); + assertEquals(-1, md.getDataItemNameIndex("")); + assertEquals(-1, md.getDataItemNameIndex("Missing")); + } + + @Test + public void test04_toString_containsHeadersAndNames() { + String[] fields = new String[] {"FROM", "TO", "Country", "Region"}; + GeolocationMetadata md = GeolocationMetadata.create(fields, 1); + String s = md.toString(); + assertTrue(s.contains("FROM_IP,TO_IP,")); + assertTrue(s.contains("Country")); + assertTrue(s.contains("Region")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestRangerGeolocationData.java b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestRangerGeolocationData.java new file mode 100644 index 0000000000..a63d44ce0c --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestRangerGeolocationData.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.geo; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerGeolocationData { + @Test + public void test01_create_withDotFormat_validRange() { + String[] fields = new String[] {"1.1.1.1", "1.1.1.10", "US", "CA"}; + RangerGeolocationData data = RangerGeolocationData.create(fields, 0, true); + assertNotNull(data); + assertEquals(0, data.compareToRange(RangerGeolocationData.ipAddressToLong("1.1.1.5"))); + assertTrue(data.compareToRange(RangerGeolocationData.ipAddressToLong("1.1.1.0")) > 0); + assertTrue(data.compareToRange(RangerGeolocationData.ipAddressToLong("1.1.1.11")) < 0); + assertEquals(2, data.getLocationData().length); + } + + @Test + public void test02_create_withNumericFormat_validRange() { + // 10.0.0.1 -> 167772161, 10.0.0.10 -> 167772170 + String[] fields = new String[] {"167772161", "167772170", "IN", "KA"}; + RangerGeolocationData data = RangerGeolocationData.create(fields, 3, false); + assertNotNull(data); + assertEquals(0, data.compareToRange(RangerGeolocationData.ipAddressToLong("10.0.0.5"))); + } + + @Test + public void test03_create_insufficientFields_returnsNull() { + String[] fields = new String[] {"1.1.1.1", "1.1.1.2"}; + RangerGeolocationData data = RangerGeolocationData.create(fields, 1, true); + assertNull(data); + } + + @Test + public void test04_ipAddressToLong_and_unsignedIntToIPAddress_roundTrip() { + long val1 = RangerGeolocationData.ipAddressToLong("10.0.0.1"); + assertEquals(167772161L, val1); + String dotted1 = RangerGeolocationData.unsignedIntToIPAddress(val1); + assertEquals("10.0.0.1", dotted1); + + long val2 = RangerGeolocationData.ipAddressToLong("192.168.1.1"); + assertTrue(val2 < 0); + String dotted2 = RangerGeolocationData.unsignedIntToIPAddress(3232235777L); + assertEquals("192.168.1.1", dotted2); + } + + @Test + public void test05_unsignedIntToIPAddress_zeroOrNegative_returnsEmpty() { + assertEquals("", RangerGeolocationData.unsignedIntToIPAddress(0)); + assertEquals("", RangerGeolocationData.unsignedIntToIPAddress(-10)); + } + + @Test + public void test06_validateAsIP_dotNotationAndNumeric() { + assertTrue(RangerGeolocationData.validateAsIP("8.8.8.8", true)); + assertFalse(RangerGeolocationData.validateAsIP("999.999.999.999", true)); + assertTrue(RangerGeolocationData.validateAsIP("123456", false)); + assertFalse(RangerGeolocationData.validateAsIP("12a34", false)); + } + + @Test + public void test07_ipAddressToLong_invalidReturnsZero() { + assertEquals(0L, RangerGeolocationData.ipAddressToLong("not.an.ip")); + // IPv6 returns 0 as bytes length > 4 + assertEquals(0L, RangerGeolocationData.ipAddressToLong("2001:db8::1")); + } + + @Test + public void test08_compareTo_variousDifferences() { + RangerGeolocationData a = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.5", "US", null}, 0, true); + RangerGeolocationData b = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.5", "US", null}, 0, true); + RangerGeolocationData c = RangerGeolocationData.create(new String[] {"1.1.1.2", "1.1.1.6", "US", null}, 0, true); + RangerGeolocationData d = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.6", "US", null}, 0, true); + RangerGeolocationData e = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.5", "US"}, 0, true); + RangerGeolocationData f = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.5", "US", "AA"}, 0, true); + + assertTrue(a.compareTo(null) > 0); + assertEquals(0, a.compareTo(b)); + assertTrue(a.compareTo(c) < 0); + assertTrue(a.compareTo(d) < 0); + assertTrue(a.compareTo(e) > 0); + assertTrue(a.compareTo(f) != 0); + } + + @Test + public void test09_equals_and_hashCode_caching() { + RangerGeolocationData a = RangerGeolocationData.create(new String[] {"2.2.2.2", "2.2.2.3", "X"}, 0, true); + RangerGeolocationData b = RangerGeolocationData.create(new String[] {"2.2.2.2", "2.2.2.3", "X"}, 0, true); + assertTrue(a.equals(b)); + assertEquals(a.hashCode(), b.hashCode()); + int first = a.hashCode(); + int second = a.hashCode(); + assertEquals(first, second); + } + + @Test + public void test10_toString_containsFromToAndLocation() { + RangerGeolocationData a = RangerGeolocationData.create(new String[] {"3.3.3.3", "3.3.3.4", "Y", "Z"}, 0, true); + String s = a.toString(); + assertTrue(s.contains("from=3.3.3.3")); + assertTrue(s.contains("to=3.3.3.4")); + assertTrue(s.contains("Y")); + assertTrue(s.contains("Z")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestRangerGeolocationDatabase.java b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestRangerGeolocationDatabase.java new file mode 100644 index 0000000000..8f94595b57 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestRangerGeolocationDatabase.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.geo; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerGeolocationDatabase { + @Test + public void test01_getValue_branches_and_valid() { + RangerGeolocationDatabase db = new RangerGeolocationDatabase(); + assertNull(db.getValue(null, "Country")); + assertNull(db.getValue(RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.1", "US"}, 0, true), "")); + + GeolocationMetadata md = GeolocationMetadata.create(new String[] {"FROM", "TO", "Country"}, 0); + db.setMetadata(md); + RangerGeolocationData data = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.1", "US"}, 0, true); + assertEquals("US", db.getValue(data, "Country")); + assertNull(db.getValue(data, "Region")); + + GeolocationMetadata md2 = GeolocationMetadata.create(new String[] {"FROM", "TO", "Country", "Region"}, 0); + db.setMetadata(md2); + RangerGeolocationData oneEntry = RangerGeolocationData.create(new String[] {"1.1.1.1", "1.1.1.1", "X"}, 0, true); + assertNull(db.getValue(oneEntry, "Region")); + } + + @Test + public void test02_find_and_optimize_and_dataMetadataAccessors() { + RangerGeolocationDatabase db = new RangerGeolocationDatabase(); + assertNull(db.find("")); + assertNull(db.find("not.an.ip")); + assertNull(db.find("2001:db8::1")); + + RangerGeolocationData data = RangerGeolocationData.create(new String[] {"2.2.2.2", "2.2.2.3", "Y"}, 0, true); + db.getData().insert(data); + assertEquals(data, db.find("2.2.2.2")); + + assertNotNull(db.getMetadata()); + db.setMetadata(null); + assertNotNull(db.getMetadata()); + + assertNotNull(db.getData()); + db.setData(null); + assertNotNull(db.getData()); + + db.optimize(); + } + + @Test + public void test03_dump_writesToFile() throws IOException { + RangerGeolocationDatabase db = new RangerGeolocationDatabase(); + GeolocationMetadata md = GeolocationMetadata.create(new String[] {"FROM", "TO", "Country", "Region"}, 0); + db.setMetadata(md); + RangerGeolocationData a = RangerGeolocationData.create(new String[] {"3.3.3.3", "3.3.3.4", "US", "CA"}, 0, true); + db.getData().insert(a); + + Path tmp = Files.createTempFile("geo-dump", ".txt"); + try { + ValuePrinter printer = new ValuePrinter<>(tmp.toAbsolutePath().toString()); + db.dump(printer); + String content = new String(Files.readAllBytes(tmp), StandardCharsets.UTF_8); + assertTrue(content.contains("Geolocation metadata")); + assertTrue(content.contains("Dump of geoDatabase")); + assertTrue(content.contains("from=3.3.3.3")); + } finally { + Files.deleteIfExists(tmp); + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestValuePrinter.java b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestValuePrinter.java new file mode 100644 index 0000000000..d6d104528f --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/geo/TestValuePrinter.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.geo; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestValuePrinter { + @Test + public void test01_build_print_process_and_close_toFile() throws IOException { + Path tmp = Files.createTempFile("vp", ".txt"); + try { + ValuePrinter vp = new ValuePrinter<>(tmp.toAbsolutePath().toString()); + vp.build(); + vp.print("header"); + vp.process(new Object() { + public String toString() { + return "line"; + } + }); + vp.close(); + + String content = new String(Files.readAllBytes(tmp), StandardCharsets.UTF_8); + assertTrue(content.contains("header")); + assertTrue(content.contains("line")); + } finally { + Files.deleteIfExists(tmp); + } + } + + @Test + public void test02_build_withBlankFilename_then_print_process_close_noException() { + ValuePrinter vp = new ValuePrinter<>(null); + vp.build(); + vp.print("x"); + vp.process("y"); + vp.close(); + assertNotNull(vp); + } + + @Test + public void test03_build_failure_path_then_continue() { + ValuePrinter vp = new ValuePrinter<>("/root/ranger-unwritable.txt"); + vp.build(); + vp.print("x"); + vp.process("y"); + vp.close(); + assertNotNull(vp); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestAuditFilter.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestAuditFilter.java new file mode 100644 index 0000000000..fe4bead7ed --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestAuditFilter.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.HashMap; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestAuditFilter { + @Test + public void test01_SettersGettersToString() { + AuditFilter f = new AuditFilter(); + f.setAccessResult(AuditFilter.AccessResult.ALLOWED); + HashMap res = new HashMap<>(); + res.put("db", new RangerPolicyResource("db1")); + f.setResources(res); + f.setAccessTypes(Arrays.asList("read")); + f.setActions(Arrays.asList("OPEN")); + f.setUsers(Arrays.asList("u1")); + f.setGroups(Arrays.asList("g1")); + f.setRoles(Arrays.asList("r1")); + f.setAction(Boolean.TRUE); // note: method name is setAction but sets isAudited + + Assertions.assertEquals(AuditFilter.AccessResult.ALLOWED, f.getAccessResult()); + Assertions.assertTrue(f.getResources().containsKey("db")); + Assertions.assertEquals(Boolean.TRUE, f.getIsAudited()); + + String s = f.toString(); + Assertions.assertTrue(s.contains("isAudited=true")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestGroupInfo.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestGroupInfo.java new file mode 100644 index 0000000000..2f9445da56 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestGroupInfo.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGroupInfo { + @Test + public void test01_ConstructorsAndSetters() { + GroupInfo g1 = new GroupInfo(); + Assertions.assertNotNull(g1.getOtherAttributes()); + + GroupInfo g2 = new GroupInfo("dev", "desc", new HashMap() { + { + put("k", "v"); + } + }); + Assertions.assertEquals("dev", g2.getName()); + Assertions.assertEquals("desc", g2.getDescription()); + Assertions.assertEquals("v", g2.getOtherAttributes().get("k")); + + String s = g2.toString(); + Assertions.assertTrue(s.contains("name=dev")); + Assertions.assertTrue(s.contains("otherAttributes={k, [v],}")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerBaseModelObject.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerBaseModelObject.java new file mode 100644 index 0000000000..7b5a5a8ba6 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerBaseModelObject.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerBaseModelObject { + @Test + public void test01_nullSafeSupplierV1() { + RangerBaseModelObject.setNullSafeSupplier((RangerBaseModelObject.NullSafeSupplier) null); + + List listCopy = RangerBaseModelObject.nullSafeList(Arrays.asList("a")); + Set setCopy = RangerBaseModelObject.nullSafeSet(new HashSet<>(Collections.singleton("b"))); + Map mapCopy = RangerBaseModelObject.nullSafeMap(Collections.singletonMap("k", "v")); + + Assertions.assertEquals(Arrays.asList("a"), listCopy); + Assertions.assertEquals(new HashSet<>(Collections.singleton("b")), setCopy); + Assertions.assertEquals("v", mapCopy.get("k")); + + Assertions.assertTrue(RangerBaseModelObject.nullSafeList(null).isEmpty()); + Assertions.assertTrue(RangerBaseModelObject.nullSafeSet(null).isEmpty()); + Assertions.assertTrue(RangerBaseModelObject.nullSafeMap(null).isEmpty()); + } + + @Test + public void test02_nullSafeSupplierV2() { + RangerBaseModelObject.setNullSafeSupplier(RangerBaseModelObject.NULL_SAFE_SUPPLIER_V2); + + List emptyList = RangerBaseModelObject.nullSafeList(null); + Set emptySet = RangerBaseModelObject.nullSafeSet(null); + Map emptyMap = RangerBaseModelObject.nullSafeMap(null); + Assertions.assertSame(Collections.emptyList(), emptyList); + Assertions.assertSame(Collections.emptySet(), emptySet); + Assertions.assertSame(Collections.emptyMap(), emptyMap); + + List base = new ArrayList<>(Arrays.asList("x")); + Assertions.assertSame(base, RangerBaseModelObject.nullSafeList(base)); + } + + @Test + public void test03_getUpdatableFactories() { + List l1 = RangerBaseModelObject.getUpdatableList(null); + List l2 = RangerBaseModelObject.getUpdatableList(Collections.singletonList("a")); + List l3 = RangerBaseModelObject.getUpdatableList(new ArrayList<>(Arrays.asList("a"))); + Assertions.assertTrue(l1.isEmpty()); + Assertions.assertEquals(Arrays.asList("a"), l2); + Assertions.assertSame(l3, RangerBaseModelObject.getUpdatableList(l3)); + + Set s1 = RangerBaseModelObject.getUpdatableSet(null); + Set s2 = RangerBaseModelObject.getUpdatableSet(new HashSet<>(Collections.singleton("z"))); + Set s3 = RangerBaseModelObject.getUpdatableSet(new HashSet<>(Collections.singleton("z"))); + Assertions.assertTrue(s1.isEmpty()); + Assertions.assertTrue(s2.contains("z")); + Assertions.assertTrue(s3.contains("z")); + + Map m1 = RangerBaseModelObject.getUpdatableMap(null); + Map m2 = RangerBaseModelObject.getUpdatableMap(Collections.singletonMap("k", "v")); + Map m3 = RangerBaseModelObject.getUpdatableMap(new HashMap<>()); + Assertions.assertTrue(m1.isEmpty()); + Assertions.assertEquals("v", m2.get("k")); + Assertions.assertSame(m3, RangerBaseModelObject.getUpdatableMap(m3)); + } + + @Test + public void test04_updateFromAndDefaults() { + RangerBaseModelObject src = new RangerBaseModelObject(); + src.setIsEnabled(Boolean.FALSE); + + RangerBaseModelObject dest = new RangerBaseModelObject(); + dest.updateFrom(src); + Assertions.assertEquals(Boolean.FALSE, dest.getIsEnabled()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerDatasetHeader.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerDatasetHeader.java new file mode 100644 index 0000000000..3f2a67e370 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerDatasetHeader.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerGds.GdsShareStatus; +import org.apache.ranger.plugin.model.RangerPrincipal.PrincipalType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.EnumMap; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerDatasetHeader { + @Test + public void test01_headerInfoSettersAndGetters() { + RangerDatasetHeader.RangerDatasetHeaderInfo info = new RangerDatasetHeader.RangerDatasetHeaderInfo(); + info.setGuid("g"); + info.setName("ds"); + info.setPermissionForCaller("read"); + info.setProjectsCount(3L); + info.setResourceCount(10L); + + EnumMap shares = new EnumMap<>(GdsShareStatus.class); + shares.put(GdsShareStatus.ACTIVE, 2L); + info.setDataSharesCountByStatus(shares); + + EnumMap principals = new EnumMap<>(PrincipalType.class); + principals.put(PrincipalType.USER, 5L); + info.setPrincipalsCountByType(principals); + + Assertions.assertEquals("g", info.getGuid()); + Assertions.assertEquals("ds", info.getName()); + Assertions.assertEquals("read", info.getPermissionForCaller()); + Assertions.assertEquals(3L, info.getProjectsCount()); + Assertions.assertEquals(10L, info.getResourceCount()); + Assertions.assertEquals(2L, info.getDataSharesCountByStatus().get(RangerGds.GdsShareStatus.ACTIVE)); + Assertions.assertEquals(5L, info.getPrincipalsCountByType().get(RangerPrincipal.PrincipalType.USER)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerGds.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerGds.java new file mode 100644 index 0000000000..e616355aaa --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerGds.java @@ -0,0 +1,312 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerGds.DataShareInDatasetSummary; +import org.apache.ranger.plugin.model.RangerGds.DataShareSummary; +import org.apache.ranger.plugin.model.RangerGds.DatasetSummary; +import org.apache.ranger.plugin.model.RangerGds.DatasetsSummary; +import org.apache.ranger.plugin.model.RangerGds.GdsPermission; +import org.apache.ranger.plugin.model.RangerGds.GdsShareStatus; +import org.apache.ranger.plugin.model.RangerGds.RangerDataShare; +import org.apache.ranger.plugin.model.RangerGds.RangerDataShareInDataset; +import org.apache.ranger.plugin.model.RangerGds.RangerDataset; +import org.apache.ranger.plugin.model.RangerGds.RangerDatasetInProject; +import org.apache.ranger.plugin.model.RangerGds.RangerGdsBaseModelObject; +import org.apache.ranger.plugin.model.RangerGds.RangerGdsMaskInfo; +import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL; +import org.apache.ranger.plugin.model.RangerGds.RangerProject; +import org.apache.ranger.plugin.model.RangerGds.RangerSharedResource; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerPrincipal.PrincipalType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerGds { + @Test + public void test01_baseModelObjectToString() { + RangerGdsBaseModelObject base = new RangerGdsBaseModelObject(); + base.setGuid("g1"); + base.setDescription("desc"); + Map opts = new HashMap<>(); + opts.put("k", "v"); + base.setOptions(opts); + Map add = new HashMap<>(); + add.put("a", "b"); + base.setAdditionalInfo(add); + + String s = base.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("description={desc}")); + Assertions.assertTrue(s.contains("options={")); + Assertions.assertTrue(s.contains("additionalInfo={")); + } + + @Test + public void test02_datasetToString() { + RangerDataset ds = new RangerDataset(); + ds.setName("ds1"); + ds.setAcl(new RangerGdsObjectACL()); + ds.setValiditySchedule(new RangerValiditySchedule()); + ds.setTermsOfUse("terms"); + List labels = new ArrayList<>(); + labels.add("L1"); + ds.setLabels(labels); + List keywords = new ArrayList<>(); + keywords.add("K1"); + ds.setKeywords(keywords); + + String s = ds.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("RangerDataset={")); + Assertions.assertTrue(s.contains("name={ds1}")); + Assertions.assertTrue(s.contains("termsOfUse={terms}")); + } + + @Test + public void test03_projectToString() { + RangerProject pr = new RangerProject(); + pr.setName("p1"); + pr.setAcl(new RangerGdsObjectACL()); + pr.setValiditySchedule(new RangerValiditySchedule()); + pr.setTermsOfUse("termsP"); + String s = pr.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("RangerProject={")); + Assertions.assertTrue(s.contains("name={p1}")); + Assertions.assertTrue(s.contains("termsOfUse={termsP}")); + } + + @Test + public void test04_dataShareToString() { + RangerDataShare ds = new RangerDataShare(); + ds.setName("share1"); + ds.setAcl(new RangerGdsObjectACL()); + ds.setService("svc"); + ds.setZone("zone"); + ds.setConditionExpr("x > 5"); + List masks = new ArrayList<>(); + RangerGdsMaskInfo mi = new RangerGdsMaskInfo(); + mi.setValues(new ArrayList<>()); + mi.setMaskInfo(new RangerPolicyItemDataMaskInfo("MASK", null, null)); + masks.add(mi); + ds.setDefaultTagMasks(masks); + + Set access = new HashSet<>(); + access.add("read"); + ds.setDefaultAccessTypes(access); + ds.setTermsOfUse("termsS"); + + String s = ds.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("RangerDataShare={")); + Assertions.assertTrue(s.contains("defaultAccessTypes={")); + Assertions.assertTrue(s.contains("defaultTagMasks={")); + } + + @Test + public void test05_sharedResourceToString() { + RangerSharedResource sr = new RangerSharedResource(); + sr.setName("res1"); + sr.setDataShareId(9L); + Map res = new HashMap<>(); + res.put("db", new RangerPolicyResource()); + sr.setResource(res); + sr.setSubResource(new RangerPolicyResource()); + sr.setSubResourceType("table"); + sr.setConditionExpr("a=1"); + Set accessTypes = new HashSet<>(); + accessTypes.add("use"); + sr.setAccessTypes(accessTypes); + sr.setRowFilter(new RangerPolicyItemRowFilterInfo("dept = 'hr'")); + List subMasks = new ArrayList<>(); + subMasks.add(new RangerGdsMaskInfo()); + sr.setSubResourceMasks(subMasks); + Set profiles = new HashSet<>(); + profiles.add("p1"); + sr.setProfiles(profiles); + + String s = sr.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("RangerSharedResource={")); + Assertions.assertTrue(s.contains("rowFilterInfo={")); + Assertions.assertTrue(s.contains("profiles={")); + } + + @Test + public void test06_maskInfoToString() { + RangerGdsMaskInfo mi = new RangerGdsMaskInfo(); + List vals = new ArrayList<>(); + vals.add("v"); + mi.setValues(vals); + mi.setMaskInfo(new RangerPolicyItemDataMaskInfo("MASK", "c", "x")); + String s = mi.toString(); + Assertions.assertTrue(s.contains("RangerGdsMaskInfo={")); + Assertions.assertTrue(s.contains("values=")); + Assertions.assertTrue(s.contains("maskInfo=")); + } + + @Test + public void test07_dataShareInDatasetToString() { + RangerDataShareInDataset did = new RangerDataShareInDataset(); + did.setDataShareId(1L); + did.setDatasetId(2L); + did.setStatus(GdsShareStatus.ACTIVE); + did.setValiditySchedule(new RangerValiditySchedule()); + Set profiles = new HashSet<>(); + profiles.add("p"); + did.setProfiles(profiles); + did.setApprover("root"); + String s = did.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("RangerDataShareInDataset={")); + Assertions.assertTrue(s.contains("status={ACTIVE}")); + } + + @Test + public void test08_datasetInProjectToString() { + RangerDatasetInProject dip = new RangerDatasetInProject(); + dip.setDatasetId(3L); + dip.setProjectId(4L); + dip.setStatus(GdsShareStatus.REQUESTED); + dip.setValiditySchedule(new RangerValiditySchedule()); + Set profiles = new HashSet<>(); + profiles.add("q"); + dip.setProfiles(profiles); + dip.setApprover("boss"); + String s = dip.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("RangerDatasetInProject={")); + Assertions.assertTrue(s.contains("datasetGuid={")); + Assertions.assertTrue(s.contains("projectGuid={")); + } + + @Test + public void test09_aclToString() { + RangerGdsObjectACL acl = new RangerGdsObjectACL(); + Map users = new HashMap<>(); + users.put("u", GdsPermission.ADMIN); + Map groups = new HashMap<>(); + groups.put("g", GdsPermission.VIEW); + Map roles = new HashMap<>(); + roles.put("r", GdsPermission.LIST); + acl.setUsers(users); + acl.setGroups(groups); + acl.setRoles(roles); + String s = acl.toString(); + Assertions.assertTrue(s.contains("RangerGdsObjectACL={")); + Assertions.assertTrue(s.contains("users={")); + Assertions.assertTrue(s.contains("groups={")); + Assertions.assertTrue(s.contains("roles={")); + } + + @Test + public void test10_datasetSummaryToString() { + DatasetSummary sum = new DatasetSummary(); + sum.setName("ds"); + sum.setDescription("d"); + sum.setPermissionForCaller(GdsPermission.VIEW); + Map pc = new HashMap<>(); + pc.put(PrincipalType.USER, 2); + sum.setPrincipalsCount(pc); + Map ap = new HashMap<>(); + ap.put(PrincipalType.GROUP, 1); + sum.setAclPrincipalsCount(ap); + sum.setProjectsCount(5L); + sum.setTotalResourceCount(7L); + sum.setValiditySchedule(new RangerValiditySchedule()); + List shares = new ArrayList<>(); + shares.add(new DataShareInDatasetSummary()); + sum.setDataShares(shares); + List labels = new ArrayList<>(); + labels.add("L"); + sum.setLabels(labels); + List keywords = new ArrayList<>(); + keywords.add("K"); + sum.setKeywords(keywords); + String s = sum.toString(); + Assertions.assertTrue(s.contains("DatasetSummary={")); + Assertions.assertTrue(s.contains("permissionForCaller={VIEW}")); + } + + @Test + public void test11_datasetsSummaryToStringAndGetters() { + Map> info = new HashMap<>(); + Map inner = new HashMap<>(); + inner.put("key", 1); + info.put("outer", inner); + DatasetsSummary dss = new DatasetsSummary(null, info); + Assertions.assertEquals(info, dss.getAdditionalInfo()); + String s = dss.toString(); + Assertions.assertTrue(s.contains("DatasetsSummary={")); + Assertions.assertTrue(s.contains("additionalInfo={")); + } + + @Test + public void test12_dataShareSummaryToString() { + DataShareSummary sum = new DataShareSummary(); + sum.setName("s"); + sum.setDescription("d"); + sum.setPermissionForCaller(GdsPermission.POLICY_ADMIN); + sum.setResourceCount(2L); + sum.setServiceId(11L); + sum.setServiceName("svc"); + sum.setServiceType("hive"); + sum.setZoneId(3L); + sum.setZoneName("z"); + List lst = new ArrayList<>(); + lst.add(new DataShareInDatasetSummary()); + sum.setDatasets(lst); + String s = sum.toString(); + Assertions.assertTrue(s.contains("DataShareSummary={")); + Assertions.assertTrue(s.contains("serviceType={hive}")); + } + + @Test + public void test13_dataShareInDatasetSummaryToString() { + DataShareInDatasetSummary sum = new DataShareInDatasetSummary(); + sum.setDatasetName("d"); + sum.setDatasetId(1L); + sum.setDataShareId(2L); + sum.setDataShareName("s"); + sum.setServiceId(3L); + sum.setServiceName("svc"); + sum.setZoneId(4L); + sum.setZoneName("z"); + sum.setResourceCount(5L); + sum.setShareStatus(GdsShareStatus.GRANTED); + sum.setApprover("a"); + String s = sum.toString(); + Assertions.assertTrue(s.contains("DataShareInDatasetSummary={")); + Assertions.assertTrue(s.contains("shareStatus={GRANTED}")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerGrant.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerGrant.java new file mode 100644 index 0000000000..91d82a605c --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerGrant.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerGrant { + @Test + public void test01_constructorAndGettersSetters() { + RangerPrincipal principal = new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "alice"); + List access = new ArrayList<>(Arrays.asList("read", "write")); + List conditions = new ArrayList<>(); + conditions.add(new RangerGrant.Condition("ip", new ArrayList<>(Arrays.asList("10.0.0.1")))); + + RangerGrant grant = new RangerGrant(principal, access, conditions); + + Assertions.assertEquals(principal, grant.getPrincipal()); + Assertions.assertEquals(access, grant.getAccessTypes()); + Assertions.assertEquals(conditions, grant.getConditions()); + + RangerPrincipal bob = new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "bob"); + grant.setPrincipal(bob); + Assertions.assertEquals(bob, grant.getPrincipal()); + } + + @Test + public void test02_setAccessTypes_replacesAndSkipsWhenSameInstance() { + RangerGrant grant = new RangerGrant(); + + List first = new ArrayList<>(Arrays.asList("a", "b")); + grant.setAccessTypes(first); + Assertions.assertEquals(first, grant.getAccessTypes()); + + // pass the same backing instance to hit the early-return branch + List internal = grant.getAccessTypes(); + grant.setAccessTypes(internal); + Assertions.assertEquals(internal, grant.getAccessTypes()); + + // replace with a new list and ensure contents are copied (not same ref) + List second = new ArrayList<>(Arrays.asList("x", "y", "z")); + grant.setAccessTypes(second); + Assertions.assertEquals(second, grant.getAccessTypes()); + Assertions.assertNotSame(second, grant.getAccessTypes()); + } + + @Test + public void test03_setConditions_replacesAndSkipsWhenSameInstance() { + RangerGrant grant = new RangerGrant(); + + List c1 = new ArrayList<>(); + c1.add(new RangerGrant.Condition("k1", new ArrayList<>(Arrays.asList("v1")))); + grant.setConditions(c1); + Assertions.assertEquals(c1, grant.getConditions()); + + List internal = grant.getConditions(); + grant.setConditions(internal); + Assertions.assertEquals(internal, grant.getConditions()); + + List c2 = new ArrayList<>(); + c2.add(new RangerGrant.Condition("k2", new ArrayList<>(Arrays.asList("v2", "v3")))); + grant.setConditions(c2); + Assertions.assertEquals(c2, grant.getConditions()); + Assertions.assertNotSame(c2, grant.getConditions()); + } + + @Test + public void test04_equalsAndHashCode() { + RangerPrincipal principal = new RangerPrincipal(RangerPrincipal.PrincipalType.GROUP, "dev"); + List access = new ArrayList<>(Arrays.asList("read")); + List conditions = new ArrayList<>(); + conditions.add(new RangerGrant.Condition("loc", new ArrayList<>(Arrays.asList("us")))); + + RangerGrant g1 = new RangerGrant(principal, access, conditions); + RangerGrant g2 = new RangerGrant(principal, new ArrayList<>(access), new ArrayList<>(conditions)); + Assertions.assertEquals(g1, g2); + Assertions.assertEquals(g1.hashCode(), g2.hashCode()); + + g2.setPrincipal(new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "charlie")); + Assertions.assertNotEquals(g1, g2); + + Assertions.assertNotEquals(g1, null); + Assertions.assertNotEquals(g1, new Object()); + } + + @Test + public void test05_toStringWithPrincipal() { + RangerGrant grant = new RangerGrant(); + grant.setPrincipal(new RangerPrincipal(RangerPrincipal.PrincipalType.ROLE, "role1")); + grant.setAccessTypes(new ArrayList<>(Arrays.asList("use"))); + grant.setConditions(new ArrayList<>()); + + String s = grant.toString(); + Assertions.assertTrue(s.contains("RangerGrant{")); + Assertions.assertTrue(s.contains("accessTypes")); + Assertions.assertTrue(s.contains("conditions")); + } + + @Test + public void test06_conditionEqualsHashCodeToString() { + RangerGrant.Condition c1 = new RangerGrant.Condition("typeA", new ArrayList<>(Arrays.asList("v1", "v2"))); + RangerGrant.Condition c2 = new RangerGrant.Condition("typeA", new ArrayList<>(Arrays.asList("v1", "v2"))); + Assertions.assertEquals(c1, c2); + Assertions.assertEquals(c1.hashCode(), c2.hashCode()); + + c2.setType("typeB"); + Assertions.assertNotEquals(c1, c2); + + String s = c1.toString(); + Assertions.assertTrue(s.contains("type='typeA'")); + Assertions.assertTrue(Objects.nonNull(c1.getValues())); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerHealth.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerHealth.java index 97530991e1..32fdcc9d59 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerHealth.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerHealth.java @@ -19,8 +19,12 @@ package org.apache.ranger.plugin.model; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.HashMap; import java.util.LinkedHashMap; @@ -29,6 +33,12 @@ import static org.apache.ranger.plugin.model.RangerServerHealth.RangerServerStatus.DOWN; import static org.apache.ranger.plugin.model.RangerServerHealth.RangerServerStatus.UP; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerHealth { @Test public void testRangerStatusUP() { @@ -59,9 +69,9 @@ public void testRangerStatusUP() { RangerServerHealth rangerHealth = RangerServerHealth.up().withDetail("components", componentsMap).build(); - Assert.assertEquals("RangerHealth.up()", UP, rangerHealth.getStatus()); - Assert.assertEquals("RangerHealth.getDetails()", 1, rangerHealth.getDetails().size()); - Assert.assertEquals("RangerHealth.getDetails('component')", 2, ((Map) rangerHealth.getDetails().get("components")).size()); + Assertions.assertEquals(UP, rangerHealth.getStatus(), "RangerHealth.up()"); + Assertions.assertEquals(1, rangerHealth.getDetails().size(), "RangerHealth.getDetails()"); + Assertions.assertEquals(2, ((Map) rangerHealth.getDetails().get("components")).size(), "RangerHealth.getDetails('component')"); } @Test @@ -92,8 +102,84 @@ public void testRangerStatusDOWN() { RangerServerHealth rangerHealth = RangerServerHealth.down().withDetail("components", componentsMap).build(); - Assert.assertEquals("RangerHealth.down()", DOWN, rangerHealth.getStatus()); - Assert.assertEquals("RangerHealth.getDetails()", 1, rangerHealth.getDetails().size()); - Assert.assertEquals("RangerHealth.getDetails('component')", 2, ((Map) rangerHealth.getDetails().get("components")).size()); + Assertions.assertEquals(DOWN, rangerHealth.getStatus(), "RangerHealth.down()"); + Assertions.assertEquals(1, rangerHealth.getDetails().size(), "RangerHealth.getDetails()"); + Assertions.assertEquals(2, ((Map) rangerHealth.getDetails().get("components")).size(), "RangerHealth.getDetails('component')"); + } + + @Test + public void testRangerStatusUnknownToStringAndImmutability() { + RangerServerHealth unknown = RangerServerHealth.unknown().build(); + + Assertions.assertEquals(RangerServerHealth.RangerServerStatus.UNKNOWN, unknown.getStatus()); + Assertions.assertTrue(unknown.getDetails().isEmpty()); + Assertions.assertEquals("UNKNOWN {}", unknown.toString()); + + try { + unknown.getDetails().put("x", "y"); + Assertions.fail("details map should be unmodifiable"); + } catch (UnsupportedOperationException expected) { + // expected + } + } + + @Test + public void testStatusInitializingAndInitFailure() { + RangerServerHealth initializing = RangerServerHealth.status(RangerServerHealth.RangerServerStatus.INITIALIZING) + .withDetail("phase", "boot").build(); + RangerServerHealth initFailure = RangerServerHealth.status(RangerServerHealth.RangerServerStatus.INITIALIZATION_FAILURE) + .withDetail("error", "db").build(); + + Assertions.assertEquals(RangerServerHealth.RangerServerStatus.INITIALIZING, initializing.getStatus()); + Assertions.assertEquals("boot", initializing.getDetails().get("phase")); + + Assertions.assertEquals(RangerServerHealth.RangerServerStatus.INITIALIZATION_FAILURE, initFailure.getStatus()); + Assertions.assertEquals("db", initFailure.getDetails().get("error")); + } + + @Test + public void testBuilderConstructors() { + RangerServerHealth.Builder defaultBuilder = new RangerServerHealth.Builder(); + RangerServerHealth def = defaultBuilder.build(); + Assertions.assertEquals(RangerServerHealth.RangerServerStatus.UNKNOWN, def.getStatus()); + Assertions.assertTrue(def.getDetails().isEmpty()); + + RangerServerHealth.Builder upBuilder = new RangerServerHealth.Builder(RangerServerHealth.RangerServerStatus.UP); + RangerServerHealth upHealth = upBuilder.withDetail("k", "v").build(); + Assertions.assertEquals(RangerServerHealth.RangerServerStatus.UP, upHealth.getStatus()); + Assertions.assertEquals("v", upHealth.getDetails().get("k")); + + Map seed = new LinkedHashMap<>(); + seed.put("a", 1); + seed.put("b", 2); + RangerServerHealth.Builder seeded = new RangerServerHealth.Builder(RangerServerHealth.RangerServerStatus.DOWN, seed); + RangerServerHealth downHealth = seeded.build(); + Assertions.assertEquals(RangerServerHealth.RangerServerStatus.DOWN, downHealth.getStatus()); + Assertions.assertEquals(2, downHealth.getDetails().size()); + Assertions.assertEquals(1, downHealth.getDetails().get("a")); + Assertions.assertEquals(2, downHealth.getDetails().get("b")); + } + + @Test + public void testEqualsAndHashCode() { + Map details1 = new LinkedHashMap<>(); + details1.put("x", 1); + details1.put("y", 2); + + Map details2 = new LinkedHashMap<>(); + details2.put("x", 1); + details2.put("y", 2); + + RangerServerHealth h1 = new RangerServerHealth.Builder(RangerServerHealth.RangerServerStatus.UP, details1).build(); + RangerServerHealth h2 = new RangerServerHealth.Builder(RangerServerHealth.RangerServerStatus.UP, details2).build(); + RangerServerHealth h3 = new RangerServerHealth.Builder(RangerServerHealth.RangerServerStatus.DOWN, details1).build(); + + Assertions.assertEquals(h1, h1); // reflexive + Assertions.assertEquals(h1, h2); + Assertions.assertEquals(h1.hashCode(), h2.hashCode()); + + Assertions.assertNotEquals(h1, h3); + Assertions.assertNotEquals(h1, null); + Assertions.assertNotEquals(h1, "not-a-health"); } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerMetrics.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerMetrics.java new file mode 100644 index 0000000000..7295cb9a20 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerMetrics.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerMetrics { + @Test + public void test01_DefaultsAndSetter() { + RangerMetrics m = new RangerMetrics(); + Assertions.assertNull(m.getData()); + HashMap d = new HashMap<>(); + d.put("k", "v"); + m.setData(d); + Assertions.assertEquals("v", m.getData().get("k")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPluginInfo.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPluginInfo.java new file mode 100644 index 0000000000..2c7ec5514e --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPluginInfo.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Date; +import java.util.HashMap; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPluginInfo { + @Test + public void test01_InfoMapDefaultingAndToString() { + RangerPluginInfo info = new RangerPluginInfo(); + Assertions.assertNotNull(info.getInfo()); + + info.setInfo(null); + Assertions.assertNotNull(info.getInfo()); + + info.setServiceName("svc"); + info.setServiceDisplayName("svc-dn"); + info.setServiceType("type"); + info.setServiceTypeDisplayName("type-dn"); + info.setHostName("host"); + info.setAppType("app"); + info.setIpAddress("1.2.3.4"); + info.setId(10L); + Date now = new Date(); + info.setCreateTime(now); + info.setUpdateTime(now); + + String s = info.toString(); + Assertions.assertNotNull(s); + Assertions.assertTrue(s.contains("serviceName={svc}")); + Assertions.assertTrue(s.contains("serviceType={type}")); + Assertions.assertTrue(s.contains("hostName={host}")); + } + + @Test + public void test02_PolicyFields() { + RangerPluginInfo info = new RangerPluginInfo(); + Assertions.assertNull(info.getPolicyDownloadTime()); + Assertions.assertNull(info.getPolicyDownloadedVersion()); + Assertions.assertNull(info.getPolicyActivationTime()); + Assertions.assertNull(info.getPolicyActiveVersion()); + + info.setPolicyDownloadTime(100L); + info.setPolicyDownloadedVersion(2L); + info.setPolicyActivationTime(200L); + info.setPolicyActiveVersion(3L); + + Assertions.assertEquals(100L, info.getPolicyDownloadTime()); + Assertions.assertEquals(2L, info.getPolicyDownloadedVersion()); + Assertions.assertEquals(200L, info.getPolicyActivationTime()); + Assertions.assertEquals(3L, info.getPolicyActiveVersion()); + + // ensure underlying map stores strings + Assertions.assertInstanceOf(String.class, info.getInfo().get(RangerPluginInfo.PLUGIN_INFO_POLICY_DOWNLOAD_TIME)); + } + + @Test + public void test03_TagFields() { + RangerPluginInfo info = new RangerPluginInfo(); + info.setTagDownloadTime(10L); + info.setTagDownloadedVersion(20L); + info.setTagActivationTime(30L); + info.setTagActiveVersion(40L); + + Assertions.assertEquals(10L, info.getTagDownloadTime()); + Assertions.assertEquals(20L, info.getTagDownloadedVersion()); + Assertions.assertEquals(30L, info.getTagActivationTime()); + Assertions.assertEquals(40L, info.getTagActiveVersion()); + } + + @Test + public void test04_RoleFields() { + RangerPluginInfo info = new RangerPluginInfo(); + info.setRoleDownloadTime(11L); + info.setRoleDownloadedVersion(22L); + info.setRoleActivationTime(33L); + info.setRoleActiveVersion(44L); + + Assertions.assertEquals(11L, info.getRoleDownloadTime()); + Assertions.assertEquals(22L, info.getRoleDownloadedVersion()); + Assertions.assertEquals(33L, info.getRoleActivationTime()); + Assertions.assertEquals(44L, info.getRoleActiveVersion()); + } + + @Test + public void test05_UserStoreFields() { + RangerPluginInfo info = new RangerPluginInfo(); + info.setUserStoreDownloadTime(111L); + info.setUserStoreDownloadedVersion(222L); + info.setUserStoreActivationTime(333L); + info.setUserStoreActiveVersion(444L); + + Assertions.assertEquals(111L, info.getUserStoreDownloadTime()); + Assertions.assertEquals(222L, info.getUserStoreDownloadedVersion()); + Assertions.assertEquals(333L, info.getUserStoreActivationTime()); + Assertions.assertEquals(444L, info.getUserStoreActiveVersion()); + } + + @Test + public void test06_GdsFieldsAndCapabilities() { + RangerPluginInfo info = new RangerPluginInfo(); + info.setGdsDownloadTime(5L); + info.setGdsDownloadedVersion(6L); + info.setGdsActivationTime(7L); + info.setGdsActiveVersion(8L); + + Assertions.assertEquals(5L, info.getGdsDownloadTime()); + Assertions.assertEquals(6L, info.getGdsDownloadedVersion()); + Assertions.assertEquals(7L, info.getGdsActivationTime()); + Assertions.assertEquals(8L, info.getGdsActiveVersion()); + + // capabilities store raw strings and return null on blank + info.setPluginCapabilities("cap1,cap2"); + info.setAdminCapabilities("capA"); + Assertions.assertEquals("cap1,cap2", info.getPluginCapabilities()); + Assertions.assertEquals("capA", info.getAdminCapabilities()); + + info.setInfo(new HashMap<>()); + Assertions.assertNull(info.getPluginCapabilities()); + Assertions.assertNull(info.getAdminCapabilities()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java index f35c5a9471..467fc0f34b 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java @@ -19,102 +19,267 @@ package org.apache.ranger.plugin.model; +import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; -import org.junit.Assert; -import org.junit.Test; +import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerPolicy { @Test - public void test_01_Policy_SetListMethods() { + public void test01_Policy_SetListMethods() { RangerPolicy policy = new RangerPolicy(); List policyItemList = getList(new RangerPolicyItem()); - Assert.assertEquals("RangerPolicy.getPolicyItems()", 0, policy.getPolicyItems().size()); + Assertions.assertEquals(0, policy.getPolicyItems().size(), "RangerPolicy.getPolicyItems()"); policy.addPolicyItem(new RangerPolicyItem()); - Assert.assertEquals("RangerPolicy.addPolicyItem()", 1, policy.getPolicyItems().size()); + Assertions.assertEquals(1, policy.getPolicyItems().size(), "RangerPolicy.addPolicyItem()"); policy.setPolicyItems(policyItemList); - Assert.assertEquals("RangerPolicy.setPolicyItems()", policyItemList.size(), policy.getPolicyItems().size()); + Assertions.assertEquals(policyItemList.size(), policy.getPolicyItems().size(), "RangerPolicy.setPolicyItems()"); - Assert.assertEquals("RangerPolicy.getDenyPolicyItems()", 0, policy.getDenyPolicyItems().size()); + Assertions.assertEquals(0, policy.getDenyPolicyItems().size(), "RangerPolicy.getDenyPolicyItems()"); policy.addDenyPolicyItem(new RangerPolicyItem()); - Assert.assertEquals("RangerPolicy.addDenyPolicyItem()", 1, policy.getDenyPolicyItems().size()); + Assertions.assertEquals(1, policy.getDenyPolicyItems().size(), "RangerPolicy.addDenyPolicyItem()"); policy.setDenyPolicyItems(policyItemList); - Assert.assertEquals("RangerPolicy.setDenyPolicyItems()", policyItemList.size(), policy.getDenyPolicyItems().size()); + Assertions.assertEquals(policyItemList.size(), policy.getDenyPolicyItems().size(), "RangerPolicy.setDenyPolicyItems()"); - Assert.assertEquals("RangerPolicy.getAllowExceptions()", 0, policy.getAllowExceptions().size()); + Assertions.assertEquals(0, policy.getAllowExceptions().size(), "RangerPolicy.getAllowExceptions()"); policy.addAllowException(new RangerPolicyItem()); - Assert.assertEquals("RangerPolicy.addAllowException()", 1, policy.getAllowExceptions().size()); + Assertions.assertEquals(1, policy.getAllowExceptions().size(), "RangerPolicy.addAllowException()"); policy.setAllowExceptions(policyItemList); - Assert.assertEquals("RangerPolicy.setAllowExceptions()", policyItemList.size(), policy.getAllowExceptions().size()); + Assertions.assertEquals(policyItemList.size(), policy.getAllowExceptions().size(), "RangerPolicy.setAllowExceptions()"); - Assert.assertEquals("RangerPolicy.getDenyExceptions()", 0, policy.getDenyExceptions().size()); + Assertions.assertEquals(0, policy.getDenyExceptions().size(), "RangerPolicy.getDenyExceptions()"); policy.addDenyException(new RangerPolicyItem()); - Assert.assertEquals("RangerPolicy.addDenyException()", 1, policy.getDenyExceptions().size()); + Assertions.assertEquals(1, policy.getDenyExceptions().size(), "RangerPolicy.addDenyException()"); policy.setDenyExceptions(policyItemList); - Assert.assertEquals("RangerPolicy.setDenyExceptions()", policyItemList.size(), policy.getDenyExceptions().size()); + Assertions.assertEquals(policyItemList.size(), policy.getDenyExceptions().size(), "RangerPolicy.setDenyExceptions()"); } @Test - public void test_02_PolicyItem_SetListMethods() { + public void test02_PolicyItem_SetListMethods() { RangerPolicyItem policyItem = new RangerPolicyItem(); List accesses = getList(new RangerPolicyItemAccess()); List users = getList("user"); List groups = getList("group"); List conditions = getList(new RangerPolicyItemCondition()); - Assert.assertEquals("RangerPolicyItem.getAccesses()", 0, policyItem.getAccesses().size()); + Assertions.assertEquals(0, policyItem.getAccesses().size(), "RangerPolicyItem.getAccesses()"); policyItem.addAccess(new RangerPolicyItemAccess()); - Assert.assertEquals("RangerPolicyItem.addAccess()", 1, policyItem.getAccesses().size()); + Assertions.assertEquals(1, policyItem.getAccesses().size(), "RangerPolicyItem.addAccess()"); policyItem.setAccesses(accesses); - Assert.assertEquals("RangerPolicyItem.setAccesses()", accesses.size(), policyItem.getAccesses().size()); + Assertions.assertEquals(accesses.size(), policyItem.getAccesses().size(), "RangerPolicyItem.setAccesses()"); - Assert.assertEquals("RangerPolicyItem.getUsers()", 0, policyItem.getUsers().size()); + Assertions.assertEquals(0, policyItem.getUsers().size(), "RangerPolicyItem.getUsers()"); policyItem.addUser(new String()); - Assert.assertEquals("RangerPolicyItem.addUser()", 1, policyItem.getUsers().size()); + Assertions.assertEquals(1, policyItem.getUsers().size(), "RangerPolicyItem.addUser()"); policyItem.setUsers(users); - Assert.assertEquals("RangerPolicyItem.setUsers()", users.size(), policyItem.getUsers().size()); + Assertions.assertEquals(users.size(), policyItem.getUsers().size(), "RangerPolicyItem.setUsers()"); - Assert.assertEquals("RangerPolicyItem.getGroups()", 0, policyItem.getGroups().size()); + Assertions.assertEquals(0, policyItem.getGroups().size(), "RangerPolicyItem.getGroups()"); policyItem.addGroup(new String()); - Assert.assertEquals("RangerPolicyItem.addGroup()", 1, policyItem.getGroups().size()); + Assertions.assertEquals(1, policyItem.getGroups().size(), "RangerPolicyItem.addGroup()"); policyItem.setGroups(groups); - Assert.assertEquals("RangerPolicyItem.setGroups()", groups.size(), policyItem.getGroups().size()); + Assertions.assertEquals(groups.size(), policyItem.getGroups().size(), "RangerPolicyItem.setGroups()"); - Assert.assertEquals("RangerPolicyItem.getConditions()", 0, policyItem.getConditions().size()); + Assertions.assertEquals(0, policyItem.getConditions().size(), "RangerPolicyItem.getConditions()"); policyItem.addCondition(new RangerPolicyItemCondition()); - Assert.assertEquals("RangerPolicyItem.addCondition()", 1, policyItem.getConditions().size()); + Assertions.assertEquals(1, policyItem.getConditions().size(), "RangerPolicyItem.addCondition()"); policyItem.setConditions(conditions); - Assert.assertEquals("RangerPolicyItem.setConditions()", conditions.size(), policyItem.getConditions().size()); + Assertions.assertEquals(conditions.size(), policyItem.getConditions().size(), "RangerPolicyItem.setConditions()"); } @Test - public void test_03_PolicyResource_SetListMethods() { + public void test03_PolicyResource_SetListMethods() { RangerPolicyResource policyResource = new RangerPolicyResource(); List values = getList("value"); - Assert.assertEquals("RangerPolicyResource.getValues()", 0, policyResource.getValues().size()); + Assertions.assertEquals(0, policyResource.getValues().size(), "RangerPolicyResource.getValues()"); policyResource.addValue(new String()); - Assert.assertEquals("RangerPolicyResource.addValue()", 1, policyResource.getValues().size()); + Assertions.assertEquals(1, policyResource.getValues().size(), "RangerPolicyResource.addValue()"); policyResource.setValues(values); - Assert.assertEquals("RangerPolicyResource.setValues()", values.size(), policyResource.getValues().size()); + Assertions.assertEquals(values.size(), policyResource.getValues().size(), "RangerPolicyResource.setValues()"); } @Test - public void test_04_PolicyItemCondition_SetListMethods() { + public void test04_PolicyItemCondition_SetListMethods() { RangerPolicyItemCondition policyItemCondition = new RangerPolicyItemCondition(); List values = getList("value"); - Assert.assertEquals("RangerPolicyItemCondition.getValues()", 0, policyItemCondition.getValues().size()); + Assertions.assertEquals(0, policyItemCondition.getValues().size(), "RangerPolicyItemCondition.getValues()"); policyItemCondition.addValue(new String()); - Assert.assertEquals("RangerPolicyItemCondition.addValue()", 1, policyItemCondition.getValues().size()); + Assertions.assertEquals(1, policyItemCondition.getValues().size(), "RangerPolicyItemCondition.addValue()"); policyItemCondition.setValues(values); - Assert.assertEquals("RangerPolicyItemCondition.setValues()", values.size(), policyItemCondition.getValues().size()); + Assertions.assertEquals(values.size(), policyItemCondition.getValues().size(), "RangerPolicyItemCondition.setValues()"); + } + + @Test + public void test05_DefaultsAndPriorityAuditFlags() { + RangerPolicy p = new RangerPolicy(); + Assertions.assertEquals(RangerPolicy.POLICY_PRIORITY_NORMAL, p.getPolicyPriority()); + Assertions.assertEquals(Boolean.TRUE, p.getIsAuditEnabled()); + + p.setPolicyPriority(null); + Assertions.assertEquals(RangerPolicy.POLICY_PRIORITY_NORMAL, p.getPolicyPriority()); + + p.setIsAuditEnabled(null); + Assertions.assertEquals(Boolean.TRUE, p.getIsAuditEnabled()); + + p.addPolicyLabel("L1"); + Assertions.assertTrue(p.getPolicyLabels().contains("L1")); + } + + @Test + public void test06_PolicyResourceEqualsHashCodeAndFlags() { + RangerPolicyResource r1 = new RangerPolicyResource("db1", null, null); + RangerPolicyResource r2 = new RangerPolicyResource("db1", null, null); + Assertions.assertEquals(r1, r2); + Assertions.assertEquals(r1.hashCode(), r2.hashCode()); + + r1.setIsExcludes(null); + r1.setIsRecursive(null); + Assertions.assertEquals(Boolean.FALSE, r1.getIsExcludes()); + Assertions.assertEquals(Boolean.FALSE, r1.getIsRecursive()); + + r1.setValues(Arrays.asList("a", "b")); + Assertions.assertEquals(Arrays.asList("a", "b"), r1.getValues()); + + r1.addValue("c"); + Assertions.assertTrue(r1.getValues().contains("c")); + r1.addValues(Arrays.asList("x", "y")); + r1.addValues(new String[] {"z"}); + Assertions.assertTrue(r1.getValues().containsAll(Arrays.asList("x", "y", "z"))); + } + + @Test + public void test07_PolicyItemAddRemoveApisAndEquals() { + RangerPolicyItem item = new RangerPolicyItem(); + RangerPolicyItemAccess a = new RangerPolicyItemAccess("read", null); + item.addAccess(a); + item.addUsers(Arrays.asList("u1", "u2")); + item.addGroups(Collections.singletonList("g1")); + item.addRoles(Collections.singletonList("r1")); + item.addConditions(Collections.singletonList(new RangerPolicyItemCondition("type", Arrays.asList("v")))); + item.setDelegateAdmin(null); + + Assertions.assertEquals(Boolean.FALSE, item.getDelegateAdmin()); + Assertions.assertTrue(item.getUsers().contains("u1")); + Assertions.assertTrue(item.getGroups().contains("g1")); + Assertions.assertTrue(item.getRoles().contains("r1")); + + Assertions.assertTrue(item.removeUser("u2")); + Assertions.assertTrue(item.removeGroup("g1")); + Assertions.assertTrue(item.removeRole("r1")); + + RangerPolicyItem copy = new RangerPolicyItem(item); + Assertions.assertEquals(item, copy); + Assertions.assertEquals(item.hashCode(), copy.hashCode()); + } + + @Test + public void test08_DataMaskAndRowFilterItems() { + RangerPolicyItemDataMaskInfo dm = new RangerPolicyItemDataMaskInfo("MASK", "col > 1", "val"); + RangerDataMaskPolicyItem dmItem = new RangerDataMaskPolicyItem(Collections.emptyList(), dm, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Boolean.TRUE); + Assertions.assertEquals(dm, dmItem.getDataMaskInfo()); + Assertions.assertTrue(dmItem.toString().contains("dataMaskInfo={")); + + RangerPolicyItemRowFilterInfo rf = new RangerPolicyItemRowFilterInfo("col=1"); + RangerRowFilterPolicyItem rfItem = new RangerRowFilterPolicyItem(rf, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Boolean.FALSE); + Assertions.assertEquals(rf, rfItem.getRowFilterInfo()); + Assertions.assertTrue(rfItem.toString().contains("rowFilterInfo={")); + } + + @Test + public void test09_PolicySettersAndNullSafeSupplierV2() { + RangerPolicy p = new RangerPolicy(); + p.setResources(new HashMap<>()); + p.addResource(new HashMap<>()); // should do nothing harmful + p.setOptions(new HashMap<>()); + p.setValiditySchedules(Collections.emptyList()); + p.setConditions(Collections.emptyList()); + p.setPolicyItems(Collections.emptyList()); + p.setDenyPolicyItems(Collections.emptyList()); + p.setAllowExceptions(Collections.emptyList()); + p.setDenyExceptions(Collections.emptyList()); + p.setDataMaskPolicyItems(Collections.emptyList()); + p.setRowFilterPolicyItems(Collections.emptyList()); + + Assertions.assertNotNull(p.getResources()); + Assertions.assertNotNull(p.getOptions()); + Assertions.assertNotNull(p.getValiditySchedules()); + + // switch supplier to V2 and verify empty collections are immutable empty + RangerBaseModelObject.setNullSafeSupplier(RangerBaseModelObject.NULL_SAFE_SUPPLIER_V2); + p.setPolicyItems(null); + Assertions.assertEquals(0, p.getPolicyItems().size()); + // revert to default + RangerBaseModelObject.setNullSafeSupplier((RangerBaseModelObject.NullSafeSupplier) null); + } + + @Test + public void test10_AdditionalResourcesAndToString() { + RangerPolicy p = new RangerPolicy(); + Map res = new LinkedHashMap<>(); + res.put("db", new RangerPolicyResource("db1")); + p.setResources(new HashMap<>()); + p.addResource(res); // with existing base resources -> should go to additionalResources + + String s = p.toString(); + Assertions.assertTrue(s.contains("additionalResources={")); + } + + @Test + public void test11_PolicyIdComparator() { + RangerPolicy p1 = new RangerPolicy(); + p1.setId(5L); + RangerPolicy p2 = new RangerPolicy(); + p2.setId(10L); + + Assertions.assertTrue(RangerPolicy.POLICY_ID_COMPARATOR.compare(p1, p2) < 0); + Assertions.assertTrue(RangerPolicy.POLICY_ID_COMPARATOR.compare(p2, p1) > 0); + Assertions.assertEquals(0, RangerPolicy.POLICY_ID_COMPARATOR.compare(p1, p1)); + } + + @Test + public void test12_NestedEqualsNullPaths() { + RangerPolicy.RangerPolicyItemAccess a1 = new RangerPolicy.RangerPolicyItemAccess(null, null); + RangerPolicy.RangerPolicyItemAccess a2 = new RangerPolicy.RangerPolicyItemAccess(null, null); + Assertions.assertEquals(a1, a2); + + RangerPolicy.RangerPolicyItemCondition c1 = new RangerPolicy.RangerPolicyItemCondition(null, null); + RangerPolicy.RangerPolicyItemCondition c2 = new RangerPolicy.RangerPolicyItemCondition(null, null); + Assertions.assertEquals(c1, c2); + + RangerPolicy.RangerPolicyItemDataMaskInfo dm1 = new RangerPolicy.RangerPolicyItemDataMaskInfo(); + RangerPolicy.RangerPolicyItemDataMaskInfo dm2 = new RangerPolicy.RangerPolicyItemDataMaskInfo(); + Assertions.assertEquals(dm1, dm2); + + RangerPolicy.RangerPolicyItemRowFilterInfo rf1 = new RangerPolicy.RangerPolicyItemRowFilterInfo(); + RangerPolicy.RangerPolicyItemRowFilterInfo rf2 = new RangerPolicy.RangerPolicyItemRowFilterInfo(); + Assertions.assertEquals(rf1, rf2); } private List getList(T value) { diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyDelta.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyDelta.java new file mode 100644 index 0000000000..bedf9c7ecf --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyDelta.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerPolicyDelta { + @Test + public void test01_defaultsAndNullPolicyBranch() { + RangerPolicyDelta delta = new RangerPolicyDelta(1L, RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE, 5L, null); + + Assertions.assertEquals(1L, delta.getId()); + Assertions.assertEquals(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE, delta.getChangeType()); + Assertions.assertNull(delta.getServiceType()); + Assertions.assertNull(delta.getPolicyType()); + Assertions.assertNull(delta.getPolicyId()); + Assertions.assertNull(delta.getZoneName()); + + // dedupStrings should be a no-op when policy is null + Map tbl = new HashMap<>(); + delta.dedupStrings(tbl); + + String s = delta.toString(); + Assertions.assertTrue(s.contains("id:1")); + Assertions.assertTrue(s.contains("POLICY_CREATE")); + } + + @Test + public void test02_nonNullPolicyBranchAndGetters() { + RangerPolicy policy = new RangerPolicy(); + policy.setId(99L); + policy.setServiceType("hive"); + policy.setPolicyType(7); + policy.setZoneName("zoneA"); + + RangerPolicyDelta delta = new RangerPolicyDelta(2L, RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE, 6L, policy); + + Assertions.assertEquals("hive", delta.getServiceType()); + Assertions.assertEquals(7, delta.getPolicyType()); + Assertions.assertEquals(99L, delta.getPolicyId()); + Assertions.assertEquals("zoneA", delta.getZoneName()); + + Map tbl = new HashMap<>(); + tbl.put("hive", "hive"); + delta.dedupStrings(tbl); + + String s = delta.toString(); + Assertions.assertTrue(s.contains("POLICY_UPDATE")); + Assertions.assertTrue(s.contains("policyId:[99]")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyHeader.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyHeader.java new file mode 100644 index 0000000000..84729269e7 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyHeader.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPolicyHeader { + @Test + public void test01_ConstructFromPolicyAndToString() { + RangerPolicy p = new RangerPolicy(); + p.setId(5L); + p.setGuid("G"); + p.setName("name"); + p.setIsEnabled(Boolean.TRUE); + p.setService("svc"); + p.setVersion(2L); + p.setPolicyType(1); + p.setZoneName("zone"); + Map res = new HashMap<>(); + res.put("db", new RangerPolicyResource("db1")); + p.setResources(res); + + RangerPolicyHeader hdr = new RangerPolicyHeader(p); + Assertions.assertEquals("svc", hdr.getService()); + Assertions.assertEquals("name", hdr.getName()); + Assertions.assertEquals(1, hdr.getPolicyType()); + Assertions.assertEquals("zone", hdr.getZoneName()); + Assertions.assertTrue(hdr.getResources().containsKey("db")); + + StringBuilder sb = new StringBuilder(); + hdr.toString(sb); + String s = sb.toString(); + Assertions.assertTrue(s.contains("id={5}")); + Assertions.assertTrue(s.contains("guid={G}")); + Assertions.assertTrue(s.contains("name={name}")); + Assertions.assertTrue(s.contains("service={svc}")); + Assertions.assertTrue(s.contains("policyType={1}")); + Assertions.assertTrue(s.contains("zoneName={zone}")); + } + + @Test + public void test02_SetResourcesDefensiveCopy() { + RangerPolicyHeader hdr = new RangerPolicyHeader(new RangerPolicy()); + Map res = new HashMap<>(); + res.put("a", new RangerPolicyResource("v")); + hdr.setResources(res); + Assertions.assertTrue(hdr.getResources().containsKey("a")); + res.clear(); + Assertions.assertTrue(hdr.getResources().containsKey("a")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java index 9949c81c96..b823f53a28 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java @@ -24,8 +24,12 @@ import org.apache.ranger.plugin.model.RangerPolicyResourceSignature.PolicySerializer; import org.apache.ranger.plugin.model.RangerPolicyResourceSignature.ResourceSerializer; import org.apache.ranger.plugin.model.validation.ValidationTestUtils; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.Arrays; import java.util.HashMap; @@ -34,6 +38,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerPolicyResourceSignature { /* * Format of data expected by the utility function which uses this is: @@ -72,76 +82,75 @@ public class TestRangerPolicyResourceSignature { private final ValidationTestUtils utils = new ValidationTestUtils(); @Test - public void test_RangerPolicyResourceView_toString() { + public void test01_RangerPolicyResourceView_toString() { // null resource RangerPolicyResource resource = null; ResourceSerializer serializer = new ResourceSerializer(resource); - Assert.assertEquals("{}", serializer.toString()); + Assertions.assertEquals("{}", serializer.toString()); // non-null policy resource with null values/recursive flag resource = createPolicyResource(null, null, null); serializer = new ResourceSerializer(resource); - Assert.assertEquals("{values=,excludes=false,recursive=false}", serializer.toString()); + Assertions.assertEquals("{values=,excludes=false,recursive=false}", serializer.toString()); // valid values in non-asending order resource = createPolicyResource(new String[] {"b", "a", "d", "c"}, true, false); serializer = new ResourceSerializer(resource); - Assert.assertEquals("{values=[a, b, c, d],excludes=false,recursive=true}", serializer.toString()); + Assertions.assertEquals("{values=[a, b, c, d],excludes=false,recursive=true}", serializer.toString()); // recursive flag is false and different variation of values to show lexicographic ordering resource = createPolicyResource(new String[] {"9", "A", "e", "_"}, false, true); serializer = new ResourceSerializer(resource); - Assert.assertEquals("{values=[9, A, _, e],excludes=true,recursive=false}", serializer.toString()); + Assertions.assertEquals("{values=[9, A, _, e],excludes=true,recursive=false}", serializer.toString()); } @Test - public void test_isPolicyValidForResourceSignatureComputation() { + public void test02_isPolicyValidForResourceSignatureComputation() { // null policy is invalid RangerPolicy rangerPolicy = null; PolicySerializer policySerializer = new PolicySerializer(rangerPolicy); - Assert.assertFalse("policy==null", policySerializer.isPolicyValidForResourceSignatureComputation()); + Assertions.assertFalse(policySerializer.isPolicyValidForResourceSignatureComputation(), "policy==null"); // null resource map is invalid rangerPolicy = mock(RangerPolicy.class); when(rangerPolicy.getResources()).thenReturn(null); policySerializer = new PolicySerializer(rangerPolicy); - Assert.assertFalse("policy.getResources()==null", policySerializer.isPolicyValidForResourceSignatureComputation()); + Assertions.assertFalse(policySerializer.isPolicyValidForResourceSignatureComputation(), "policy.getResources()==null"); // empty resources map is ok! Map policyResources = new HashMap<>(); when(rangerPolicy.getResources()).thenReturn(policyResources); when(rangerPolicy.getGuid()).thenReturn("TEST_GUID"); policySerializer = new PolicySerializer(rangerPolicy); - Assert.assertTrue("policy.getResources().isEmpty()", policySerializer.isPolicyValidForResourceSignatureComputation()); + Assertions.assertTrue(policySerializer.isPolicyValidForResourceSignatureComputation(), "policy.getResources().isEmpty()"); // but having a resource map with null key is not ok! RangerPolicyResource aPolicyResource = mock(RangerPolicyResource.class); policyResources.put(null, aPolicyResource); policySerializer = new PolicySerializer(rangerPolicy); - Assert.assertFalse("policy.getResources().contains(null)", policySerializer.isPolicyValidForResourceSignatureComputation()); + Assertions.assertFalse(policySerializer.isPolicyValidForResourceSignatureComputation(), "policy.getResources().contains(null)"); } @Test - public void test_RangerPolicyResourceSignature() { + public void test03_RangerPolicyResourceSignature() { // String rep of a null policy is an empty string! and its hash is sha of empty string! RangerPolicyResourceSignature signature = new RangerPolicyResourceSignature((String) null); - Assert.assertEquals("", signature.asString()); - Assert.assertEquals(DigestUtils.sha256Hex(""), signature.getSignature()); + Assertions.assertEquals("", signature.asString()); + Assertions.assertEquals(DigestUtils.sha256Hex(""), signature.getSignature()); } @Test - public void test_getResourceSignature_happyPath() { + public void test04_getResourceSignature_happyPath() { // null policy returns signature of empty resource RangerPolicy policy = null; PolicySerializer serializer = new PolicySerializer(policy); - Assert.assertSame("Null policy", "", serializer.toString()); + Assertions.assertEquals("", serializer.toString(), "Null policy"); policy = mock(RangerPolicy.class); when(policy.getPolicyType()).thenReturn(null); Map policyResources = utils.createPolicyResourceMap(first); when(policy.getResources()).thenReturn(policyResources); when(policy.getZoneName()).thenReturn(null); - when(policy.getGuid()).thenReturn("TEST_GUID"); when(policy.getIsEnabled()).thenReturn(true); serializer = new PolicySerializer(policy); String expectedVersion = "version=1"; @@ -153,87 +162,77 @@ public void test_getResourceSignature_happyPath() { "}"; String serializationFormat = "{%s,%s,resource=%s}"; String expectedFull = String.format(serializationFormat, expectedVersion, expectedType, expectedResource); - Assert.assertEquals(expectedFull, serializer.toString()); + Assertions.assertEquals(expectedFull, serializer.toString()); // order of values should not matter policyResources = utils.createPolicyResourceMap(dataSecond); when(policy.getResources()).thenReturn(policyResources); - Assert.assertEquals(expectedFull, serializer.toString()); + Assertions.assertEquals(expectedFull, serializer.toString()); // changing the policy type has expected changes when(policy.getPolicyType()).thenReturn(1); expectedType = "type=1"; expectedFull = String.format(serializationFormat, expectedVersion, expectedType, expectedResource); - Assert.assertEquals(expectedFull, serializer.toString()); + Assertions.assertEquals(expectedFull, serializer.toString()); } @Test - public void test_nullRecursiveFlagIsSameAsFlase() { + public void test05_nullRecursiveFlagIsSameAsFlase() { // create two policies with resources that differ only in the recursive flag such that flags are null in one and false in another RangerPolicy policy1 = createPolicy(first); RangerPolicy policy2 = createPolicy(firstRecursiveNullOrFalse); RangerPolicyResourceSignature signature1 = new RangerPolicyResourceSignature(policy1); RangerPolicyResourceSignature signature2 = new RangerPolicyResourceSignature(policy2); - when(policy1.getGuid()).thenReturn("TEST_GUID-1"); - when(policy2.getGuid()).thenReturn("TEST_GUID-2"); - Assert.assertEquals("Recursive flag: null is same as false", signature1.toString(), signature2.toString()); + Assertions.assertEquals(signature1.toString(), signature2.toString(), "Recursive flag: null is same as false"); } @Test - public void test_onlyDifferByRecursiveFlag() { + public void test06_onlyDifferByRecursiveFlag() { // create two policies with resources that differ only in the recursive flag, i.e. null/false in one and true in another RangerPolicy policy1 = createPolicy(first); RangerPolicy policy2 = createPolicy(firstRecursiveFlagDifferent); - when(policy1.getGuid()).thenReturn("TEST_GUID-1"); - when(policy2.getGuid()).thenReturn("TEST_GUID-2"); RangerPolicyResourceSignature signature1 = new RangerPolicyResourceSignature(policy1); RangerPolicyResourceSignature signature2 = new RangerPolicyResourceSignature(policy2); - Assert.assertNotEquals("Resources differ only by recursive flag true vs false/null", signature1.toString(), signature2.toString()); + Assertions.assertNotEquals(signature1.toString(), signature2.toString(), "Resources differ only by recursive flag true vs false/null"); } @Test - public void test_nullExcludesFlagIsSameAsFlase() { + public void test07_nullExcludesFlagIsSameAsFlase() { // create two policies with resources that differ only in the excludes flag such that flags are null in one and false in another RangerPolicy policy1 = createPolicy(first); RangerPolicy policy2 = createPolicy(firstExcludesNullOrFalse); - when(policy1.getGuid()).thenReturn("TEST_GUID-1"); - when(policy2.getGuid()).thenReturn("TEST_GUID-2"); RangerPolicyResourceSignature signature1 = new RangerPolicyResourceSignature(policy1); RangerPolicyResourceSignature signature2 = new RangerPolicyResourceSignature(policy2); - Assert.assertEquals("Excludes flag: null is same as false", signature1.toString(), signature2.toString()); + Assertions.assertEquals(signature1.toString(), signature2.toString(), "Excludes flag: null is same as false"); } @Test - public void test_onlyDifferByExcludesFlag() { + public void test08_onlyDifferByExcludesFlag() { // create two policies with resources that differ only in the excludes flag, i.e. null/false in one and true in another RangerPolicy policy1 = createPolicy(first); RangerPolicy policy2 = createPolicy(firstExcludesFlagDifferent); - when(policy1.getGuid()).thenReturn("TEST_GUID-1"); - when(policy2.getGuid()).thenReturn("TEST_GUID-2"); RangerPolicyResourceSignature signature1 = new RangerPolicyResourceSignature(policy1); RangerPolicyResourceSignature signature2 = new RangerPolicyResourceSignature(policy2); - Assert.assertNotEquals("Resources differ only by excludes flag true vs false/null", signature1.toString(), signature2.toString()); + Assertions.assertNotEquals(signature1.toString(), signature2.toString(), "Resources differ only by excludes flag true vs false/null"); } @Test - public void test_integration() { + public void test09_integration() { // setup two policies with resources that are structurally different but semantically the same. RangerPolicy aPolicy = mock(RangerPolicy.class); Map resources = utils.createPolicyResourceMap(first); when(aPolicy.getResources()).thenReturn(resources); when(aPolicy.getIsEnabled()).thenReturn(true); - when(aPolicy.getGuid()).thenReturn("TEST_GUID-1"); RangerPolicyResourceSignature signature = new RangerPolicyResourceSignature(aPolicy); RangerPolicy anotherPolicy = mock(RangerPolicy.class); resources = utils.createPolicyResourceMap(dataSecond); when(anotherPolicy.getResources()).thenReturn(resources); when(anotherPolicy.getIsEnabled()).thenReturn(true); - when(anotherPolicy.getGuid()).thenReturn("TEST_GUID-2"); RangerPolicyResourceSignature anotherSignature = new RangerPolicyResourceSignature(anotherPolicy); - Assert.assertEquals(signature, anotherSignature); - Assert.assertEquals(anotherSignature, signature); + Assertions.assertEquals(signature, anotherSignature); + Assertions.assertEquals(anotherSignature, signature); } RangerPolicyResource createPolicyResource(String[] values, Boolean recursive, Boolean excludes) { diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPrincipal.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPrincipal.java new file mode 100644 index 0000000000..7b48498503 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPrincipal.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerPrincipal.PrincipalType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPrincipal { + @Test + public void test01_SettersEqualsHashCodeToString() { + RangerPrincipal p1 = new RangerPrincipal(); + p1.setType(PrincipalType.USER); + p1.setName("alice"); + + RangerPrincipal p2 = new RangerPrincipal(PrincipalType.USER, "alice"); + + Assertions.assertEquals(p1, p2); + Assertions.assertEquals(p1.hashCode(), p2.hashCode()); + Assertions.assertTrue(p1.toString().contains("type=USER")); + Assertions.assertTrue(p1.toString().contains("name=alice")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerRole.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerRole.java new file mode 100644 index 0000000000..f0843f765a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerRole.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerRole { + @Test + public void test01_constructorAndToString() { + Map options = new HashMap<>(); + options.put("opt1", "val1"); + List users = new ArrayList<>(); + users.add(new RangerRole.RoleMember("alice", true)); + List groups = new ArrayList<>(); + groups.add(new RangerRole.RoleMember("dev", false)); + List roles = new ArrayList<>(); + roles.add(new RangerRole.RoleMember("data-steward", false)); + + RangerRole role = new RangerRole("r1", "desc", options, users, groups, roles); + role.setCreatedByUser("admin"); + + String s = role.toString(); + Assertions.assertTrue(s.contains("name=r1")); + Assertions.assertTrue(s.contains("options={opt1, [val1],}")); + Assertions.assertTrue(s.contains("users=[")); + Assertions.assertTrue(s.contains("groups=[")); + Assertions.assertTrue(s.contains("roles=[")); + } + + @Test + public void test02_gettersSettersAndCollectionsDefault() { + RangerRole role = new RangerRole(); + role.setName("n"); + role.setDescription("d"); + role.setOptions(null); + role.setUsers(null); + role.setGroups(null); + role.setRoles(null); + role.setCreatedByUser("c"); + + Assertions.assertEquals("n", role.getName()); + Assertions.assertEquals("d", role.getDescription()); + Assertions.assertNotNull(role.getOptions()); + Assertions.assertNotNull(role.getUsers()); + Assertions.assertNotNull(role.getGroups()); + Assertions.assertNotNull(role.getRoles()); + Assertions.assertEquals("c", role.getCreatedByUser()); + } + + @Test + public void test03_equalsAndHashCode() { + RangerRole r1 = new RangerRole(); + r1.setName("x"); + r1.setDescription("y"); + r1.setOptions(new HashMap<>()); + r1.setUsers(new ArrayList<>()); + r1.setGroups(new ArrayList<>()); + r1.setRoles(new ArrayList<>()); + + RangerRole r2 = new RangerRole(); + r2.setName("x"); + r2.setDescription("y"); + r2.setOptions(new HashMap<>()); + r2.setUsers(new ArrayList<>()); + r2.setGroups(new ArrayList<>()); + r2.setRoles(new ArrayList<>()); + + Assertions.assertEquals(r1, r2); + Assertions.assertEquals(r1.hashCode(), r2.hashCode()); + + r2.setDescription("z"); + Assertions.assertNotEquals(r1, r2); + } + + @Test + public void test04_roleMemberEqualsHashCodeToString() { + RangerRole.RoleMember m1 = new RangerRole.RoleMember("u1", true); + RangerRole.RoleMember m2 = new RangerRole.RoleMember("u1", true); + Assertions.assertEquals(m1, m2); + Assertions.assertEquals(m1.hashCode(), m2.hashCode()); + + m2.setIsAdmin(false); + Assertions.assertNotEquals(m1, m2); + + String s = m1.toString(); + Assertions.assertTrue(s.contains("u1")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZone.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZone.java new file mode 100644 index 0000000000..603faa7809 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZone.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerPrincipal.PrincipalType; +import org.apache.ranger.plugin.model.RangerSecurityZone.SecurityZoneSummary; +import org.apache.ranger.plugin.model.RangerSecurityZone.ZoneServiceSummary; +import org.apache.ranger.plugin.model.RangerSecurityZoneV2.RangerSecurityZoneResourceBase; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerSecurityZone { + @Test + public void test01_DefaultsAndSetters() { + RangerSecurityZone zone = new RangerSecurityZone(); + Assertions.assertNotNull(zone.getServices()); + Assertions.assertNotNull(zone.getAdminUsers()); + Assertions.assertNotNull(zone.getAdminUserGroups()); + Assertions.assertNotNull(zone.getAuditUsers()); + Assertions.assertNotNull(zone.getAuditUserGroups()); + Assertions.assertNotNull(zone.getTagServices()); + + zone.setName("zone1"); + zone.setDescription("desc"); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + zone.setTagServices(new ArrayList<>()); + + Assertions.assertEquals("zone1", zone.getName()); + Assertions.assertEquals("desc", zone.getDescription()); + + String s = zone.toString(); + Assertions.assertTrue(s.contains("name=zone1")); + } + + @Test + public void test02_ServiceNestedToString() { + RangerSecurityZone.RangerSecurityZoneService svc = new RangerSecurityZone.RangerSecurityZoneService(); + svc.setResources(new ArrayList<>()); + svc.setResourcesBaseInfo(new ArrayList()); + String s = svc.toString(); + Assertions.assertTrue(s.startsWith("{resources=[")); + } + + @Test + public void test03_SummaryNestedSetters() { + SecurityZoneSummary summary = new SecurityZoneSummary(); + summary.setName("zn"); + summary.setDescription("desc"); + summary.setTotalResourceCount(5L); + summary.setAdminCount(new HashMap()); + summary.setAuditorCount(new HashMap()); + summary.setTagServices(new ArrayList()); + summary.setServices(new ArrayList()); + + Assertions.assertEquals("zn", summary.getName()); + Assertions.assertEquals("desc", summary.getDescription()); + Assertions.assertEquals(5L, summary.getTotalResourceCount()); + + ZoneServiceSummary zss = new ZoneServiceSummary(); + zss.setId(1L); + zss.setName("svc"); + zss.setType("type"); + zss.setDisplayName("dn"); + zss.setResourceCount(7L); + Assertions.assertEquals(1L, zss.getId()); + Assertions.assertEquals("svc", zss.getName()); + Assertions.assertEquals("type", zss.getType()); + Assertions.assertEquals("dn", zss.getDisplayName()); + Assertions.assertEquals(7L, zss.getResourceCount()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZoneHeaderInfo.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZoneHeaderInfo.java new file mode 100644 index 0000000000..5814fa781c --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZoneHeaderInfo.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerSecurityZoneHeaderInfo { + @Test + public void test01_defaultConstructorAndToString() { + RangerSecurityZoneHeaderInfo info = new RangerSecurityZoneHeaderInfo(); + Assertions.assertEquals(-1L, info.getId()); + Assertions.assertEquals("", info.getName()); + String s = info.toString(new StringBuilder()).toString(); + Assertions.assertTrue(s.contains("id={-1}")); + Assertions.assertTrue(s.contains("isEnabled={true}")); + } + + @Test + public void test02_paramConstructorAndSetters() { + RangerSecurityZoneHeaderInfo info = new RangerSecurityZoneHeaderInfo(5L, "zone"); + Assertions.assertEquals(5L, info.getId()); + Assertions.assertEquals("zone", info.getName()); + + info.setName("z2"); + Assertions.assertEquals("z2", info.getName()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZoneV2.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZoneV2.java new file mode 100644 index 0000000000..a7ae1bf09d --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerSecurityZoneV2.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerSecurityZoneV2 { + @Test + public void test01_defaultsAndSetters() { + RangerSecurityZoneV2 v2 = new RangerSecurityZoneV2(); + Assertions.assertNotNull(v2.getServices()); + Assertions.assertNotNull(v2.getTagServices()); + Assertions.assertNotNull(v2.getAdmins()); + Assertions.assertNotNull(v2.getAuditors()); + + v2.setName("nz"); + v2.setDescription("desc"); + v2.setAdmins(new ArrayList<>()); + v2.setAuditors(new ArrayList<>()); + v2.setTagServices(new ArrayList<>()); + v2.setServices(null); + + Assertions.assertEquals("nz", v2.getName()); + Assertions.assertEquals("desc", v2.getDescription()); + Assertions.assertNotNull(v2.getServices()); + } + + @Test + public void test02_convertFromV1AndBack() { + RangerSecurityZone v1 = new RangerSecurityZone(); + v1.setId(10L); + v1.setGuid("g"); + v1.setIsEnabled(Boolean.TRUE); + v1.setCreatedBy("creator"); + v1.setUpdatedBy("upd"); + v1.setName("zone1"); + v1.setDescription("d"); + v1.setTagServices(new ArrayList<>()); + v1.getTagServices().add("tags1"); + v1.setAdminUsers(new ArrayList<>()); + v1.getAdminUsers().add("u1"); + v1.setAdminUserGroups(new ArrayList<>()); + v1.getAdminUserGroups().add("g1"); + v1.setAdminRoles(new ArrayList<>()); + v1.getAdminRoles().add("r1"); + v1.setAuditUsers(new ArrayList<>()); + v1.getAuditUsers().add("u2"); + v1.setAuditUserGroups(new ArrayList<>()); + v1.getAuditUserGroups().add("g2"); + v1.setAuditRoles(new ArrayList<>()); + v1.getAuditRoles().add("r2"); + + Map services = new HashMap<>(); + RangerSecurityZone.RangerSecurityZoneService v1svc = new RangerSecurityZone.RangerSecurityZoneService(); + v1svc.setResources(new ArrayList<>()); + HashMap> resMap = new HashMap<>(); + resMap.put("db", new ArrayList<>()); + resMap.get("db").add("sales"); + v1svc.getResources().add(resMap); + v1svc.setResourcesBaseInfo(new ArrayList<>()); + RangerSecurityZoneV2.RangerSecurityZoneResourceBase base = new RangerSecurityZoneV2.RangerSecurityZoneResourceBase(); + base.setId(1L); + v1svc.getResourcesBaseInfo().add(base); + services.put("hive", v1svc); + v1.setServices(services); + + RangerSecurityZoneV2 v2 = new RangerSecurityZoneV2(v1); + Assertions.assertEquals("zone1", v2.getName()); + Assertions.assertEquals(1, v2.getServices().get("hive").getResources().size()); + Assertions.assertEquals(3, v2.getAdmins().size()); + Assertions.assertEquals(3, v2.getAuditors().size()); + + RangerSecurityZone back = v2.toV1(); + Assertions.assertEquals(v1.getId(), back.getId()); + Assertions.assertEquals(v1.getGuid(), back.getGuid()); + Assertions.assertEquals(v1.getIsEnabled(), back.getIsEnabled()); + Assertions.assertEquals("zone1", back.getName()); + Assertions.assertEquals("d", back.getDescription()); + Assertions.assertEquals(v1.getTagServices(), back.getTagServices()); + Assertions.assertTrue(back.getAdminUsers().contains("u1")); + Assertions.assertTrue(back.getAdminUserGroups().contains("g1")); + Assertions.assertTrue(back.getAdminRoles().contains("r1")); + Assertions.assertTrue(back.getAuditUsers().contains("u2")); + Assertions.assertTrue(back.getAuditUserGroups().contains("g2")); + Assertions.assertTrue(back.getAuditRoles().contains("r2")); + Assertions.assertEquals(resMap, back.getServices().get("hive").getResources().get(0)); + Assertions.assertEquals(1, back.getServices().get("hive").getResourcesBaseInfo().size()); + } + + @Test + public void test03_nestedToStringCoverage() { + RangerSecurityZoneV2.RangerSecurityZoneServiceV2 svc = new RangerSecurityZoneV2.RangerSecurityZoneServiceV2(); + List resList = new ArrayList<>(); + Map> res = new HashMap<>(); + res.put("path", new ArrayList<>()); + res.get("path").add("/data"); + RangerSecurityZoneV2.RangerSecurityZoneResourceBase base = new RangerSecurityZoneV2.RangerSecurityZoneResourceBase(); + base.setId(11L); + RangerSecurityZoneV2.RangerSecurityZoneResource rs = new RangerSecurityZoneV2.RangerSecurityZoneResource(res, + base); + resList.add(rs); + svc.setResources(resList); + + String s1 = svc.toString(); + Assertions.assertTrue(s1.contains("resources=[")); + String s2 = rs.toString(); + Assertions.assertTrue(s2.contains("resource-def-name=path")); + String s3 = base.toString(); + Assertions.assertTrue(s3.contains("id=11")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerService.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerService.java index 7bc5835b96..baa3ebd157 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerService.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerService.java @@ -20,25 +20,35 @@ package org.apache.ranger.plugin.model; import org.apache.commons.lang3.StringUtils; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.HashMap; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerService { @Test - public void test_configToString() { + public void test01_configToString() { RangerService svc = new RangerService("hdfs", "dev_hdfs", "HDFS", "dev_tag", new HashMap<>()); String str = svc.toString(); - Assert.assertFalse(StringUtils.containsIgnoreCase(str, RangerService.CONFIG_PASSWORD)); + Assertions.assertFalse(StringUtils.containsIgnoreCase(str, RangerService.CONFIG_PASSWORD)); svc.getConfigs().put(RangerService.CONFIG_PASSWORD, "test1234"); str = svc.toString(); - Assert.assertTrue(StringUtils.containsIgnoreCase(str, RangerService.CONFIG_PASSWORD)); - Assert.assertFalse(StringUtils.containsIgnoreCase(str, "test1234")); - Assert.assertTrue(StringUtils.containsIgnoreCase(str, RangerService.MASKED_PASSWORD_VALUE)); + Assertions.assertTrue(StringUtils.containsIgnoreCase(str, RangerService.CONFIG_PASSWORD)); + Assertions.assertFalse(StringUtils.containsIgnoreCase(str, "test1234")); + Assertions.assertTrue(StringUtils.containsIgnoreCase(str, RangerService.MASKED_PASSWORD_VALUE)); } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java new file mode 100644 index 0000000000..408b18b019 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java @@ -0,0 +1,348 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumElementDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceDef { + @Test + public void test01_DefaultsAndSetters() { + RangerServiceDef def = new RangerServiceDef(); + def.setName("name"); + def.setDisplayName("dn"); + def.setImplClass("impl"); + def.setLabel("label"); + def.setDescription("desc"); + def.setRbKeyLabel("rbl"); + def.setRbKeyDescription("rbd"); + def.setOptions(new HashMap() { + { + put("k", "v"); + } + }); + def.setConfigs(new ArrayList()); + def.setResources(new ArrayList()); + def.setAccessTypes(new ArrayList()); + def.setPolicyConditions(new ArrayList()); + def.setContextEnrichers(new ArrayList()); + def.setEnums(new ArrayList()); + def.setMarkerAccessTypes(new ArrayList()); + + Assertions.assertEquals("name", def.getName()); + Assertions.assertEquals("dn", def.getDisplayName()); + Assertions.assertEquals("impl", def.getImplClass()); + Assertions.assertEquals("label", def.getLabel()); + Assertions.assertEquals("desc", def.getDescription()); + Assertions.assertTrue(def.getOptions().containsKey("k")); + + String s = def.toString(); + Assertions.assertTrue(s.contains("RangerServiceDef={")); + Assertions.assertTrue(s.contains("name={name}")); + Assertions.assertTrue(s.contains("displayName={dn}")); + } + + @Test + public void test02_RangerEnumDefDefaultIndex() { + List elements = new ArrayList<>(); + elements.add(new RangerEnumElementDef(1L, "e1", "l1", "rb1")); + elements.add(new RangerEnumElementDef(2L, "e2", "l2", "rb2")); + + RangerEnumDef enumDef = new RangerEnumDef(1L, "en", elements, null); + enumDef.setDefaultIndex(5); // out of bounds -> should clamp to 0 + Assertions.assertEquals(0, enumDef.getDefaultIndex()); + + enumDef.setDefaultIndex(1); + Assertions.assertEquals(1, enumDef.getDefaultIndex()); + } + + @Test + public void test03_ResourceDefDefaultsAndSetters() { + RangerResourceDef r = new RangerResourceDef(); + r.setLevel(null); + r.setMandatory(null); + r.setLookupSupported(null); + r.setRecursiveSupported(null); + r.setExcludesSupported(null); + r.setMatcherOptions(new HashMap() { + { + put("m", "o"); + } + }); + r.setAccessTypeRestrictions(new HashSet()); + + Assertions.assertEquals(Integer.valueOf(1), r.getLevel()); + Assertions.assertEquals(Boolean.FALSE, r.getMandatory()); + Assertions.assertEquals(Boolean.FALSE, r.getLookupSupported()); + Assertions.assertEquals(Boolean.FALSE, r.getRecursiveSupported()); + Assertions.assertEquals(Boolean.FALSE, r.getExcludesSupported()); + Assertions.assertTrue(r.getMatcherOptions().containsKey("m")); + } + + @Test + public void test04_setMarkerAccessTypesAndDefaultDefs() { + RangerServiceDef def = new RangerServiceDef(); + // verify defaulting of dataMaskDef/rowFilterDef when set to null + def.setDataMaskDef(null); + def.setRowFilterDef(null); + Assertions.assertNotNull(def.getDataMaskDef()); + Assertions.assertNotNull(def.getRowFilterDef()); + + // verify setMarkerAccessTypes clears and adds + List marker = new ArrayList<>(); + marker.add(new RangerAccessTypeDef(1L, "m1", "lbl", "rb", null)); + def.setMarkerAccessTypes(marker); + Assertions.assertEquals(1, def.getMarkerAccessTypes().size()); + def.setMarkerAccessTypes(new ArrayList()); + Assertions.assertTrue(def.getMarkerAccessTypes().isEmpty()); + } + + @Test + public void test05_ServiceDefSettersSameRefAndClear() { + RangerServiceDef def = new RangerServiceDef(); + + List cfg = new ArrayList<>(); + cfg.add(new RangerServiceDef.RangerServiceConfigDef()); + def.setConfigs(cfg); + Assertions.assertEquals(1, def.getConfigs().size()); + + List res = new ArrayList<>(); + res.add(new RangerResourceDef()); + def.setResources(res); + Assertions.assertEquals(1, def.getResources().size()); + + List at = new ArrayList<>(); + at.add(new RangerAccessTypeDef("read")); + def.setAccessTypes(at); + Assertions.assertEquals(1, def.getAccessTypes().size()); + + List pc = new ArrayList<>(); + pc.add(new RangerServiceDef.RangerPolicyConditionDef()); + def.setPolicyConditions(pc); + Assertions.assertEquals(1, def.getPolicyConditions().size()); + + List ce = new ArrayList<>(); + ce.add(new RangerServiceDef.RangerContextEnricherDef()); + def.setContextEnrichers(ce); + Assertions.assertEquals(1, def.getContextEnrichers().size()); + + List enums = new ArrayList<>(); + enums.add(new RangerEnumDef()); + def.setEnums(enums); + Assertions.assertEquals(1, def.getEnums().size()); + + // same-ref early-return: mutate the returned list and set the same reference + List sameResRef = def.getResources(); + sameResRef.add(new RangerResourceDef()); + def.setResources(sameResRef); + Assertions.assertEquals(2, def.getResources().size()); + + // now clear each by passing null + def.setConfigs(null); + def.setResources(null); + def.setAccessTypes(null); + def.setPolicyConditions(null); + def.setContextEnrichers(null); + def.setEnums(null); + Assertions.assertEquals(0, def.getConfigs().size()); + Assertions.assertEquals(0, def.getResources().size()); + Assertions.assertEquals(0, def.getAccessTypes().size()); + Assertions.assertEquals(0, def.getPolicyConditions().size()); + Assertions.assertEquals(0, def.getContextEnrichers().size()); + Assertions.assertEquals(0, def.getEnums().size()); + } + + @Test + public void test06_ServiceConfigDefDefaultsEqualsAndToString() { + RangerServiceDef.RangerServiceConfigDef c1 = new RangerServiceDef.RangerServiceConfigDef(); + c1.setMandatory(null); + Assertions.assertEquals(Boolean.FALSE, c1.getMandatory()); + String s = c1.toString(); + Assertions.assertTrue(s.contains("RangerServiceConfigDef={")); + + RangerServiceDef.RangerServiceConfigDef c2 = new RangerServiceDef.RangerServiceConfigDef(); + Assertions.assertEquals(c1, c2); + Assertions.assertEquals(c1.hashCode(), c2.hashCode()); + } + + @Test + public void test07_AccessTypeDefImpliedGrantsAndDedup() { + RangerAccessTypeDef at = new RangerAccessTypeDef(); + at.setImpliedGrants(null); + Assertions.assertTrue(at.getImpliedGrants().isEmpty()); + + List grants = new ArrayList<>(Arrays.asList(new String("read"), new String("write"))); + at.setImpliedGrants(grants); + Assertions.assertTrue(at.getImpliedGrants().contains("read")); + + Map tbl = new HashMap<>(); + at.dedupStrings(tbl); + + String str = at.toString(); + Assertions.assertTrue(str.contains("impliedGrants={")); + } + + @Test + public void test08_PolicyConditionDefDefaultsEquals() { + RangerServiceDef.RangerPolicyConditionDef pc = new RangerServiceDef.RangerPolicyConditionDef(); + pc.setEvaluatorOptions(null); + Assertions.assertNotNull(pc.getEvaluatorOptions()); + + RangerServiceDef.RangerPolicyConditionDef pc2 = new RangerServiceDef.RangerPolicyConditionDef(); + Assertions.assertEquals(pc, pc2); + Assertions.assertEquals(pc.hashCode(), pc2.hashCode()); + } + + @Test + public void test09_ContextEnricherDefDefaultsEquals() { + RangerServiceDef.RangerContextEnricherDef ce = new RangerServiceDef.RangerContextEnricherDef(); + ce.setEnricherOptions(null); + Assertions.assertNotNull(ce.getEnricherOptions()); + + RangerServiceDef.RangerContextEnricherDef ce2 = new RangerServiceDef.RangerContextEnricherDef(); + Assertions.assertEquals(ce, ce2); + Assertions.assertEquals(ce.hashCode(), ce2.hashCode()); + } + + @Test + public void test10_DataMaskTypeDefDefaultsEquals() { + RangerServiceDef.RangerDataMaskTypeDef mt1 = new RangerServiceDef.RangerDataMaskTypeDef(); + mt1.setDataMaskOptions(null); + Assertions.assertNotNull(mt1.getDataMaskOptions()); + + RangerServiceDef.RangerDataMaskTypeDef mt2 = new RangerServiceDef.RangerDataMaskTypeDef(); + Assertions.assertEquals(mt1, mt2); + Assertions.assertEquals(mt1.hashCode(), mt2.hashCode()); + } + + @Test + public void test11_DataMaskDefSettersSameRefNullAndToString() { + RangerServiceDef.RangerDataMaskDef dm = new RangerServiceDef.RangerDataMaskDef(); + Assertions.assertTrue(dm.getMaskTypes().isEmpty()); + Assertions.assertTrue(dm.getAccessTypes().isEmpty()); + Assertions.assertTrue(dm.getResources().isEmpty()); + + List mts = new ArrayList<>(); + mts.add(new RangerServiceDef.RangerDataMaskTypeDef()); + dm.setMaskTypes(mts); + List ats = new ArrayList<>(); + ats.add(new RangerAccessTypeDef("read")); + dm.setAccessTypes(ats); + List rs = new ArrayList<>(); + rs.add(new RangerResourceDef()); + dm.setResources(rs); + Assertions.assertEquals(1, dm.getMaskTypes().size()); + Assertions.assertEquals(1, dm.getAccessTypes().size()); + Assertions.assertEquals(1, dm.getResources().size()); + + // same-ref early return + List sameMt = dm.getMaskTypes(); + sameMt.add(new RangerServiceDef.RangerDataMaskTypeDef()); + dm.setMaskTypes(sameMt); + Assertions.assertEquals(2, dm.getMaskTypes().size()); + + // null to clear + dm.setMaskTypes(null); + dm.setAccessTypes(null); + dm.setResources(null); + Assertions.assertEquals(0, dm.getMaskTypes().size()); + Assertions.assertEquals(0, dm.getAccessTypes().size()); + Assertions.assertEquals(0, dm.getResources().size()); + + String s = dm.toString(); + Assertions.assertTrue(s.contains("RangerDataMaskDef={")); + } + + @Test + public void test12_RowFilterDefSettersSameRefNullAndToString() { + RangerServiceDef.RangerRowFilterDef rf = new RangerServiceDef.RangerRowFilterDef(); + Assertions.assertTrue(rf.getAccessTypes().isEmpty()); + Assertions.assertTrue(rf.getResources().isEmpty()); + + List ats = new ArrayList<>(); + ats.add(new RangerAccessTypeDef("read")); + rf.setAccessTypes(ats); + List rs = new ArrayList<>(); + rs.add(new RangerResourceDef()); + rf.setResources(rs); + Assertions.assertEquals(1, rf.getAccessTypes().size()); + Assertions.assertEquals(1, rf.getResources().size()); + + // same-ref early return + List sameAts = rf.getAccessTypes(); + sameAts.add(new RangerAccessTypeDef("write")); + rf.setAccessTypes(sameAts); + Assertions.assertEquals(2, rf.getAccessTypes().size()); + + // null to clear + rf.setAccessTypes(null); + rf.setResources(null); + Assertions.assertEquals(0, rf.getAccessTypes().size()); + Assertions.assertEquals(0, rf.getResources().size()); + + String s = rf.toString(); + Assertions.assertTrue(s.contains("RangerRowFilterDef={")); + } + + @Test + public void test13_EnumDefSetElementsSameRefAndDedup() { + RangerEnumElementDef e1 = new RangerEnumElementDef(1L, new String("e1"), new String("l1"), new String("rb1")); + List elements = new ArrayList<>(); + elements.add(e1); + + RangerEnumDef enumDef = new RangerEnumDef(1L, new String("en"), elements, 0); + enumDef.setDefaultIndex(10); // out of bounds -> set to 0 + Assertions.assertEquals(0, enumDef.getDefaultIndex()); + + // same-ref early return (size remains unchanged when setting same list) + List sameRef = enumDef.getElements(); + sameRef.add(new RangerEnumElementDef(2L, "e2", "l2", "rb2")); + enumDef.setElements(sameRef); + Assertions.assertEquals(2, enumDef.getElements().size()); + + Map tbl = new HashMap<>(); + enumDef.dedupStrings(tbl); + + String s = enumDef.toString(); + Assertions.assertTrue(s.contains("RangerEnumDef={")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceHeaderInfo.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceHeaderInfo.java new file mode 100644 index 0000000000..87f2c3caef --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceHeaderInfo.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceHeaderInfo { + @Test + public void test01_DefaultConstructor() { + RangerServiceHeaderInfo info = new RangerServiceHeaderInfo(); + Assertions.assertEquals(-1L, info.getId()); + Assertions.assertEquals("", info.getName()); + Assertions.assertEquals(Boolean.TRUE, info.getIsEnabled()); + } + + @Test + public void test02_IdNameAndTagConstructor() { + RangerServiceHeaderInfo info = new RangerServiceHeaderInfo(1L, "svc", true); + Assertions.assertEquals(1L, info.getId()); + Assertions.assertEquals("svc", info.getName()); + Assertions.assertEquals(Boolean.TRUE, info.getIsTagService()); + Assertions.assertEquals(Boolean.FALSE, info.getIsGdsService()); + } + + @Test + public void test03_WithTypeSetsTagFlag() { + RangerServiceHeaderInfo tagInfo = new RangerServiceHeaderInfo(2L, "tagSvc", "Tag Service", EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME); + Assertions.assertEquals(Boolean.TRUE, tagInfo.getIsTagService()); + + RangerServiceHeaderInfo other = new RangerServiceHeaderInfo(3L, "hdfsSvc", "HDFS", "hdfs"); + Assertions.assertEquals(Boolean.FALSE, other.getIsTagService()); + } + + @Test + public void test04_WithTypeAndEnabled() { + RangerServiceHeaderInfo info = new RangerServiceHeaderInfo(4L, "svc4", "dn4", "hive", Boolean.FALSE); + Assertions.assertEquals(4L, info.getId()); + Assertions.assertEquals("svc4", info.getName()); + Assertions.assertEquals("dn4", info.getDisplayName()); + Assertions.assertEquals("hive", info.getType()); + Assertions.assertEquals(Boolean.FALSE, info.getIsEnabled()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceResource.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceResource.java new file mode 100644 index 0000000000..eb79d57054 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceResource.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceResource { + @Test + public void test01_SettersAndToString() { + Map elements = new HashMap<>(); + elements.put("db", new RangerPolicyResource("db1")); + + Map addl = new HashMap<>(); + addl.put("k", "v"); + + RangerServiceResource rsr = new RangerServiceResource("guid-1", "svc", elements, "sig", "owner", addl); + + Assertions.assertEquals("svc", rsr.getServiceName()); + Assertions.assertEquals("sig", rsr.getResourceSignature()); + Assertions.assertEquals("owner", rsr.getOwnerUser()); + Assertions.assertEquals(elements, rsr.getResourceElements()); + Assertions.assertEquals(addl, rsr.getAdditionalInfo()); + + String s = rsr.toString(); + Assertions.assertTrue(s.contains("RangerServiceResource={")); + Assertions.assertTrue(s.contains("serviceName={svc}")); + Assertions.assertTrue(s.contains("resourceSignature={sig}")); + } + + @Test + public void test02_dedupStrings() { + RangerServiceResource rsr = new RangerServiceResource(); + rsr.setServiceName(new String("svc")); + rsr.setOwnerUser(new String("owner")); + Map elements = new HashMap<>(); + elements.put(new String("db"), new RangerPolicyResource("db1")); + rsr.setResourceElements(elements); + Map addl = new HashMap<>(); + addl.put(new String("k"), new String("v")); + rsr.setAdditionalInfo(addl); + + Map tbl = new HashMap<>(); + rsr.dedupStrings(tbl); + + // ensure dedup runs without altering semantics + Assertions.assertEquals("svc", rsr.getServiceName()); + Assertions.assertEquals("owner", rsr.getOwnerUser()); + Assertions.assertTrue(rsr.getResourceElements().containsKey("db")); + Assertions.assertEquals("v", rsr.getAdditionalInfo().get("k")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceResourceWithTags.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceResourceWithTags.java new file mode 100644 index 0000000000..f24a5b508b --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceResourceWithTags.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceResourceWithTags { + @Test + public void test01_AssociatedTagsToString() { + RangerServiceResourceWithTags r = new RangerServiceResourceWithTags(); + r.setServiceName("svc"); + r.setResourceElements(new HashMap() { + { + put("db", new RangerPolicyResource("db1")); + } + }); + + List tags = new ArrayList<>(); + tags.add(new RangerTag("t1", new HashMap())); + r.setAssociatedTags(tags); + + String s = r.toString(); + Assertions.assertTrue(s.contains("RangerServiceResourceWithTags={")); + Assertions.assertTrue(s.contains("associatedTags=[")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceTags.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceTags.java new file mode 100644 index 0000000000..ba8bb2f703 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceTags.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.apache.ranger.plugin.util.ServiceTags; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceTags { + @Test + public void test01_DefaultsAndSetters() { + RangerServiceTags rst = new RangerServiceTags(); + Assertions.assertEquals(RangerServiceTags.OP_SET, rst.getOp()); + Assertions.assertNotNull(rst.getTagDefinitions()); + Assertions.assertNotNull(rst.getTags()); + Assertions.assertNotNull(rst.getServiceResources()); + Assertions.assertNotNull(rst.getResourceToTagIds()); + + rst.setOp(RangerServiceTags.OP_REPLACE); + rst.setServiceName("svc"); + rst.setTagVersion(5L); + rst.setTagUpdateTime(new Date(0)); + + Assertions.assertEquals(RangerServiceTags.OP_REPLACE, rst.getOp()); + Assertions.assertEquals("svc", rst.getServiceName()); + Assertions.assertEquals(5L, rst.getTagVersion()); + Assertions.assertEquals(new Date(0), rst.getTagUpdateTime()); + + String s = rst.toString(); + Assertions.assertTrue(s.contains("RangerServiceTags={")); + } + + @Test + public void test02_ConvertToServiceTagsAndBack() { + RangerServiceTags rst = new RangerServiceTags(); + rst.setOp(RangerServiceTags.OP_SET); + rst.setServiceName("svc"); + rst.setTagVersion(10L); + rst.setTagUpdateTime(new Date(1000)); + + Map tagDefs = new HashMap<>(); + Map tags = new HashMap<>(); + List serviceResources = new ArrayList<>(); + Map> r2t = new HashMap<>(); + + rst.setTagDefinitions(tagDefs); + rst.setTags(tags); + rst.setServiceResources(serviceResources); + rst.setResourceToTagIds(r2t); + + ServiceTags st = RangerServiceTags.toServiceTags(rst); + Assertions.assertNotNull(st); + Assertions.assertEquals(ServiceTags.OP_ADD_OR_UPDATE, st.getOp()); + Assertions.assertEquals("svc", st.getServiceName()); + Assertions.assertEquals(10L, st.getTagVersion()); + Assertions.assertEquals(new Date(1000), st.getTagUpdateTime()); + Assertions.assertSame(tagDefs, st.getTagDefinitions()); + Assertions.assertSame(tags, st.getTags()); + Assertions.assertSame(serviceResources, st.getServiceResources()); + Assertions.assertSame(r2t, st.getResourceToTagIds()); + + RangerServiceTags rstBack = RangerServiceTags.toRangerServiceTags(st); + Assertions.assertNotNull(rstBack); + Assertions.assertEquals(RangerServiceTags.OP_SET, rstBack.getOp()); + Assertions.assertEquals("svc", rstBack.getServiceName()); + Assertions.assertEquals(10L, rstBack.getTagVersion()); + Assertions.assertEquals(new Date(1000), rstBack.getTagUpdateTime()); + } + + @Test + public void test03_NullConversionsAndToStringBuilder() { + Assertions.assertNull(RangerServiceTags.toServiceTags(null)); + Assertions.assertNull(RangerServiceTags.toRangerServiceTags((ServiceTags) null)); + + RangerServiceTags rst = new RangerServiceTags(); + StringBuilder sb = new StringBuilder(); + StringBuilder out = rst.toString(sb); + Assertions.assertSame(sb, out); + Assertions.assertTrue(out.toString().contains("RangerServiceTags={")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTag.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTag.java new file mode 100644 index 0000000000..5b7d45f346 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTag.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerTag { + @Test + public void test01_constructorsAndSetters() { + RangerTag tag = new RangerTag(); + tag.setGuid("g1"); + tag.setType("t1"); + tag.setOwner(RangerTag.OWNER_GLOBAL); + Map attrs = new HashMap<>(); + attrs.put("k", "v"); + tag.setAttributes(attrs); + Map opts = new HashMap<>(); + opts.put(RangerTag.OPTION_TAG_VALIDITY_PERIODS, "true"); + tag.setOptions(opts); + List vp = new ArrayList<>(); + vp.add(new RangerValiditySchedule()); + tag.setValidityPeriods(vp); + + Assertions.assertEquals("g1", tag.getGuid()); + Assertions.assertEquals("t1", tag.getType()); + Assertions.assertEquals(RangerTag.OWNER_GLOBAL, tag.getOwner()); + Assertions.assertEquals(attrs, tag.getAttributes()); + Assertions.assertEquals(opts, tag.getOptions()); + Assertions.assertEquals(vp, tag.getValidityPeriods()); + } + + @Test + public void test02_dedupStringsAndToString() { + Map attrs = new HashMap<>(); + attrs.put("a", "b"); + Map opts = new HashMap<>(); + opts.put("x", "y"); + RangerTag tag = new RangerTag("g", "type", attrs, RangerTag.OWNER_SERVICERESOURCE, opts, null); + + Map tbl = new HashMap<>(); + tbl.put("type", "type"); + int beforeSize = tbl.size(); + tag.dedupStrings(tbl); + Assertions.assertTrue(tbl.size() >= beforeSize); + + String s = tag.toString(); + Assertions.assertTrue(s.contains("RangerTag={")); + Assertions.assertTrue(s.contains("type={type}")); + } + + @Test + public void test03_equalsAndHashCode() { + RangerTag t1 = new RangerTag("g", "type", new HashMap<>(), RangerTag.OWNER_SERVICERESOURCE, new HashMap<>(), + new ArrayList<>()); + RangerTag t2 = new RangerTag("g", "type", new HashMap<>(), RangerTag.OWNER_SERVICERESOURCE, new HashMap<>(), + new ArrayList<>()); + Assertions.assertEquals(t1, t2); + Assertions.assertEquals(t1.hashCode(), t2.hashCode()); + + t2.setType("type2"); + Assertions.assertNotEquals(t1, t2); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTagDef.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTagDef.java new file mode 100644 index 0000000000..aebe453ddb --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTagDef.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerTagDef { + @Test + public void test01_defaultsAndSetters() { + RangerTagDef def = new RangerTagDef(); + Assertions.assertEquals("", def.getName()); + Assertions.assertEquals("Internal", def.getSource()); + + def.setName("PII"); + def.setSource("Atlas"); + Assertions.assertEquals("PII", def.getName()); + Assertions.assertEquals("Atlas", def.getSource()); + + List attrs = new ArrayList<>(); + attrs.add(new RangerTagDef.RangerTagAttributeDef("level", "string")); + def.setAttributeDefs(attrs); + Assertions.assertEquals(attrs, def.getAttributeDefs()); + } + + @Test + public void test02_dedupStringsAndEqualsHashCode() { + RangerTagDef.RangerTagAttributeDef ad1 = new RangerTagDef.RangerTagAttributeDef("n", "t"); + RangerTagDef.RangerTagAttributeDef ad2 = new RangerTagDef.RangerTagAttributeDef("n", "t"); + Assertions.assertEquals(ad1, ad2); + Assertions.assertEquals(ad1.hashCode(), ad2.hashCode()); + + RangerTagDef def1 = new RangerTagDef("PII", "Atlas"); + List list1 = new ArrayList<>(); + list1.add(ad1); + def1.setAttributeDefs(list1); + + RangerTagDef def2 = new RangerTagDef("PII", "Atlas"); + List list2 = new ArrayList<>(); + list2.add(new RangerTagDef.RangerTagAttributeDef("n", "t")); + def2.setAttributeDefs(list2); + + Assertions.assertEquals(def1, def2); + Assertions.assertEquals(def1.hashCode(), def2.hashCode()); + + Map tbl = new HashMap<>(); + def1.dedupStrings(tbl); + Assertions.assertTrue(tbl.isEmpty() || tbl.containsKey("PII") || tbl.containsKey("Atlas")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTagResourceMap.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTagResourceMap.java new file mode 100644 index 0000000000..90cddaa431 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerTagResourceMap.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** + * @generated by Cursor + * @description + */ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerTagResourceMap { + @Test + public void test01_gettersSettersAndToString() { + RangerTagResourceMap map = new RangerTagResourceMap(); + map.setResourceId(100L); + map.setTagId(200L); + + Assertions.assertEquals(100L, map.getResourceId()); + Assertions.assertEquals(200L, map.getTagId()); + + String s = map.toString(); + Assertions.assertTrue(s.contains("RangerTagResourceMap={")); + Assertions.assertTrue(s.contains("resourceId=100")); + Assertions.assertTrue(s.contains("tagId=200")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerValidityRecurrence.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerValidityRecurrence.java new file mode 100644 index 0000000000..bd56a1c23e --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerValidityRecurrence.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerValidityRecurrence { + @Test + public void test01_validityIntervalComputationAndToString() { + RangerValidityRecurrence.ValidityInterval vi = new RangerValidityRecurrence.ValidityInterval(1, 2, 30); + int minutes = RangerValidityRecurrence.ValidityInterval.getValidityIntervalInMinutes(vi); + Assertions.assertEquals((1 * 24 + 2) * 60 + 30, minutes); + + Assertions.assertEquals(0, RangerValidityRecurrence.ValidityInterval.getValidityIntervalInMinutes(null)); + + String s = vi.toString(); + Assertions.assertTrue(s.contains("days=1")); + Assertions.assertTrue(s.contains("hours=2")); + Assertions.assertTrue(s.contains("minutes=30")); + } + + @Test + public void test02_recurrenceScheduleSetAndGet() { + RangerValidityRecurrence.RecurrenceSchedule rs = new RangerValidityRecurrence.RecurrenceSchedule(); + rs.setFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.minute, "0,30"); + rs.setFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.hour, "1"); + rs.setFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfMonth, "*"); + rs.setFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfWeek, "1-5"); + rs.setFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.month, "0-11"); + rs.setFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.year, "2025"); + + Assertions.assertEquals("0,30", + rs.getFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.minute)); + Assertions.assertEquals("1", + rs.getFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.hour)); + Assertions.assertEquals("*", + rs.getFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfMonth)); + Assertions.assertEquals("1-5", + rs.getFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfWeek)); + Assertions.assertEquals("0-11", + rs.getFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.month)); + Assertions.assertEquals("2025", + rs.getFieldValue(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.year)); + + String s = rs.toString(); + Assertions.assertTrue(s.contains("minute=0,30")); + Assertions.assertTrue(s.contains("dayOfWeek=1-5")); + } + + @Test + public void test03_validityRecurrenceToStringAndAccessors() { + RangerValidityRecurrence.RecurrenceSchedule rs = new RangerValidityRecurrence.RecurrenceSchedule("0", "12", "*", + "1-5", "0-11", "2030"); + RangerValidityRecurrence.ValidityInterval vi = new RangerValidityRecurrence.ValidityInterval(0, 1, 0); + RangerValidityRecurrence rvr = new RangerValidityRecurrence(rs, vi); + + Assertions.assertEquals(rs, rvr.getSchedule()); + Assertions.assertEquals(vi, rvr.getInterval()); + + String s = rvr.toString(); + Assertions.assertTrue(s.contains("Schedule={")); + Assertions.assertTrue(s.contains("ValidityInterval")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerValiditySchedule.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerValiditySchedule.java new file mode 100644 index 0000000000..f2cf8bd294 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerValiditySchedule.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestRangerValiditySchedule { + @Test + public void test01_defaultsAndSetters() { + RangerValiditySchedule sched = new RangerValiditySchedule(); + Assertions.assertNotNull(sched.getRecurrences()); + Assertions.assertTrue(sched.getRecurrences().isEmpty()); + + sched.setTimeZone("UTC"); + sched.setStartTime("2025/09/22 00:00:00"); + sched.setEndTime("2025/09/23 00:00:00"); + sched.setRecurrences(null); + + Assertions.assertEquals("UTC", sched.getTimeZone()); + Assertions.assertEquals("2025/09/22 00:00:00", sched.getStartTime()); + Assertions.assertEquals("2025/09/23 00:00:00", sched.getEndTime()); + Assertions.assertNotNull(sched.getRecurrences()); + } + + @Test + public void test02_setRecurrencesCopiesAndString() { + List rec = new ArrayList<>(); + rec.add(new RangerValidityRecurrence(new RangerValidityRecurrence.RecurrenceSchedule(), + new RangerValidityRecurrence.ValidityInterval())); + + RangerValiditySchedule sched = new RangerValiditySchedule("s", "e", "Z", rec); + Assertions.assertEquals("Z", sched.getTimeZone()); + Assertions.assertEquals(rec, sched.getRecurrences()); + + String s = sched.toString(); + Assertions.assertTrue(s.contains("startTime=s")); + Assertions.assertTrue(s.contains("endTime=e")); + Assertions.assertTrue(s.contains("recurrences=")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestServiceDeleteResponse.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestServiceDeleteResponse.java new file mode 100644 index 0000000000..f78e34e9fa --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestServiceDeleteResponse.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** +* @generated by Cursor +* @description +*/ +@TestMethodOrder(MethodOrderer.MethodName.class) +@ExtendWith(MockitoExtension.class) +public class TestServiceDeleteResponse { + @Test + public void test01_gettersSetters() { + ServiceDeleteResponse resp = new ServiceDeleteResponse(7L); + Assertions.assertEquals(7L, resp.getServiceId()); + + resp.setServiceName("svc"); + resp.setIsDeleted(Boolean.TRUE); + resp.setErrorMsg("none"); + resp.setServiceId(8L); + + Assertions.assertEquals("svc", resp.getServiceName()); + Assertions.assertEquals(Boolean.TRUE, resp.getIsDeleted()); + Assertions.assertEquals("none", resp.getErrorMsg()); + Assertions.assertEquals(8L, resp.getServiceId()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestUserInfo.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestUserInfo.java new file mode 100644 index 0000000000..1de8de7295 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestUserInfo.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestUserInfo { + @Test + public void test01_ConstructorsAndSetters() { + UserInfo u1 = new UserInfo(); + Assertions.assertNotNull(u1.getOtherAttributes()); + + UserInfo u2 = new UserInfo("alice", "desc", new HashMap() { + { + put("k", "v"); + } + }); + u2.setGroups(new HashSet() { + { + add("g1"); + } + }); + + Assertions.assertEquals("alice", u2.getName()); + Assertions.assertEquals("desc", u2.getDescription()); + Assertions.assertEquals("v", u2.getOtherAttributes().get("k")); + Assertions.assertTrue(u2.getGroups().contains("g1")); + + String s = u2.toString(); + Assertions.assertTrue(s.contains("name=alice")); + Assertions.assertTrue(s.contains("otherAttributes={k, [v],}")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java index e7f04a85e0..4dc1c43ce9 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java @@ -35,14 +35,14 @@ import org.apache.ranger.plugin.store.SecurityZoneStore; import org.apache.ranger.plugin.store.ServiceStore; import org.apache.ranger.plugin.util.SearchFilter; -import org.junit.Assert; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.Collections; @@ -53,8 +53,12 @@ import static org.mockito.Mockito.mock; -@RunWith(MockitoJUnitRunner.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class RangerSecurityZoneValidatorTest { ServiceStore store = mock(ServiceStore.class); SecurityZoneStore securityZoneStore = mock(SecurityZoneStore.class); @@ -116,7 +120,7 @@ public void testValidateSecurityZoneForDeleteThrowsError() throws Exception { try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.DELETE); } catch (IllegalArgumentException ex) { - Assert.assertEquals(ex.getMessage(), "isValid(RangerSecurityZone, ...) is only supported for create/update"); + Assertions.assertEquals(ex.getMessage(), "isValid(RangerSecurityZone, ...) is only supported for create/update"); } } @@ -127,7 +131,7 @@ public void testValidateSecurityZoneWithoutNameForCreate() { try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3035], reason[Internal error: missing field[name]], field[name], subfield[null], type[missing] "); + Assertions.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3035], reason[Internal error: missing field[name]], field[name], subfield[null], type[missing] "); } } @@ -140,7 +144,7 @@ public void testValidateSecurityZoneForCreateWithExistingNameThrowsError() throw try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3036], reason[Another security zone already exists for this name: zone-id=[1]]], field[name], subfield[null], type[] "); + Assertions.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3036], reason[Another security zone already exists for this name: zone-id=[1]]], field[name], subfield[null], type[] "); } } @@ -151,7 +155,7 @@ public void testValidateSecurityZoneNotExistForUpdateThrowsError() throws Except try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.UPDATE); } catch (Exception ex) { - Assert.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3037], reason[No security zone found for [1]], field[id], subfield[null], type[] "); + Assertions.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3037], reason[No security zone found for [1]], field[id], subfield[null], type[] "); } } @@ -172,7 +176,7 @@ public void testValidateSecurityZoneWitoutServicesAdminUserAdminUserGroupAuditUs ValidationErrorCode expectedError = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS_AND_ROLES; boolean hasExpectedError = StringUtils.contains(failureMessage, expectedError.getErrorCode() + ""); - Assert.assertTrue("validation failure message didn't include expected error code " + expectedError.getErrorCode() + ". Failure message: " + failureMessage, hasExpectedError); + Assertions.assertTrue(hasExpectedError, "validation failure message didn't include expected error code " + expectedError.getErrorCode() + ". Failure message: " + failureMessage); } } @@ -194,7 +198,7 @@ public void testValidateSecurityZoneWitoutResourcesForCreateThrowsError() throws try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals( + Assertions.assertEquals( ex.getMessage(), "(0) Validation failure: error code[3039], reason[No resources specified for service [hdfsSvc]], field[security zone resources], subfield[null], type[missing] "); } @@ -210,7 +214,7 @@ public void testValidateSecurityZoneWitoutRangerServiceForCreateThrowsError() th try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals( + Assertions.assertEquals( ex.getMessage(), "(0) Validation failure: error code[3040], reason[Invalid service [hdfsSvc]], field[security zone resource service-name], subfield[null], type[] "); } @@ -228,7 +232,7 @@ public void testValidateSecurityZoneWitoutRangerServiceDefForCreateThrowsError() try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals(ex.getMessage(), + Assertions.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3041], reason[Invalid service-type [1]], field[security zone resource service-type], subfield[null], type[] "); } } @@ -247,7 +251,7 @@ public void testValidateSecurityZoneWitoutRangerServiceDefResourceForCreateThrow try { rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals(ex.getMessage(), + Assertions.assertEquals(ex.getMessage(), "(0) Validation failure: error code[3042], reason[Invalid resource hierarchy specified for service:[hdfsSvc], resource-hierarchy:[[hdfs]]], field[security zone resource hierarchy], subfield[null], type[] "); } } @@ -268,7 +272,7 @@ public void testValidateWhileFetchingSecurityZoneForCreateThrowsError() throws E rangerSecurityZoneValidator.validate(suppliedSecurityZone, RangerValidator.Action.CREATE); } catch (Exception ex) { - Assert.assertEquals( + Assertions.assertEquals( ex.getMessage(), "(0) Validation failure: error code[3045], reason[Internal Error:[null]], field[null], subfield[null], type[] "); } @@ -281,7 +285,7 @@ public void testIsValidSecurityZoneForDeleteWithWrongActionTypeReturnFalse() { boolean isValid = rangerSecurityZoneValidator.isValid(suppliedSecurityZone.getName(), RangerValidator.Action.UPDATE, failures); - Assert.assertFalse(isValid); + Assertions.assertFalse(isValid); } @Test @@ -292,7 +296,7 @@ public void testIsValidSecurityZoneForDeleteWithoutNameReturnFalse() { boolean isValid = rangerSecurityZoneValidator.isValid(suppliedSecurityZone.getName(), RangerValidator.Action.DELETE, failures); - Assert.assertFalse(isValid); + Assertions.assertFalse(isValid); } @Test @@ -302,7 +306,7 @@ public void testIsValidSecurityZoneForDeleteWithWrongNameReturnFalse() throws Ex List failures = new ArrayList<>(); boolean isValid = rangerSecurityZoneValidator.isValid(suppliedSecurityZone.getName(), RangerValidator.Action.DELETE, failures); - Assert.assertFalse(isValid); + Assertions.assertFalse(isValid); } @Test @@ -311,7 +315,7 @@ public void testIsValidSecurityZoneIdForDeleteWithWrongActionTypeReturnFalse() { List failures = new ArrayList<>(); boolean isValid = rangerSecurityZoneValidator.isValid(suppliedSecurityZone.getId(), RangerValidator.Action.UPDATE, failures); - Assert.assertFalse(isValid); + Assertions.assertFalse(isValid); } @Test @@ -322,7 +326,7 @@ public void testIsValidSecurityZoneForDeleteWithWrongIdReturnFalse() throws Exce boolean isValid = rangerSecurityZoneValidator.isValid(suppliedSecurityZone.getId(), RangerValidator.Action.DELETE, failures); - Assert.assertFalse(isValid); + Assertions.assertFalse(isValid); } @Test @@ -354,13 +358,13 @@ public void testValidatePathResourceInMultipleSecurityZones() throws Exception { try { rangerSecurityZoneValidator.validate(zone2, RangerValidator.Action.UPDATE); - Assert.fail("security-zone update should have failed in validation"); + Assertions.fail("security-zone update should have failed in validation"); } catch (Exception excp) { String failureMessage = excp.getMessage(); ValidationErrorCode expectedError = ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT; boolean hasExpectedError = StringUtils.contains(failureMessage, expectedError.getErrorCode() + ""); - Assert.assertTrue("validation failure message didn't include expected error code " + expectedError.getErrorCode() + ". Failure message: " + failureMessage, hasExpectedError); + Assertions.assertTrue(hasExpectedError, "validation failure message didn't include expected error code " + expectedError.getErrorCode() + ". Failure message: " + failureMessage); } } @@ -393,12 +397,12 @@ public void testValidateHiveResourceInMultipleSecurityZones() throws Exception { try { rangerSecurityZoneValidator.validate(zone2, RangerValidator.Action.UPDATE); - Assert.fail("security-zone update should have failed in validation"); + Assertions.fail("security-zone update should have failed in validation"); } catch (Exception excp) { String failureMessage = excp.getMessage(); boolean hasResourceConflictError = StringUtils.contains(failureMessage, ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ""); - Assert.assertTrue("validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ". Failure message: " + excp.getMessage(), hasResourceConflictError); + Assertions.assertTrue(hasResourceConflictError, "validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ". Failure message: " + excp.getMessage()); } } @@ -431,12 +435,12 @@ public void test2ValidateHiveResourceInMultipleSecurityZones() throws Exception try { rangerSecurityZoneValidator.validate(zone2, RangerValidator.Action.UPDATE); - Assert.fail("security-zone update should have failed in validation"); + Assertions.fail("security-zone update should have failed in validation"); } catch (Exception excp) { String failureMessage = excp.getMessage(); boolean hasResourceConflictError = StringUtils.contains(failureMessage, ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ""); - Assert.assertTrue("validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ". Failure message: " + excp.getMessage(), hasResourceConflictError); + Assertions.assertTrue(hasResourceConflictError, "validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ". Failure message: " + excp.getMessage()); } } @@ -461,12 +465,12 @@ public void testValidateDuplicateResourceEntries() throws Exception { try { rangerSecurityZoneValidator.validate(zone1, RangerValidator.Action.UPDATE); - Assert.fail("security-zone update should have failed in validation"); + Assertions.fail("security-zone update should have failed in validation"); } catch (Exception excp) { String failureMessage = excp.getMessage(); boolean hasResourceConflictError = StringUtils.contains(failureMessage, ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_DUPLICATE_RESOURCE_ENTRY.getErrorCode() + ""); - Assert.assertTrue("validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_DUPLICATE_RESOURCE_ENTRY.getErrorCode() + ". Failure message: " + excp.getMessage(), hasResourceConflictError); + Assertions.assertTrue(hasResourceConflictError, "validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_DUPLICATE_RESOURCE_ENTRY.getErrorCode() + ". Failure message: " + excp.getMessage()); } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestDirectedGraph.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestDirectedGraph.java index 0f18ff4888..0ff7857992 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestDirectedGraph.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestDirectedGraph.java @@ -22,12 +22,22 @@ import org.apache.hadoop.thirdparty.com.google.common.collect.Lists; import org.apache.hadoop.thirdparty.com.google.common.collect.Sets; import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper.DirectedGraph; -import org.junit.Test; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.HashSet; import static org.junit.Assert.assertEquals; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestDirectedGraph { @Test public void test() { diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java index 5328695de4..07d1f1947b 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java @@ -33,9 +33,11 @@ import org.apache.ranger.plugin.model.validation.RangerValidator.Action; import org.apache.ranger.plugin.store.ServiceStore; import org.apache.ranger.plugin.util.RangerObjectFactory; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.Arrays; @@ -45,10 +47,20 @@ import java.util.Map; import java.util.Set; -import static org.mockito.Matchers.argThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerPolicyValidator { final Action[] cu = new Action[] {Action.CREATE, Action.UPDATE}; final Object[] policyItemsData = new Object[] { @@ -143,48 +155,46 @@ public class TestRangerPolicyValidator { private RangerObjectFactory factory; private final Long zoneId = RangerSecurityZone.RANGER_UNZONED_SECURITY_ZONE_ID; - @Before - public void setUp() throws Exception { + private void initialize() throws Exception { store = mock(ServiceStore.class); policy = mock(RangerPolicy.class); validator = new RangerPolicyValidatorWrapper(store); serviceDef = mock(RangerServiceDef.class); - factory = mock(RangerObjectFactory.class); + factory = mock(RangerObjectFactory.class); validator.factory = factory; + failures.clear(); } @Test public final void testIsValid_long() throws Exception { + initialize(); // this validation should be removed if we start supporting other than delete action - Assert.assertFalse(validator.isValid(3L, Action.CREATE, failures)); + assertFalse(validator.isValid(3L, Action.CREATE, failures)); utils.checkFailureForInternalError(failures); // should fail with appropriate error message if id is null failures.clear(); failures.clear(); - Assert.assertFalse(validator.isValid((Long) null, Action.DELETE, failures)); + assertFalse(validator.isValid((Long) null, Action.DELETE, failures)); utils.checkFailureForMissingValue(failures, "id"); // should not fail if policy can't be found for the specified id - when(store.getPolicy(1L)).thenReturn(null); - when(store.getPolicy(2L)).thenThrow(new Exception()); - RangerPolicy existingPolicy = mock(RangerPolicy.class); - when(store.getPolicy(3L)).thenReturn(existingPolicy); failures.clear(); - Assert.assertTrue(validator.isValid(1L, Action.DELETE, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(1L, Action.DELETE, failures)); + assertTrue(failures.isEmpty()); failures.clear(); - Assert.assertTrue(validator.isValid(2L, Action.DELETE, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(2L, Action.DELETE, failures)); + assertTrue(failures.isEmpty()); // if policy exists then delete validation should pass, too! failures.clear(); - Assert.assertTrue(validator.isValid(3L, Action.DELETE, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(3L, Action.DELETE, failures)); + assertTrue(failures.isEmpty()); } @Test public final void testIsValid_errorPaths() throws Exception { + initialize(); boolean isAdmin = true; // 1. create policy in a non-existing service @@ -192,7 +202,7 @@ public final void testIsValid_errorPaths() throws Exception { when(policy.getService()).thenReturn("non-existing-service-name"); when(store.getServiceByName("non-existing-service-name")).thenReturn(null); - Assert.assertFalse(action.toString(), validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures), action.toString()); // 2. update a policy to change the service-name RangerPolicy existingPolicy = mock(RangerPolicy.class); @@ -219,7 +229,7 @@ public final void testIsValid_errorPaths() throws Exception { when(store.getServiceByName("service-name2")).thenReturn(service2); action = Action.UPDATE; - Assert.assertFalse(action.toString(), validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures), action.toString()); // 3. update a policy to change the policy-type when(existingPolicy.getId()).thenReturn(8L); @@ -230,11 +240,12 @@ public final void testIsValid_errorPaths() throws Exception { when(policy.getService()).thenReturn("service-name"); when(policy.getPolicyType()).thenReturn(1); - Assert.assertFalse(action.toString(), validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures), action.toString()); } @Test public final void testIsValid_happyPath() throws Exception { + initialize(); // valid policy has valid non-empty name and service name when(policy.getService()).thenReturn("service-name"); // service name exists @@ -244,14 +255,10 @@ public final void testIsValid_happyPath() throws Exception { when(store.getServiceByName("service-name")).thenReturn(service); // service points to a valid service-def serviceDef = utils.createServiceDefWithAccessTypes(accessTypes); - when(serviceDef.getName()).thenReturn("service-type"); when(store.getServiceDefByName("service-type")).thenReturn(serviceDef); // a matching policy should exist for create when checked by id and not exist when checked by name. - when(store.getPolicy(7L)).thenReturn(null); RangerPolicy existingPolicy = mock(RangerPolicy.class); - when(existingPolicy.getId()).thenReturn(8L); when(existingPolicy.getService()).thenReturn("service-name"); - when(store.getPolicy(8L)).thenReturn(existingPolicy); // a matching policy should not exist for update. // valid policy can have empty set of policy items if audit is turned on // null value for audit is treated as audit on. @@ -265,19 +272,21 @@ public final void testIsValid_happyPath() throws Exception { when(policy.getId()).thenReturn(7L); when(policy.getName()).thenReturn("policy-name-1"); when(store.getPolicyId(service.getId(), policy.getName(), zoneId)).thenReturn(null); - Assert.assertTrue(action + ", " + auditEnabled, validator.isValid(policy, action, isAdmin, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(policy, action, isAdmin, failures), action + ", " + auditEnabled); + assertTrue(failures.isEmpty()); } else { // update should work both when by-name is found or not, since nothing found by-name means name is being updated. when(policy.getId()).thenReturn(8L); when(policy.getName()).thenReturn("policy-name-1"); - Assert.assertTrue(action + ", " + auditEnabled, validator.isValid(policy, action, isAdmin, failures)); - Assert.assertTrue(failures.isEmpty()); + when(store.getPolicy(8L)).thenReturn(existingPolicy); + assertTrue(validator.isValid(policy, action, isAdmin, failures), action + ", " + auditEnabled); + assertTrue(failures.isEmpty()); when(policy.getName()).thenReturn("policy-name-2"); when(store.getPolicyId(service.getId(), policy.getName(), zoneId)).thenReturn(null); - Assert.assertTrue(action + ", " + auditEnabled, validator.isValid(policy, action, isAdmin, failures)); - Assert.assertTrue(failures.isEmpty()); + when(store.getPolicy(8L)).thenReturn(existingPolicy); + assertTrue(validator.isValid(policy, action, isAdmin, failures), action + ", " + auditEnabled); + assertTrue(failures.isEmpty()); } } } @@ -295,8 +304,8 @@ public final void testIsValid_happyPath() throws Exception { when(policy.getId()).thenReturn(8L); when(policy.getName()).thenReturn("policy-name-2"); } - Assert.assertTrue("" + action, validator.isValid(policy, action, isAdmin, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(policy, action, isAdmin, failures), "" + action); + assertTrue(failures.isEmpty()); } } @@ -312,7 +321,9 @@ public final void testIsValid_happyPath() throws Exception { when(factory.createPolicyResourceSignature(policy)).thenReturn(policySignature); // setup the store to indicate that no other policy exists with matching signature when(policySignature.getSignature()).thenReturn("hash-1"); - when(store.getPoliciesByResourceSignature("service-name", "hash-1", true)).thenReturn(null); + // Ensure helper works with non-null service-def name/time + when(serviceDef.getName()).thenReturn("service-type"); + when(serviceDef.getUpdateTime()).thenReturn(new Date()); // we are reusing the same policies collection here -- which is fine for (Action action : cu) { if (action == Action.CREATE) { @@ -322,13 +333,14 @@ public final void testIsValid_happyPath() throws Exception { when(policy.getId()).thenReturn(8L); when(policy.getName()).thenReturn("policy-name-2"); } - Assert.assertTrue("" + action, validator.isValid(policy, action, true, failures)); // since policy resource has excludes admin privilages would be required - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(policy, action, true, failures), "" + action); // since policy resource has excludes admin privilages would be required + assertTrue(failures.isEmpty()); } } @Test public final void testIsValid_failures() throws Exception { + initialize(); for (Action action : cu) { // passing in a null policy should fail with appropriate failure reason policy = null; @@ -338,7 +350,6 @@ public final void testIsValid_failures() throws Exception { policy = mock(RangerPolicy.class); for (String name : new String[] {null, " "}) { when(policy.getName()).thenReturn(name); - when(policy.getResources()).thenReturn(null); checkFailure_isValid(action, "missing", "name"); } @@ -354,30 +365,23 @@ public final void testIsValid_failures() throws Exception { */ when(policy.getName()).thenReturn("policy-name"); when(policy.getService()).thenReturn("service-name"); + when(policy.getResources()).thenReturn(null); when(store.getServiceByName("service-name")).thenReturn(service); when(service.getId()).thenReturn(2L); RangerPolicy existingPolicy = mock(RangerPolicy.class); - when(existingPolicy.getId()).thenReturn(7L); - when(existingPolicy.getService()).thenReturn("service-name"); - List existingPolicies = new ArrayList<>(); when(store.getPolicyId(service.getId(), "policy-name", zoneId)).thenReturn(7L); checkFailure_isValid(Action.CREATE, "semantic", "policy name"); // update : does not exist for id when(policy.getId()).thenReturn(7L); - when(store.getPolicy(7L)).thenReturn(null); + when(policy.getResources()).thenReturn(null); checkFailure_isValid(Action.UPDATE, "semantic", "id"); // Update: name should not point to an existing different policy, i.e. with a different id when(store.getPolicy(7L)).thenReturn(existingPolicy); - RangerPolicy anotherExistingPolicy = mock(RangerPolicy.class); - when(anotherExistingPolicy.getId()).thenReturn(8L); - when(anotherExistingPolicy.getService()).thenReturn("service-name"); - - existingPolicies.add(anotherExistingPolicy); when(store.getPolicyId(service.getId(), "policy-name", zoneId)).thenReturn(8L); checkFailure_isValid(Action.UPDATE, "semantic", "id/name"); @@ -387,12 +391,12 @@ public final void testIsValid_failures() throws Exception { for (boolean isAdmin : new boolean[] {true, false}) { when(policy.getService()).thenReturn(null); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForMissingValue(failures, "service name"); when(policy.getService()).thenReturn(""); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForMissingValue(failures, "service name"); } } @@ -404,22 +408,22 @@ public final void testIsValid_failures() throws Exception { for (boolean isAdmin : new boolean[] {true, false}) { when(policy.getService()).thenReturn(null); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForMissingValue(failures, "service name"); when(policy.getService()).thenReturn(null); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForMissingValue(failures, "service name"); when(policy.getService()).thenReturn("service-name"); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForSemanticError(failures, "service name"); when(policy.getService()).thenReturn("another-service-name"); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForSemanticError(failures, "service name"); } } @@ -431,12 +435,12 @@ public final void testIsValid_failures() throws Exception { // when it is null when(policy.getPolicyItems()).thenReturn(null); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForMissingValue(failures, "policy items"); // or when it is not null but empty. when(policy.getPolicyItems()).thenReturn(policyItems); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForMissingValue(failures, "policy items"); } } @@ -452,24 +456,26 @@ public final void testIsValid_failures() throws Exception { when(policy.getService()).thenReturn("service-name"); when(store.getServiceByName("service-name")).thenReturn(service); failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForInternalError(failures, "policy service def"); } } // service-def should contain the right access types on it. - serviceDef = utils.createServiceDefWithAccessTypes(accessTypesBad, "service-type"); + serviceDef = utils.createServiceDefWithAccessTypes(accessTypesBad); when(store.getServiceDefByName("service-type")).thenReturn(serviceDef); for (Action action : cu) { for (boolean isAdmin : new boolean[] {true, false}) { failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForSemanticError(failures, "policy item access type"); } } // create the right service def with right resource defs - this is the same as in the happypath test above. - serviceDef = utils.createServiceDefWithAccessTypes(accessTypes, "service-type"); + serviceDef = utils.createServiceDefWithAccessTypes(accessTypes); + when(serviceDef.getName()).thenReturn("service-type"); + when(serviceDef.getUpdateTime()).thenReturn(new Date()); when(store.getPolicyId(service.getId(), "policy-name", zoneId)).thenReturn(null); List resourceDefs = utils.createResourceDefs(resourceDefData); when(serviceDef.getResources()).thenReturn(resourceDefs); @@ -482,11 +488,11 @@ public final void testIsValid_failures() throws Exception { RangerPolicyResourceSignature signature = mock(RangerPolicyResourceSignature.class); when(factory.createPolicyResourceSignature(policy)).thenReturn(signature); when(signature.getSignature()).thenReturn("hash-1"); - when(store.getPoliciesByResourceSignature("service-name", "hash-1", true)).thenReturn(null); // store does not have any policies for that signature hash + when(store.getPoliciesByResourceSignature("service-name", "hash-1", true)).thenReturn(null); // store does not policies for that signature hash for (Action action : cu) { for (boolean isAdmin : new boolean[] {true, false}) { failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForSemanticError(failures, "resource-values", "col"); // for spurious resource: "extra" utils.checkFailureForSemanticError(failures, "isRecursive", "db"); // for specifying it as true when def did not allow it utils.checkFailureForSemanticError(failures, "isExcludes", "col"); // for specifying it as true when def did not allow it @@ -494,64 +500,70 @@ public final void testIsValid_failures() throws Exception { } // Check if error around resource signature clash are reported. have Store return policies for same signature + List existingPolicies = new ArrayList<>(); + RangerPolicy policy1 = mock(RangerPolicy.class); + existingPolicies.add(policy1); when(store.getPoliciesByResourceSignature("service-name", "hash-1", true)).thenReturn(existingPolicies); for (Action action : cu) { for (boolean isAdmin : new boolean[] {true, false}) { failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); utils.checkFailureForSemanticError(failures, "policy resources"); } } } @Test - public void test_isValidResourceValues() { + public void test_isValidResourceValues() throws Exception { + initialize(); List resourceDefs = utils.createResourceDefs(resourceDefData); when(serviceDef.getResources()).thenReturn(resourceDefs); Map policyResources = utils.createPolicyResourceMap(policyResourceMapBad); - Assert.assertFalse(validator.isValidResourceValues(policyResources, failures, serviceDef)); + assertFalse(validator.isValidResourceValues(policyResources, failures, serviceDef)); utils.checkFailureForSemanticError(failures, "resource-values", "col"); policyResources = utils.createPolicyResourceMap(policyResourceMapGood); - Assert.assertTrue(validator.isValidResourceValues(policyResources, failures, serviceDef)); + assertTrue(validator.isValidResourceValues(policyResources, failures, serviceDef)); policyResources = utils.createPolicyResourceMap(policyResourceMapBadDuplicateValues); - Assert.assertFalse(validator.isValidResourceValues(policyResources, failures, serviceDef)); + assertFalse(validator.isValidResourceValues(policyResources, failures, serviceDef)); utils.checkFailureForSemanticError(failures, "resource-values", "tbl"); policyResources = utils.createPolicyResourceMap(policyResourceMapGoodDuplicateValues); - Assert.assertTrue(validator.isValidResourceValues(policyResources, failures, serviceDef)); + assertTrue(validator.isValidResourceValues(policyResources, failures, serviceDef)); } @Test - public void test_isValidPolicyItems_failures() { + public void test_isValidPolicyItems_failures() throws Exception { + initialize(); // null/empty list is good because there is nothing - Assert.assertTrue(validator.isValidPolicyItems(null, failures, serviceDef)); + assertTrue(validator.isValidPolicyItems(null, failures, serviceDef)); failures.isEmpty(); List policyItems = new ArrayList<>(); - Assert.assertTrue(validator.isValidPolicyItems(policyItems, failures, serviceDef)); + assertTrue(validator.isValidPolicyItems(policyItems, failures, serviceDef)); failures.isEmpty(); // null elements in the list are flagged policyItems.add(null); - Assert.assertFalse(validator.isValidPolicyItems(policyItems, failures, serviceDef)); + assertFalse(validator.isValidPolicyItems(policyItems, failures, serviceDef)); utils.checkFailureForMissingValue(failures, "policy item"); } @Test - public void test_isValidPolicyItem_failures() { + public void test_isValidPolicyItem_failures() throws Exception { + initialize(); // empty access collections are invalid RangerPolicyItem policyItem = mock(RangerPolicyItem.class); when(policyItem.getAccesses()).thenReturn(null); failures.clear(); - Assert.assertFalse(validator.isValidPolicyItem(policyItem, failures, serviceDef)); + assertFalse(validator.isValidPolicyItem(policyItem, failures, serviceDef)); utils.checkFailureForMissingValue(failures, "policy item accesses"); List accesses = new ArrayList<>(); when(policyItem.getAccesses()).thenReturn(accesses); failures.clear(); - Assert.assertFalse(validator.isValidPolicyItem(policyItem, failures, serviceDef)); + assertFalse(validator.isValidPolicyItem(policyItem, failures, serviceDef)); utils.checkFailureForMissingValue(failures, "policy item accesses"); // both user and groups can't be null @@ -560,12 +572,13 @@ public void test_isValidPolicyItem_failures() { when(policyItem.getUsers()).thenReturn(null); when(policyItem.getGroups()).thenReturn(new ArrayList<>()); failures.clear(); - Assert.assertFalse(validator.isValidPolicyItem(policyItem, failures, serviceDef)); + assertFalse(validator.isValidPolicyItem(policyItem, failures, serviceDef)); utils.checkFailureForMissingValue(failures, "policy item users/user-groups/roles"); } @Test - public void test_isValidPolicyItem_happPath() { + public void test_isValidPolicyItem_happPath() throws Exception { + initialize(); // A policy item with no access is valid if it has delegated admin turned on and one user/group specified. RangerPolicyItem policyItem = mock(RangerPolicyItem.class); when(policyItem.getAccesses()).thenReturn(null); @@ -574,31 +587,34 @@ public void test_isValidPolicyItem_happPath() { List users = Arrays.asList("user1"); when(policyItem.getUsers()).thenReturn(users); failures.clear(); - Assert.assertTrue(validator.isValidPolicyItem(policyItem, failures, serviceDef)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValidPolicyItem(policyItem, failures, serviceDef)); + assertTrue(failures.isEmpty()); } @Test - public void test_isValidItemAccesses_happyPath() { + public void test_isValidItemAccesses_happyPath() throws Exception { + initialize(); // happy path Object[][] data = new Object[][] { {"a", null}, // valid {"b", true}, // valid {"c", true}, // valid }; + List accesses = utils.createItemAccess(data); serviceDef = utils.createServiceDefWithAccessTypes(new String[] {"a", "b", "c", "d"}); - Assert.assertTrue(validator.isValidItemAccesses(accesses, failures, serviceDef)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValidItemAccesses(accesses, failures, serviceDef)); + assertTrue(failures.isEmpty()); } @Test - public void test_isValidItemAccesses_failure() { + public void test_isValidItemAccesses_failure() throws Exception { + initialize(); // null policy item access values are an error List accesses = new ArrayList<>(); accesses.add(null); failures.clear(); - Assert.assertFalse(validator.isValidItemAccesses(accesses, failures, serviceDef)); + assertFalse(validator.isValidItemAccesses(accesses, failures, serviceDef)); utils.checkFailureForMissingValue(failures, "policy item access"); // all items must be valid for this call to be valid @@ -610,26 +626,28 @@ public void test_isValidItemAccesses_failure() { accesses = utils.createItemAccess(data); serviceDef = utils.createServiceDefWithAccessTypes(new String[] {"a", "b", "c", "d"}); failures.clear(); - Assert.assertFalse(validator.isValidItemAccesses(accesses, failures, serviceDef)); + assertFalse(validator.isValidItemAccesses(accesses, failures, serviceDef)); } @Test - public void test_isValidPolicyItemAccess_happyPath() { + public void test_isValidPolicyItemAccess_happyPath() throws Exception { + initialize(); RangerPolicyItemAccess access = mock(RangerPolicyItemAccess.class); when(access.getType()).thenReturn("an-Access"); // valid - Set validAccesses = Sets.newHashSet(new String[] {"an-access", "another-access"}); // valid accesses should be lower-cased + Set validAccesses = Sets.newHashSet(new String[] {"an-access", "another-access" }); // valid accesses should be lower-cased // both null or true access types are the same and valid for (Boolean allowed : new Boolean[] {null, true}) { when(access.getIsAllowed()).thenReturn(allowed); - Assert.assertTrue(validator.isValidPolicyItemAccess(access, failures, validAccesses)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValidPolicyItemAccess(access, failures, validAccesses)); + assertTrue(failures.isEmpty()); } } @Test - public void test_isValidPolicyItemAccess_failures() { + public void test_isValidPolicyItemAccess_failures() throws Exception { + initialize(); Set validAccesses = Sets.newHashSet(new String[] {"anAccess", "anotherAccess"}); // null/empty names are invalid RangerPolicyItemAccess access = mock(RangerPolicyItemAccess.class); @@ -638,45 +656,45 @@ public void test_isValidPolicyItemAccess_failures() { for (String type : new String[] {null, " \t"}) { when(access.getType()).thenReturn(type); // invalid // null/empty validAccess set skips all checks - Assert.assertTrue(validator.isValidPolicyItemAccess(access, failures, null)); - Assert.assertTrue(validator.isValidPolicyItemAccess(access, failures, new HashSet<>())); + assertTrue(validator.isValidPolicyItemAccess(access, failures, null)); + assertTrue(validator.isValidPolicyItemAccess(access, failures, new HashSet<>())); failures.clear(); - Assert.assertFalse(validator.isValidPolicyItemAccess(access, failures, validAccesses)); + assertFalse(validator.isValidPolicyItemAccess(access, failures, validAccesses)); utils.checkFailureForMissingValue(failures, "policy item access type"); } when(access.getType()).thenReturn("anAccess"); // valid when(access.getIsAllowed()).thenReturn(false); // invalid failures.clear(); - Assert.assertFalse(validator.isValidPolicyItemAccess(access, failures, validAccesses)); + assertFalse(validator.isValidPolicyItemAccess(access, failures, validAccesses)); utils.checkFailureForSemanticError(failures, "policy item access type allowed"); when(access.getType()).thenReturn("newAccessType"); // invalid failures.clear(); - Assert.assertFalse(validator.isValidPolicyItemAccess(access, failures, validAccesses)); + assertFalse(validator.isValidPolicyItemAccess(access, failures, validAccesses)); utils.checkFailureForSemanticError(failures, "policy item access type"); } @Test - public final void test_isValidResourceFlags_happyPath() { + public final void test_isValidResourceFlags_happyPath() throws Exception { + initialize(); Map resourceMap = utils.createPolicyResourceMap(policyResourceMapHappyPath); List resourceDefs = utils.createResourceDefs(resourceDefHappyPath); - when(serviceDef.getResources()).thenReturn(resourceDefs); - Assert.assertTrue(validator.isValidResourceFlags(resourceMap, failures, resourceDefs, "a-service-def", "a-policy", true)); + assertTrue(validator.isValidResourceFlags(resourceMap, failures, resourceDefs, "a-service-def", "a-policy", true)); // Since one of the resource has excludes set to true, without admin privilages it should fail and contain appropriate error messages - Assert.assertFalse(validator.isValidResourceFlags(resourceMap, failures, resourceDefs, "a-service-def", "a-policy", false)); + assertFalse(validator.isValidResourceFlags(resourceMap, failures, resourceDefs, "a-service-def", "a-policy", false)); utils.checkFailureForSemanticError(failures, "isExcludes", "isAdmin"); } @Test - public final void test_isValidResourceFlags_failures() { + public final void test_isValidResourceFlags_failures() throws Exception { + initialize(); // passing true when def says false/null List resourceDefs = utils.createResourceDefs(resourceDefHappyPath); Map resourceMap = utils.createPolicyResourceMap(policyResourceMapFailures); - when(serviceDef.getResources()).thenReturn(resourceDefs); // should not error out on - Assert.assertFalse(validator.isValidResourceFlags(resourceMap, failures, resourceDefs, "a-service-def", "a-policy", false)); + assertFalse(validator.isValidResourceFlags(resourceMap, failures, resourceDefs, "a-service-def", "a-policy", false)); utils.checkFailureForSemanticError(failures, "isExcludes", "tbl"); utils.checkFailureForSemanticError(failures, "isRecursive", "col"); utils.checkFailureForSemanticError(failures, "isExcludes", "isAdmin"); @@ -684,6 +702,7 @@ public final void test_isValidResourceFlags_failures() { @Test public final void test_isPolicyResourceUnique() throws Exception { + initialize(); // if store does not contain any matching policies then check should succeed RangerPolicyResourceSignature signature = mock(RangerPolicyResourceSignature.class); String hash = "hash-1"; @@ -694,8 +713,8 @@ public final void test_isPolicyResourceUnique() throws Exception { when(store.getPoliciesByResourceSignature("service-name", hash, true)).thenReturn(policies); policies = new ArrayList<>(); for (Action action : cu) { - Assert.assertTrue(validator.isPolicyResourceUnique(policy, failures, action)); - Assert.assertTrue(validator.isPolicyResourceUnique(policy, failures, action)); + assertTrue(validator.isPolicyResourceUnique(policy, failures, action)); + assertTrue(validator.isPolicyResourceUnique(policy, failures, action)); } /* * If store has a policy with matching signature then the check should fail with appropriate error message. @@ -705,48 +724,42 @@ public final void test_isPolicyResourceUnique() throws Exception { RangerPolicy policy1 = mock(RangerPolicy.class); policies.add(policy1); when(store.getPoliciesByResourceSignature("service-name", hash, true)).thenReturn(policies); - when(policy.getIsEnabled()).thenReturn(true); // ensure policy is enabled failures.clear(); - Assert.assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.CREATE)); + assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.CREATE)); utils.checkFailureForSemanticError(failures, "resources"); // same check should fail even if the policy is disabled - when(policy.getIsEnabled()).thenReturn(false); failures.clear(); - Assert.assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.CREATE)); + assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.CREATE)); utils.checkFailureForSemanticError(failures, "resources"); // For Update match with itself is not a problem as long as it isn't itself, i.e. same id. - when(policy.getIsEnabled()).thenReturn(true); // ensure policy is enabled when(policy1.getId()).thenReturn(103L); when(policy.getId()).thenReturn(103L); - Assert.assertTrue(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); + assertTrue(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); // matching policy can't be some other policy (i.e. different id) because that implies a conflict. when(policy1.getId()).thenReturn(104L); - Assert.assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); + assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); utils.checkFailureForSemanticError(failures, "resources"); // same check should pass if the policy is disabled - when(policy.getIsEnabled()).thenReturn(false); failures.clear(); - Assert.assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); + assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); utils.checkFailureForSemanticError(failures, "resources"); // And validation should never pass if there are more than one policies with matching signature, regardless of their ID!! RangerPolicy policy2 = mock(RangerPolicy.class); - when(policy2.getId()).thenReturn(103L); // has same id as the policy being tested (_policy) policies.add(policy2); - when(policy.getIsEnabled()).thenReturn(true); // ensure policy is enabled - Assert.assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); + assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); utils.checkFailureForSemanticError(failures, "resources"); // same check should pass if the policy is disabled - when(policy.getIsEnabled()).thenReturn(false); failures.clear(); - Assert.assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); + assertFalse(validator.isPolicyResourceUnique(policy, failures, Action.UPDATE)); utils.checkFailureForSemanticError(failures, "resources"); } @Test - public final void test_isValidResourceNames_happyPath() { + public final void test_isValidResourceNames_happyPath() throws Exception { + initialize(); String serviceName = "a-service-def"; // setup service-def Date now = new Date(); @@ -757,11 +770,12 @@ public final void test_isValidResourceNames_happyPath() { // setup policy Map policyResources = utils.createPolicyResourceMap(policyResourceMapGoodMultipleHierarchies); when(policy.getResources()).thenReturn(policyResources); - Assert.assertTrue(validator.isValidResourceNames(policy, failures, serviceDef)); + assertTrue(validator.isValidResourceNames(policy, failures, serviceDef)); } @Test - public final void test_isValidResourceNames_failures() { + public final void test_isValidResourceNames_failures() throws Exception { + initialize(); String serviceName = "a-service-def"; // setup service-def Date now = new Date(); @@ -772,26 +786,28 @@ public final void test_isValidResourceNames_failures() { // setup policy Map policyResources = utils.createPolicyResourceMap(policyResourceMapBad); when(policy.getResources()).thenReturn(policyResources); - Assert.assertFalse("Missing required resource and unknown resource", validator.isValidResourceNames(policy, failures, serviceDef)); + assertFalse(validator.isValidResourceNames(policy, failures, serviceDef), "Missing required resource and unknown resource"); utils.checkFailureForSemanticError(failures, "policy resources"); // another bad resource map that straddles multiple hierarchies policyResources = utils.createPolicyResourceMap(policyResourceMapBadMultipleHierarchies); when(policy.getResources()).thenReturn(policyResources); failures.clear(); - Assert.assertFalse("Policy with resources for multiple hierarchies", validator.isValidResourceNames(policy, failures, serviceDef)); + assertFalse(validator.isValidResourceNames(policy, failures, serviceDef), "Policy with resources for multiple hierarchies"); utils.checkFailureForSemanticError(failures, "policy resources", "incompatible"); // another bad policy resource map that could match multiple hierarchies but is short on mandatory resources for all of those matches policyResources = utils.createPolicyResourceMap(policyResourceMapBadMultipleHierarchiesMissingMandatory); when(policy.getResources()).thenReturn(policyResources); failures.clear(); - Assert.assertFalse("Policy with resources for multiple hierarchies missing mandatory resources for all pontential matches", validator.isValidResourceNames(policy, failures, serviceDef)); + assertFalse(validator.isValidResourceNames(policy, failures, serviceDef), + "Policy with resources for multiple hierarchies missing mandatory resources for all pontential matches"); utils.checkFailureForSemanticError(failures, "policy resources", "missing mandatory"); } @Test - public void test_isValidResource_additionalResources() { + public void test_isValidResource_additionalResources() throws Exception { + initialize(); String serviceName = "a-service-def"; Date now = new Date(); List resourceDefs = utils.createResourceDefs(resourceDefDataMultipleHierarchies); @@ -804,17 +820,18 @@ public void test_isValidResource_additionalResources() { when(policy.getResources()).thenReturn(resources); when(policy.getAdditionalResources()).thenReturn(additionalResources); - Assert.assertTrue("valid resources and empty additionalResources", validator.isValidResourceNames(policy, failures, serviceDef)); + assertTrue(validator.isValidResourceNames(policy, failures, serviceDef), "valid resources and empty additionalResources"); additionalResources.add(utils.createPolicyResourceMap(policyResourceMapGood)); - Assert.assertTrue("valid resources and additionalResources[0]", validator.isValidResourceNames(policy, failures, serviceDef)); + assertTrue(validator.isValidResourceNames(policy, failures, serviceDef), "valid resources and additionalResources[0]"); additionalResources.add(utils.createPolicyResourceMap(policyResourceMapBad)); - Assert.assertFalse("valid resources and invalid additionalResources[1]", validator.isValidResourceNames(policy, failures, serviceDef)); + assertFalse(validator.isValidResourceNames(policy, failures, serviceDef), "valid resources and invalid additionalResources[1]"); } @Test public final void test_isValidServiceWithZone_happyPath() throws Exception { + initialize(); boolean isAdmin = true; when(policy.getId()).thenReturn(1L); when(policy.getName()).thenReturn("my-all"); @@ -822,7 +839,6 @@ public final void test_isValidServiceWithZone_happyPath() throws Exception { when(policy.getZoneName()).thenReturn("zone1"); when(policy.getResources()).thenReturn(null); when(policy.getIsAuditEnabled()).thenReturn(Boolean.TRUE); - when(policy.getIsEnabled()).thenReturn(Boolean.FALSE); RangerService service = new RangerService(); service.setType("service-type"); service.setId(2L); @@ -839,13 +855,12 @@ public final void test_isValidServiceWithZone_happyPath() throws Exception { RangerServiceDef svcDef = new RangerServiceDef(); svcDef.setName("my-svc-def"); when(store.getServiceDefByName("service-type")).thenReturn(svcDef); - RangerPolicyResourceSignature policySignature = mock(RangerPolicyResourceSignature.class); - when(factory.createPolicyResourceSignature(policy)).thenReturn(policySignature); - Assert.assertTrue(validator.isValid(policy, action, isAdmin, failures)); + assertTrue(validator.isValid(policy, action, isAdmin, failures)); } @Test public final void test_isValidServiceWithZone_failurePath() throws Exception { + initialize(); boolean isAdmin = true; when(policy.getId()).thenReturn(1L); when(policy.getName()).thenReturn("my-all"); @@ -853,7 +868,6 @@ public final void test_isValidServiceWithZone_failurePath() throws Exception { when(policy.getZoneName()).thenReturn("zone1"); when(policy.getResources()).thenReturn(null); when(policy.getIsAuditEnabled()).thenReturn(Boolean.TRUE); - when(policy.getIsEnabled()).thenReturn(Boolean.FALSE); RangerService service = new RangerService(); service.setType("service-type"); service.setId(2L); @@ -870,12 +884,10 @@ public final void test_isValidServiceWithZone_failurePath() throws Exception { RangerServiceDef svcDef = new RangerServiceDef(); svcDef.setName("my-svc-def"); when(store.getServiceDefByName("service-type")).thenReturn(svcDef); - RangerPolicyResourceSignature policySignature = mock(RangerPolicyResourceSignature.class); - when(factory.createPolicyResourceSignature(policy)).thenReturn(policySignature); boolean isValid = validator.isValid(policy, action, isAdmin, failures); - Assert.assertFalse(isValid); - Assert.assertEquals(failures.get(0).errorCode, 3048); - Assert.assertEquals(failures.get(0).reason, "Service name = hdfssvc1 is not associated to Zone name = zone1"); + assertFalse(isValid); + assertEquals(failures.get(0).errorCode, 3048); + assertEquals(failures.get(0).reason, "Service name = hdfssvc1 is not associated to Zone name = zone1"); } void checkFailure_isValid(Action action, String errorType, String field) { @@ -885,7 +897,7 @@ void checkFailure_isValid(Action action, String errorType, String field) { void checkFailure_isValid(Action action, String errorType, String field, String subField) { for (boolean isAdmin : new boolean[] {true, false}) { failures.clear(); - Assert.assertFalse(validator.isValid(policy, action, isAdmin, failures)); + assertFalse(validator.isValid(policy, action, isAdmin, failures)); switch (errorType) { case "missing": utils.checkFailureForMissingValue(failures, field, subField); @@ -897,7 +909,7 @@ void checkFailure_isValid(Action action, String errorType, String field, String utils.checkFailureForInternalError(failures); break; default: - Assert.fail("Unsupported errorType[" + errorType + "]"); + fail("Unsupported errorType[" + errorType + "]"); break; } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerRoleValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerRoleValidator.java new file mode 100644 index 0000000000..443305b50b --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerRoleValidator.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model.validation; + +import org.apache.ranger.plugin.errors.ValidationErrorCode; +import org.apache.ranger.plugin.model.RangerRole; +import org.apache.ranger.plugin.model.validation.RangerValidator.Action; +import org.apache.ranger.plugin.store.RoleStore; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRoleValidator { + @Test + public void test01_isValidId_unsupportedAction() { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(1L, Action.CREATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_UNSUPPORTED_ACTION; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().isAnInternalError() + .becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test02_isValidId_nullId() { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid((Long) null, Action.DELETE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_FIELD; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("id").isMissing() + .errorCode(error.getErrorCode()).becauseOf(error.getMessage((Object) null)).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test03_isValidId_roleDoesNotExist() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + Mockito.when(roleStore.roleExists(7L)).thenReturn(false); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(7L, Action.DELETE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_ID; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("id").isMissing() + .errorCode(error.getErrorCode()).becauseOf(error.getMessage(7L)).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test04_isValidId_success() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + Mockito.when(roleStore.roleExists(9L)).thenReturn(true); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(9L, Action.DELETE, failures); + + Assertions.assertTrue(valid); + Assertions.assertTrue(failures.isEmpty()); + } + + @Test + public void test05_isValidName_unsupportedAction() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid("roleA", Action.UPDATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_UNSUPPORTED_ACTION; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().isAnInternalError() + .becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test06_isValidName_nullName() { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid((String) null, Action.DELETE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_FIELD; + // Implementation uses field("id") for name-missing; test reflects current + // behavior + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("id").isMissing() + .errorCode(error.getErrorCode()).becauseOf(error.getMessage((Object) null)).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test07_isValidName_notExist() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + Mockito.when(roleStore.roleExists("unknown")).thenReturn(false); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid("unknown", Action.DELETE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_NAME; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("name").isMissing() + .errorCode(error.getErrorCode()).becauseOf(error.getMessage("unknown")).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test08_isValidRole_nullRole() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid((RangerRole) null, Action.CREATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_NULL_RANGER_ROLE_OBJECT; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().isAnInternalError().isMissing() + .becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test09_isValidRole_emptyName() { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + RangerRole role = new RangerRole(); + role.setName(""); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(role, Action.CREATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_NULL_RANGER_ROLE_NAME; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("name").isMissing() + .becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test10_isValidRole_create_conflictOnSameName() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRole existing = new RangerRole(); + existing.setName("r1"); + Mockito.when(roleStore.getRole(5L)).thenReturn(existing); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + RangerRole input = new RangerRole(); + input.setId(5L); + input.setName("r1"); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(input, Action.CREATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_ROLE_NAME_CONFLICT; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("name") + .isSemanticallyIncorrect().becauseOf(error.getMessage("r1")).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test11_isValidRole_update_missingId() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + RangerRole input = new RangerRole(); + input.setName("r1"); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(input, Action.UPDATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_FIELD; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("id").isMissing() + .becauseOf(error.getMessage((Object) null)).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test12_isValidRole_update_invalidId() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + Mockito.when(roleStore.getRole(100L)).thenReturn(null); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + RangerRole input = new RangerRole(); + input.setId(100L); + input.setName("r1"); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(input, Action.UPDATE, failures); + + Assertions.assertFalse(valid); + ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_ID; + ValidationFailureDetails expected = new ValidationFailureDetailsBuilder().field("id").isSemanticallyIncorrect() + .becauseOf(error.getMessage(100L)).errorCode(error.getErrorCode()).build(); + Assertions.assertTrue(failures.contains(expected)); + } + + @Test + public void test13_validate_throws_onInvalid() { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + RangerRole input = null; + + Exception ex = Assertions.assertThrows(Exception.class, () -> validator.validate(input, Action.CREATE)); + Assertions.assertTrue(ex.getMessage() != null && ex.getMessage().contains("Validation failure")); + } + + @Test + public void test14_validate_ok_onUpdateWithExistingId() throws Exception { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRole existing = new RangerRole(); + existing.setName("x"); + Mockito.when(roleStore.getRole(11L)).thenReturn(existing); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + RangerRole input = new RangerRole(); + input.setId(11L); + input.setName("new-name"); + + List failures = new ArrayList<>(); + Assertions.assertTrue(validator.isValid(input, Action.UPDATE, failures)); + validator.validate(input, Action.UPDATE); + } + + @Test + public void test15_isValidRole_create_ok_withoutId() { + RoleStore roleStore = Mockito.mock(RoleStore.class); + RangerRoleValidator validator = new RangerRoleValidator(roleStore); + + RangerRole input = new RangerRole(); + input.setName("create-ok"); + + List failures = new ArrayList<>(); + boolean valid = validator.isValid(input, Action.CREATE, failures); + + Assertions.assertTrue(valid); + Assertions.assertTrue(failures.isEmpty()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java index b31726006c..918b67777f 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java @@ -23,39 +23,54 @@ import org.apache.ranger.authorization.utils.JsonUtils; import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerDataMaskDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerRowFilterDef; import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper.Delegate; -import org.junit.Before; -import org.junit.Test; +import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher; +import org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import static java.util.Objects.requireNonNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerServiceDefHelper { - private RangerServiceDef serviceDef; - private RangerServiceDefHelper helper; - - @Before + @BeforeEach public void before() { - serviceDef = mock(RangerServiceDef.class); - - when(serviceDef.getName()).thenReturn("a-service-def"); - // wipe the cache clean RangerServiceDefHelper.cache.clear(); } @@ -78,34 +93,43 @@ public void test_getResourceHierarchies() { * - [ Database Table Column ] * - [ Database Table Table-Attribute ] */ - RangerResourceDef database = createResourceDef("Database", ""); - RangerResourceDef udf = createResourceDef("UDF", "Database"); - RangerResourceDef table = createResourceDef("Table", "Database"); - RangerResourceDef column = createResourceDef("Column", "Table", true); - RangerResourceDef tableAttribute = createResourceDef("Table-Attribute", "Table", true); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef database = createRealResourceDef("Database", null, 1, null); + RangerResourceDef udf = createRealResourceDef("UDF", "Database", 2, null); + RangerResourceDef table = createRealResourceDef("Table", "Database", 2, null); + RangerResourceDef column = createRealResourceDef("Column", "Table", 3, true); + RangerResourceDef tableAttribute = createRealResourceDef("Table-Attribute", "Table", 3, true); // order of resources in list sould not matter List resourceDefs = Lists.newArrayList(column, database, table, tableAttribute, udf); // stuff this into a service-def when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); // now assert the behavior - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); assertTrue(helper.isResourceGraphValid()); Set> hierarchies = helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS); - List hierarchy = Lists.newArrayList(database, udf); - // there should be - assertTrue(hierarchies.contains(hierarchy)); + Set> expectedHierarchies = new HashSet<>(); + expectedHierarchies.add(Lists.newArrayList("Database", "UDF")); + expectedHierarchies.add(Lists.newArrayList("Database", "Table", "Column")); + expectedHierarchies.add(Lists.newArrayList("Database", "Table", "Table-Attribute")); - hierarchy = Lists.newArrayList(database, table, column); - assertTrue(hierarchies.contains(hierarchy)); + for (List aHierarchy : hierarchies) { + List resourceNames = helper.getAllResourceNamesOrdered(aHierarchy); + if (expectedHierarchies.contains(resourceNames)) { + expectedHierarchies.remove(resourceNames); + } + } - hierarchy = Lists.newArrayList(database, table, tableAttribute); - assertTrue(hierarchies.contains(hierarchy)); + assertTrue(expectedHierarchies.isEmpty()); } @Test @@ -117,19 +141,24 @@ public final void test_isResourceGraphValid_detectCycle() { * | | * |---- D <--- */ - RangerResourceDef a = createResourceDef("A", "D"); // A's parent is D, etc. - RangerResourceDef b = createResourceDef("B", "C"); - RangerResourceDef c = createResourceDef("C", "D"); - RangerResourceDef d = createResourceDef("D", "A"); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef a = createMockResourceDef("A", "D"); // A's parent is D, etc. + RangerResourceDef b = createMockResourceDef("B", "C"); + RangerResourceDef c = createMockResourceDef("C", "D"); + RangerResourceDef d = createMockResourceDef("D", "A"); // order of resources in list sould not matter List resourceDefs = Lists.newArrayList(a, b, c, d); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); - assertFalse("Graph was valid!", helper.isResourceGraphValid()); + assertFalse(helper.isResourceGraphValid()); } @Test @@ -148,18 +177,23 @@ public final void test_isResourceGraphValid_forest() { * * Check that helper corrects reports back all of the hierarchies: levels in it and their order. */ - RangerResourceDef database = createResourceDef("database", ""); - RangerResourceDef tableSpace = createResourceDef("table-space", "database", true); - RangerResourceDef table = createResourceDef("table", "database"); - RangerResourceDef column = createResourceDef("column", "table", true); - RangerResourceDef namespace = createResourceDef("namespace", ""); - RangerResourceDef function = createResourceDef("function", "namespace", true); - RangerResourceDef packagE = createResourceDef("package", "namespace", true); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef database = createMockResourceDef("database", ""); + RangerResourceDef tableSpace = createMockResourceDef("table-space", "database", true); + RangerResourceDef table = createMockResourceDef("table", "database"); + RangerResourceDef column = createMockResourceDef("column", "table", true); + RangerResourceDef namespace = createMockResourceDef("namespace", ""); + RangerResourceDef function = createMockResourceDef("function", "namespace", true); + RangerResourceDef packagE = createMockResourceDef("package", "namespace", true); List resourceDefs = Lists.newArrayList(database, tableSpace, table, column, namespace, function, packagE); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); assertTrue(helper.isResourceGraphValid()); @@ -179,7 +213,7 @@ public final void test_isResourceGraphValid_forest() { expectedHierarchies.remove(resourceNames); } - assertTrue("Missing hierarchies: " + expectedHierarchies, expectedHierarchies.isEmpty()); // make sure we got back all hierarchies + assertTrue(expectedHierarchies.isEmpty()); // make sure we got back all hierarchies } @Test @@ -198,16 +232,21 @@ public final void test_isResourceGraphValid_forest_singleNodeTrees() { * * Check that helper corrects reports back all of the hierarchies: levels in it and their order. */ - RangerResourceDef database = createResourceDef("database", ""); - RangerResourceDef server = createResourceDef("server", ""); - RangerResourceDef namespace = createResourceDef("namespace", ""); - RangerResourceDef function = createResourceDef("function", "namespace", true); - RangerResourceDef packagE = createResourceDef("package", "namespace", true); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef database = createRealResourceDef("database", null, 1, null); + RangerResourceDef server = createRealResourceDef("server", null, 1, null); + RangerResourceDef namespace = createRealResourceDef("namespace", null, 1, null); + RangerResourceDef function = createRealResourceDef("function", "namespace", 2, true); + RangerResourceDef packagE = createRealResourceDef("package", "namespace", 2, true); List resourceDefs = Lists.newArrayList(database, server, namespace, function, packagE); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); assertTrue(helper.isResourceGraphValid()); @@ -227,34 +266,31 @@ public final void test_isResourceGraphValid_forest_singleNodeTrees() { expectedHierarchies.remove(resourceNames); } - assertTrue("Missing hierarchies: " + expectedHierarchies, expectedHierarchies.isEmpty()); // make sure we got back all hierarchies + assertTrue(expectedHierarchies.isEmpty()); // make sure we got back all hierarchies } @Test public final void test_cacheBehavior() { - // wipe the cache clean - RangerServiceDefHelper.cache.clear(); - // let's add one entry to the cache Delegate delegate = mock(Delegate.class); Date aDate = getNow(); String serviceName = "a-service-def"; when(delegate.getServiceFreshnessDate()).thenReturn(aDate); - when(delegate.getServiceName()).thenReturn(serviceName); RangerServiceDefHelper.cache.put(serviceName, delegate); // create a service def with matching date value - serviceDef = mock(RangerServiceDef.class); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); when(serviceDef.getName()).thenReturn(serviceName); when(serviceDef.getUpdateTime()).thenReturn(aDate); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); // since cache has it, we should get back the one that we have added - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); - assertSame("Didn't get back the same object that was put in cache", delegate, helper.delegate); + assertSame(delegate, helper.delegate); // if we change the date then that should force helper to create a new delegate instance /* @@ -265,14 +301,14 @@ public final void test_cacheBehavior() { helper = new RangerServiceDefHelper(serviceDef); - assertNotSame("Didn't get a delegate different than what was put in the cache", delegate, helper.delegate); + assertNotSame(delegate, helper.delegate); // now that a new instance was added to the cache let's ensure that it got added to the cache Delegate newDelegate = helper.delegate; helper = new RangerServiceDefHelper(serviceDef); - assertSame("Didn't get a delegate different than what was put in the cache", newDelegate, helper.delegate); + assertSame(newDelegate, helper.delegate); } @Test @@ -301,40 +337,46 @@ public void test_getResourceHierarchies_with_leaf_specification() { * - [ Database Table ] * - [ Database Table Table-Attribute ] */ - RangerResourceDef database = createResourceDef("Database", "", false); - RangerResourceDef udf = createResourceDef("UDF", "Database"); - RangerResourceDef table = createResourceDef("Table", "Database", true); - RangerResourceDef column = createResourceDef("Column", "Table", true); - RangerResourceDef tableAttribute = createResourceDef("Table-Attribute", "Table", true); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef database = createRealResourceDef("Database", null, 1, false); + RangerResourceDef udf = createRealResourceDef("UDF", "Database", 2, null); + RangerResourceDef table = createRealResourceDef("Table", "Database", 2, true); + RangerResourceDef column = createRealResourceDef("Column", "Table", 3, true); + RangerResourceDef tableAttribute = createRealResourceDef("Table-Attribute", "Table", 3, true); // order of resources in list should not matter List resourceDefs = Lists.newArrayList(column, database, table, tableAttribute, udf); // stuff this into a service-def when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); // now assert the behavior - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); assertTrue(helper.isResourceGraphValid()); Set> hierarchies = helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS); - List hierarchy = Lists.newArrayList(database, udf); - // there should be - assertTrue(hierarchies.contains(hierarchy)); + Set> expectedHierarchies = new HashSet<>(); + expectedHierarchies.add(Lists.newArrayList("Database", "UDF")); + expectedHierarchies.add(Lists.newArrayList("Database", "Table", "Column")); + expectedHierarchies.add(Lists.newArrayList("Database", "Table", "Table-Attribute")); + expectedHierarchies.add(Lists.newArrayList("Database", "Table")); - hierarchy = Lists.newArrayList(database, table, column); - assertTrue(hierarchies.contains(hierarchy)); - - hierarchy = Lists.newArrayList(database, table, tableAttribute); - assertTrue(hierarchies.contains(hierarchy)); + Set> actualHierarchies = new HashSet<>(); + for (List aHierarchy : hierarchies) { + actualHierarchies.add(helper.getAllResourceNamesOrdered(aHierarchy)); + } - hierarchy = Lists.newArrayList(database, table); - assertTrue(hierarchies.contains(hierarchy)); + for (List expected : expectedHierarchies) { + assertTrue(actualHierarchies.contains(expected)); + } - hierarchy = Lists.newArrayList(database); - assertFalse(hierarchies.contains(hierarchy)); + assertFalse(actualHierarchies.contains(Lists.newArrayList("Database"))); } @Test @@ -360,18 +402,23 @@ public void test_invalid_resourceHierarchies_with_leaf_specification() { * It should fail as the hierarchy is invalid ("Error in path: sink node:[Column] is not leaf node") * */ - RangerResourceDef database = createResourceDef("Database", "", false); - RangerResourceDef udf = createResourceDef("UDF", "Database"); - RangerResourceDef table = createResourceDef("Table", "Database", true); - RangerResourceDef column = createResourceDef("Column", "Table", false); - RangerResourceDef tableAttribute = createResourceDef("Table-Attribute", "Table", true); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef database = createRealResourceDef("Database", null, 1, false); + RangerResourceDef udf = createRealResourceDef("UDF", "Database", 2, null); + RangerResourceDef table = createRealResourceDef("Table", "Database", 2, true); + RangerResourceDef column = createRealResourceDef("Column", "Table", 3, false); + RangerResourceDef tableAttribute = createRealResourceDef("Table-Attribute", "Table", 3, true); List resourceDefs = Lists.newArrayList(column, database, table, tableAttribute, udf); // order of resources in list should not matter // stuff this into a service-def when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); // now assert the behavior - helper = new RangerServiceDefHelper(serviceDef); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); assertFalse(helper.isResourceGraphValid()); } @@ -400,20 +447,526 @@ public void testRrnTemplateS3() { assertEquals("bucket/path", svcDefHelper.getRrnTemplate("path")); } - RangerResourceDef createResourceDef(String name, String parent) { - return createResourceDef(name, parent, null); + @Test + public void test_getResourceHierarchies_filteredByKeys() { + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getName()).thenReturn("a-service-def"); + when(serviceDef.getUpdateTime()).thenReturn(getNow()); + + RangerResourceDef database = createRealResourceDef("Database", null, 1, null); + RangerResourceDef udf = createRealResourceDef("UDF", "Database", 2, null); + RangerResourceDef table = createRealResourceDef("Table", "Database", 2, null); + RangerResourceDef column = createRealResourceDef("Column", "Table", 3, true); + RangerResourceDef tableAttribute = createRealResourceDef("Table-Attribute", "Table", 3, true); + + List resourceDefs = Lists.newArrayList(column, database, table, tableAttribute, udf); + when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getAccessTypes()).thenReturn(new ArrayList<>()); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); + assertTrue(helper.isResourceGraphValid()); + + Set keys = new HashSet<>(); + keys.add("Database"); + keys.add("Table"); + + Set> filtered = helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS, keys); + List expected1 = Lists.newArrayList(database, table, column); + List expected2 = Lists.newArrayList(database, table, tableAttribute); + + assertTrue(filtered.contains(expected1)); + assertTrue(filtered.contains(expected2)); } - RangerResourceDef createResourceDef(String name, String parent, Boolean isValidLeaf) { - RangerResourceDef resourceDef = mock(RangerResourceDef.class); + @Test + public void test_static_getServiceDefForPolicyFiltering_pathMatcherModification() { + RangerServiceDef base = new RangerServiceDef(); + base.setName("svc"); + base.setUpdateTime(getNow()); + base.setAccessTypes(new ArrayList<>()); + + RangerResourceDef pathRes = new RangerResourceDef(); + pathRes.setName("path"); + pathRes.setMatcher(RangerPathResourceMatcher.class.getName()); + Map opts = new HashMap<>(); + opts.put(RangerPathResourceMatcher.OPTION_PATH_SEPARATOR, "/"); + pathRes.setMatcherOptions(opts); + pathRes.setRecursiveSupported(true); + pathRes.setLevel(1); + + RangerResourceDef otherRes = new RangerResourceDef(); + otherRes.setName("other"); + otherRes.setMatcher("com.example.OtherMatcher"); + otherRes.setLevel(1); + + base.setResources(Arrays.asList(pathRes, otherRes)); + + RangerServiceDef modified = RangerServiceDefHelper.getServiceDefForPolicyFiltering(base); + + RangerResourceDef modifiedPath = null; + RangerResourceDef modifiedOther = null; + for (RangerResourceDef r : modified.getResources()) { + if ("path".equals(r.getName())) { + modifiedPath = r; + } else if ("other".equals(r.getName())) { + modifiedOther = r; + } + } + assertNotNull(modifiedPath); + assertNotNull(modifiedOther); + assertEquals("false", modifiedPath.getMatcherOptions().get(RangerAbstractResourceMatcher.OPTION_WILD_CARD)); + assertFalse(Boolean.TRUE.equals(modifiedPath.getRecursiveSupported())); + assertNull(modifiedOther.getMatcherOptions() == null ? null : modifiedOther.getMatcherOptions().get(RangerAbstractResourceMatcher.OPTION_WILD_CARD)); + } + + @Test + public void test_static_getFilterResourcesForAncestorPolicyFiltering_withDefaultDelimiterAndSuffix() { + RangerServiceDef base = new RangerServiceDef(); + base.setName("svc"); + base.setUpdateTime(getNow()); + base.setAccessTypes(new ArrayList<>()); + + RangerResourceDef pathRes = new RangerResourceDef(); + pathRes.setName("path"); + pathRes.setMatcher(RangerPathResourceMatcher.class.getName()); + pathRes.setLevel(1); + // no PATH_SEPARATOR option to force default + pathRes.setMatcherOptions(new HashMap<>()); + + RangerResourceDef otherRes = new RangerResourceDef(); + otherRes.setName("other"); + otherRes.setMatcher("com.example.OtherMatcher"); + otherRes.setLevel(1); + + base.setResources(Arrays.asList(pathRes, otherRes)); + + Map filter = new HashMap<>(); + filter.put("path", "a/b"); + + Map out = RangerServiceDefHelper.getFilterResourcesForAncestorPolicyFiltering(base, filter); + assertNotNull(out); + assertEquals("a/b/" + RangerAbstractResourceMatcher.WILDCARD_ASTERISK, out.get("path")); + } + + @Test + public void test_static_getFilterResourcesForAncestorPolicyFiltering_noMatchingReturnsNull() { + RangerServiceDef base = new RangerServiceDef(); + base.setName("svc"); + base.setUpdateTime(getNow()); + base.setAccessTypes(new ArrayList<>()); + + RangerResourceDef otherRes = new RangerResourceDef(); + otherRes.setName("other"); + otherRes.setMatcher("com.example.OtherMatcher"); + otherRes.setLevel(1); + + base.setResources(Collections.singletonList(otherRes)); + + Map filter = new HashMap<>(); + filter.put("path", "a/b"); + + Map out = RangerServiceDefHelper.getFilterResourcesForAncestorPolicyFiltering(base, filter); + assertNull(out); + } + + @Test + public void test_resourceHierarchyKeys_nullAuditUnknown() { + RangerServiceDef serviceDef = createServiceDefWithSingleNodes("svc", Arrays.asList("A", "B")); + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); + + Set> accessKeys = helper.getResourceHierarchyKeys(RangerPolicy.POLICY_TYPE_ACCESS); + assertFalse(accessKeys.isEmpty()); + Set> auditKeys = helper.getResourceHierarchyKeys(RangerPolicy.POLICY_TYPE_AUDIT); + assertIterableEquals(accessKeys, auditKeys); + + Set> nullKeys = helper.getResourceHierarchyKeys(null); + assertIterableEquals(accessKeys, nullKeys); + + Set> unknown = helper.getResourceHierarchyKeys(9999); + assertTrue(unknown.isEmpty()); + } + + @Test + public void test_isDataMaskSupported_variants() { + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("svc"); + serviceDef.setUpdateTime(getNow()); + serviceDef.setAccessTypes(new ArrayList<>()); + + RangerResourceDef dmRes = new RangerResourceDef(); + dmRes.setName("DM"); + dmRes.setLevel(1); + + RangerDataMaskDef dmd = new RangerDataMaskDef(); + dmd.setResources(Collections.singletonList(dmRes)); + serviceDef.setDataMaskDef(dmd); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); + assertTrue(helper.isDataMaskSupported()); + Set match = new HashSet<>(); + match.add("DM"); + assertTrue(helper.isDataMaskSupported(match)); + + Set noMatch = new HashSet<>(); + noMatch.add("X"); + assertFalse(helper.isDataMaskSupported(noMatch)); + } + + @Test + public void test_isRowFilterSupported_variants() { + RangerServiceDef serviceDef = new RangerServiceDef(); + serviceDef.setName("svc"); + serviceDef.setUpdateTime(getNow()); + serviceDef.setAccessTypes(new ArrayList<>()); + + RangerResourceDef rfRes = new RangerResourceDef(); + rfRes.setName("RF"); + rfRes.setLevel(1); + + RangerRowFilterDef rfd = new RangerRowFilterDef(); + rfd.setResources(Collections.singletonList(rfRes)); + serviceDef.setRowFilterDef(rfd); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(serviceDef); + assertTrue(helper.isRowFilterSupported()); + + Set match = new HashSet<>(); + match.add("RF"); + assertTrue(helper.isRowFilterSupported(match)); + + Set noMatch = new HashSet<>(); + noMatch.add("Y"); + assertFalse(helper.isRowFilterSupported(noMatch)); + } + + @Test + public void test_filterHierarchies_containsOnlyMandatoryResources() { + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setAccessTypes(new ArrayList<>()); + + RangerResourceDef r1 = new RangerResourceDef(); + r1.setName("A"); + r1.setLevel(1); + r1.setMandatory(true); + + RangerResourceDef r2 = new RangerResourceDef(); + r2.setName("B"); + r2.setParent("A"); + r2.setLevel(2); + r2.setMandatory(true); + r2.setIsValidLeaf(true); + + RangerResourceDef r3 = new RangerResourceDef(); + r3.setName("C"); + r3.setParent("B"); + r3.setLevel(3); + r3.setMandatory(false); + + svc.setResources(Arrays.asList(r1, r2, r3)); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + Set> onlyMandatory = helper.filterHierarchies_containsOnlyMandatoryResources(RangerPolicy.POLICY_TYPE_ACCESS); + assertTrue(onlyMandatory.contains(Lists.newArrayList(r1, r2))); + assertFalse(onlyMandatory.contains(Lists.newArrayList(r1, r2, r3))); + } + + @Test + public void test_isValidHierarchy_exact_vs_contains() { + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setAccessTypes(new ArrayList<>()); + + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(1); + + RangerResourceDef resB = new RangerResourceDef(); + resB.setName("B"); + resB.setParent("A"); + resB.setLevel(2); + + RangerResourceDef resC = new RangerResourceDef(); + resC.setName("C"); + resC.setParent("B"); + resC.setLevel(3); + + svc.setResources(Arrays.asList(resA, resB, resC)); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + + Set subset = new HashSet<>(); + subset.add("A"); + subset.add("B"); + + Set exact = new HashSet<>(); + exact.add("A"); + exact.add("B"); + exact.add("C"); + + assertTrue(helper.isValidHierarchy(RangerPolicy.POLICY_TYPE_ACCESS, subset, false)); + assertFalse(helper.isValidHierarchy(RangerPolicy.POLICY_TYPE_ACCESS, subset, true)); + assertTrue(helper.isValidHierarchy(RangerPolicy.POLICY_TYPE_ACCESS, exact, true)); + } + + @Test + public void test_hierarchyHasAllResources_true_false() { + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setAccessTypes(new ArrayList<>()); + + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(1); + + RangerResourceDef resB = new RangerResourceDef(); + resB.setName("B"); + resB.setParent("A"); + resB.setLevel(2); + + List hierarchy = Arrays.asList(resA, resB); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + + Set yes = new HashSet<>(); + yes.add("A"); + yes.add("B"); + assertTrue(helper.hierarchyHasAllResources(hierarchy, yes)); + + Set no = new HashSet<>(); + no.add("A"); + no.add("C"); + assertFalse(helper.hierarchyHasAllResources(hierarchy, no)); + } + + @Test + public void test_getMandatoryResourceNames_and_getAllResourceNamesOrdered() { + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(1); + resA.setMandatory(true); + + RangerResourceDef resB = new RangerResourceDef(); + resB.setName("B"); + resB.setParent("A"); + resB.setLevel(2); + resB.setMandatory(false); + + List hierarchy = Arrays.asList(resA, resB); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(createServiceDef("svc", hierarchy)); + + Set mandatory = helper.getMandatoryResourceNames(hierarchy); + assertTrue(mandatory.contains("A")); + assertFalse(mandatory.contains("B")); + + List ordered = helper.getAllResourceNamesOrdered(hierarchy); + assertIterableEquals(Arrays.asList("A", "B"), ordered); + } + + @Test + public void test_getOrderedResourceNames_orderingAndNull() { + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(2); + + RangerResourceDef resB = new RangerResourceDef(); + resB.setName("B"); + resB.setLevel(1); + + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setResources(Arrays.asList(resA, resB)); + svc.setAccessTypes(new ArrayList<>()); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc, false); + + List input = Arrays.asList("A", "B"); + List ordered = helper.getOrderedResourceNames(input); + assertIterableEquals(Arrays.asList("B", "A"), ordered); + + List nullOrdered = helper.getOrderedResourceNames(null); + assertTrue(nullOrdered.isEmpty()); + } + + @Test + public void test_getResourceDef_nullPolicyTypeAndSpecific() { + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(1); + RangerResourceDef resB = new RangerResourceDef(); + resB.setName("B"); + resB.setLevel(1); + + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setResources(Arrays.asList(resA, resB)); + svc.setAccessTypes(new ArrayList<>()); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + assertEquals("A", helper.getResourceDef("A", null).getName()); + assertNull(helper.getResourceDef("Z", RangerPolicy.POLICY_TYPE_ACCESS)); + } + + @Test + public void test_getWildcardEnabledResourceDef_cachingAndNullCase() { + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(1); + resA.setMatcher("com.example.X"); + resA.setMatcherOptions(new HashMap<>()); + + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setResources(Collections.singletonList(resA)); + svc.setAccessTypes(new ArrayList<>()); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + RangerResourceDef wr1 = helper.getWildcardEnabledResourceDef("A", RangerPolicy.POLICY_TYPE_ACCESS); + assertNotNull(wr1); + assertEquals("true", wr1.getMatcherOptions().get(RangerAbstractResourceMatcher.OPTION_WILD_CARD)); + + RangerResourceDef wr2 = helper.getWildcardEnabledResourceDef("A", RangerPolicy.POLICY_TYPE_ACCESS); + assertSame(wr1, wr2); + + RangerResourceDef missing = helper.getWildcardEnabledResourceDef("Z", RangerPolicy.POLICY_TYPE_ACCESS); + assertNull(missing); + RangerResourceDef missingAgain = helper.getWildcardEnabledResourceDef("Z", RangerPolicy.POLICY_TYPE_ACCESS); + assertNull(missingAgain); + } + + @Test + public void test_expandImpliedAccessGrants_cases() { + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + + RangerAccessTypeDef read = new RangerAccessTypeDef(); + read.setName("read"); + read.setImpliedGrants(Arrays.asList("view")); + + RangerAccessTypeDef write = new RangerAccessTypeDef(); + write.setName("write"); + write.setImpliedGrants(null); + + RangerAccessTypeDef viewMarker = new RangerAccessTypeDef(); + viewMarker.setName("view"); + viewMarker.setImpliedGrants(Arrays.asList("inspect")); + + svc.setAccessTypes(Arrays.asList(read, write)); + svc.setMarkerAccessTypes(Collections.singletonList(viewMarker)); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + + assertTrue(helper.getImpliedAccessGrants().containsKey("read")); + assertTrue(helper.getImpliedAccessGrants().containsKey("view")); + assertFalse(helper.getImpliedAccessGrants().containsKey("write")); + + Set empty = helper.expandImpliedAccessGrants(null); + assertTrue(empty.isEmpty()); + + Set none = new HashSet<>(); + none.add("write"); + Set noneOut = helper.expandImpliedAccessGrants(none); + assertSame(none, noneOut); + + Set some = new HashSet<>(); + some.add("read"); + Set expanded = helper.expandImpliedAccessGrants(some); + assertTrue(expanded.contains("read")); + assertTrue(expanded.contains("view")); + // expansion is not recursive; should not include implied of implied + assertFalse(expanded.contains("inspect")); + } + + @Test + public void test_patchServiceDefWithDefaultValues_setsLeafOnHierarchyEnds() { + RangerServiceDef svc = new RangerServiceDef(); + svc.setName("svc"); + svc.setUpdateTime(getNow()); + svc.setAccessTypes(new ArrayList<>()); + + RangerResourceDef resA = new RangerResourceDef(); + resA.setName("A"); + resA.setLevel(1); + resA.setIsValidLeaf(null); + + RangerResourceDef resB = new RangerResourceDef(); + resB.setName("B"); + resB.setParent("A"); + resB.setLevel(2); + resB.setIsValidLeaf(null); + + RangerResourceDef resC = new RangerResourceDef(); + resC.setName("C"); + resC.setParent("B"); + resC.setLevel(3); + resC.setIsValidLeaf(null); + + svc.setResources(Arrays.asList(resA, resB, resC)); + + RangerServiceDefHelper helper = new RangerServiceDefHelper(svc); + helper.patchServiceDefWithDefaultValues(); + + assertFalse(Boolean.TRUE.equals(resA.getIsValidLeaf())); + assertFalse(Boolean.TRUE.equals(resB.getIsValidLeaf())); + assertTrue(Boolean.TRUE.equals(resC.getIsValidLeaf())); + } + + private RangerServiceDef createServiceDef(String name, List resources) { + RangerServiceDef svc = new RangerServiceDef(); + svc.setName(name); + svc.setUpdateTime(getNow()); + svc.setResources(resources); + svc.setAccessTypes(new ArrayList<>()); + return svc; + } + + private RangerServiceDef createServiceDefWithSingleNodes(String name, List resourceNames) { + List defs = new ArrayList<>(); + int level = 1; + for (String rn : resourceNames) { + RangerResourceDef d = new RangerResourceDef(); + d.setName(rn); + d.setLevel(level++); + defs.add(d); + } + return createServiceDef(name, defs); + } + + private RangerResourceDef createMockResourceDef(String name, String parent) { + RangerResourceDef resourceDef = mock(RangerResourceDef.class); when(resourceDef.getName()).thenReturn(name); when(resourceDef.getParent()).thenReturn(parent); - when(resourceDef.getIsValidLeaf()).thenReturn(isValidLeaf); + return resourceDef; + } + private RangerResourceDef createMockResourceDef(String name, String parent, Boolean isValidLeaf) { + RangerResourceDef resourceDef = mock(RangerResourceDef.class); + when(resourceDef.getName()).thenReturn(name); + when(resourceDef.getParent()).thenReturn(parent); + if (isValidLeaf != null) { + when(resourceDef.getIsValidLeaf()).thenReturn(isValidLeaf); + } return resourceDef; } + private RangerResourceDef createRealResourceDef(String name, String parent, int level, Boolean isValidLeaf) { + RangerResourceDef r = new RangerResourceDef(); + r.setName(name); + r.setParent(parent); + r.setLevel(level); + r.setIsValidLeaf(isValidLeaf); + return r; + } + Date getLastMonth() { Calendar cal = GregorianCalendar.getInstance(); diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefValidator.java index e2793effe2..cff84b6473 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefValidator.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefValidator.java @@ -465,7 +465,6 @@ public final void test_isValidResourceGraph() { failures.clear(); assertFalse(validator.isValidResourceGraph(serviceDef, failures)); - utils.checkFailureForMissingValue(failures, "resource level"); utils.checkFailureForSemanticError(failures, "resource level", "20"); // level 20 is duplicate for 1 hierarchy utils.checkFailureForSemanticError(failures, "resource level", "10"); // level 10 is duplicate for another hierarchy @@ -495,6 +494,8 @@ public final void test_isValidResourceGraph() { }; resourceDefs = utils.createResourceDefs(dataGood); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getName()).thenReturn("service-name"); + when(serviceDef.getUpdateTime()).thenReturn(new Date()); failures.clear(); assertTrue(validator.isValidResourceGraph(serviceDef, failures)); assertTrue(failures.isEmpty()); @@ -509,6 +510,8 @@ public final void test_isValidResourceGraph() { resourceDefs = utils.createResourceDefs(dataCycles); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getName()).thenReturn("service-name"); + when(serviceDef.getUpdateTime()).thenReturn(new Date()); failures.clear(); assertFalse("Graph was valid!", validator.isValidResourceGraph(serviceDef, failures)); assertFalse(failures.isEmpty()); @@ -523,6 +526,8 @@ public final void test_isValidResourceGraph() { }; resourceDefs = utils.createResourceDefs(dataBad); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getName()).thenReturn("service-name"); + when(serviceDef.getUpdateTime()).thenReturn(new Date()); failures.clear(); assertFalse(validator.isValidResourceGraph(serviceDef, failures)); assertFalse(failures.isEmpty()); @@ -536,6 +541,8 @@ public final void test_isValidResourceGraph() { }; resourceDefs = utils.createResourceDefs(dataGood); when(serviceDef.getResources()).thenReturn(resourceDefs); + when(serviceDef.getName()).thenReturn("service-name"); + when(serviceDef.getUpdateTime()).thenReturn(new Date()); failures.clear(); assertTrue(validator.isValidResourceGraph(serviceDef, failures)); assertTrue(failures.isEmpty()); @@ -613,4 +620,46 @@ public final void test_isValidPolicyConditions() { utils.checkFailureForMissingValue(failures, "policy condition def evaluator", "condition-2"); utils.checkFailureForMissingValue(failures, "policy condition def evaluator", "condition-1"); } + + @Test + public final void test_isValidServiceDefDisplayName_conflicts() throws Exception { + Long id = null; + String displayName = "svc-display"; + RangerServiceDef other = mock(RangerServiceDef.class); + when(other.getId()).thenReturn(99L); + when(other.getName()).thenReturn("svc-name"); + when(store.getServiceDefByDisplayName(displayName)).thenReturn(other); + assertFalse(validator.isValidServiceDefDisplayName(displayName, id, Action.CREATE, failures)); + utils.checkFailureForSemanticError(failures, "displayName"); + + failures.clear(); + id = 7L; + assertFalse(validator.isValidServiceDefDisplayName(displayName, id, Action.UPDATE, failures)); + utils.checkFailureForSemanticError(failures, "id/displayName"); + } + + @Test + public final void test_isValidConfigs_enumTypeBranches() { + List configs = new ArrayList<>(); + RangerServiceDef.RangerServiceConfigDef enumCfg = new RangerServiceDef.RangerServiceConfigDef(); + enumCfg.setItemId(1L); + enumCfg.setName("enumCfg"); + enumCfg.setType("enum"); + enumCfg.setSubType("time-unit"); + enumCfg.setDefaultValue("year"); // not in enum + configs.add(enumCfg); + + List enumDefs = utils.createEnumDefs(new Object[][] { + {1L, "time-unit", new String[] {"day", "hour"}} + }); + + assertFalse(validator.isValidConfigs(configs, enumDefs, failures)); + utils.checkFailureForSemanticError(failures, "config def default value", "enumCfg"); + + failures.clear(); + enumCfg.setSubType("unknown-enum"); + enumCfg.setDefaultValue(null); + assertFalse(validator.isValidConfigs(configs, enumDefs, failures)); + utils.checkFailureForSemanticError(failures, "config def subtype", "enumCfg"); + } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceValidator.java index 20656339a1..bf9a907235 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceValidator.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceValidator.java @@ -25,18 +25,30 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef; import org.apache.ranger.plugin.model.validation.RangerValidator.Action; import org.apache.ranger.plugin.store.ServiceStore; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class TestRangerServiceValidator { private final Action[] cu = new Action[] {Action.CREATE, Action.UPDATE}; private ServiceStore store; @@ -45,15 +57,16 @@ public class TestRangerServiceValidator { private final ValidationTestUtils utils = new ValidationTestUtils(); private final List failures = new ArrayList<>(); - @Before - public void before() { + private void initialize() { store = mock(ServiceStore.class); action = Action.CREATE; // by default we set action to create validator = new RangerServiceValidator(store); + failures.clear(); } @Test public void testIsValidServiceNameCreationWithOutSpecialCharacters() throws Exception { + initialize(); String serviceName = "c1_yarn"; RangerService rangerService = new RangerService(); @@ -80,12 +93,13 @@ public void testIsValidServiceNameCreationWithOutSpecialCharacters() throws Exce when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, Action.CREATE, failures); - Assert.assertEquals(0, failures.size()); - Assert.assertTrue(valid); + assertEquals(0, failures.size()); + assertTrue(valid); } @Test public void testIsValidServiceNameUpdationWithOutSpecialCharacters() throws Exception { + initialize(); String serviceName = "c1_yarn"; RangerService rangerService = new RangerService(); @@ -114,12 +128,13 @@ public void testIsValidServiceNameUpdationWithOutSpecialCharacters() throws Exce when(store.getService(1L)).thenReturn(rangerService); when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, Action.UPDATE, failures); - Assert.assertEquals(0, failures.size()); - Assert.assertTrue(valid); + assertEquals(0, failures.size()); + assertTrue(valid); } @Test public void testIsValidServiceNameUpdationWithSpecialCharacters() throws Exception { + initialize(); String serviceName = "c1_yarn"; ValidationErrorCode vErrCod = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME; @@ -150,16 +165,17 @@ public void testIsValidServiceNameUpdationWithSpecialCharacters() throws Excepti when(store.getService(1L)).thenReturn(rangerService); when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); - boolean valid = validator.isValid(rangerService, Action.UPDATE, failures); + boolean valid = validator.isValid(rangerService, Action.UPDATE, failures); ValidationFailureDetails failureMessage = failures.get(0); - Assert.assertFalse(valid); - Assert.assertEquals("name", failureMessage.getFieldName()); - Assert.assertEquals(errorMessage, failureMessage.reason); - Assert.assertEquals(errorCode, failureMessage.errorCode); + assertFalse(valid); + assertEquals("name", failureMessage.getFieldName()); + assertEquals(errorMessage, failureMessage.reason); + assertEquals(errorCode, failureMessage.errorCode); } @Test public void testIsValidServiceNameCreationWithSpecialCharacters() throws Exception { + initialize(); String serviceName = ""; ValidationErrorCode vErrCod = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME; @@ -190,14 +206,15 @@ public void testIsValidServiceNameCreationWithSpecialCharacters() throws Excepti when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, action, failures); ValidationFailureDetails failureMessage = failures.get(0); - Assert.assertFalse(valid); - Assert.assertEquals("name", failureMessage.getFieldName()); - Assert.assertEquals(errorMessage, failureMessage.reason); - Assert.assertEquals(errorCode, failureMessage.errorCode); + assertFalse(valid); + assertEquals("name", failureMessage.getFieldName()); + assertEquals(errorMessage, failureMessage.reason); + assertEquals(errorCode, failureMessage.errorCode); } @Test public void testIsValidServiceNameCreationWithSpaceCharacter() throws Exception { + initialize(); String serviceName = "Cluster 1_c1_yarn"; ValidationErrorCode vErrCod = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME; @@ -229,15 +246,16 @@ public void testIsValidServiceNameCreationWithSpaceCharacter() throws Exception when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, action, failures); ValidationFailureDetails failureMessage = failures.get(0); - Assert.assertFalse(valid); - Assert.assertEquals("name", failureMessage.getFieldName()); - Assert.assertEquals(errorMessage, failureMessage.reason); - Assert.assertEquals(errorCode, failureMessage.errorCode); + assertFalse(valid); + assertEquals("name", failureMessage.getFieldName()); + assertEquals(errorMessage, failureMessage.reason); + assertEquals(errorCode, failureMessage.errorCode); } @Test public void testIsValidServiceNameUpdationWithSpaceCharacter() throws Exception { - String serviceName = "Cluster 1_c1_yarn"; + initialize(); + String serviceName = "Cluster 1_c1_yarn"; ValidationErrorCode vErrCod = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME; String errorMessage = vErrCod.getMessage(serviceName); @@ -280,20 +298,21 @@ public void testIsValidServiceNameUpdationWithSpaceCharacter() throws Exception when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, Action.UPDATE, failures); ValidationFailureDetails failureMessage = failures.get(0); - Assert.assertFalse(valid); - Assert.assertEquals("name", failureMessage.getFieldName()); - Assert.assertEquals(errorMessage, failureMessage.reason); - Assert.assertEquals(errorCode, failureMessage.errorCode); + assertFalse(valid); + assertEquals("name", failureMessage.getFieldName()); + assertEquals(errorMessage, failureMessage.reason); + assertEquals(errorCode, failureMessage.errorCode); //Case: previous service name does have space, updating with name containing space when(store.getService(1L)).thenReturn(rangerService); when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean validWithSpace = validator.isValid(rangerService, Action.UPDATE, failures); - Assert.assertTrue(validWithSpace); + assertTrue(validWithSpace); } @Test public void testIsValidServiceNameCreationWithGreater255Characters() throws Exception { + initialize(); String serviceName = "c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1"; ValidationErrorCode vErrCod = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME; @@ -324,14 +343,15 @@ public void testIsValidServiceNameCreationWithGreater255Characters() throws Exce when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, action, failures); ValidationFailureDetails failureMessage = failures.get(0); - Assert.assertFalse(valid); - Assert.assertEquals("name", failureMessage.getFieldName()); - Assert.assertEquals(errorMessage, failureMessage.reason); - Assert.assertEquals(errorCode, failureMessage.errorCode); + assertFalse(valid); + assertEquals("name", failureMessage.getFieldName()); + assertEquals(errorMessage, failureMessage.reason); + assertEquals(errorCode, failureMessage.errorCode); } @Test public void testIsValidServiceNameUpdationWithGreater255Characters() throws Exception { + initialize(); String serviceName = "c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1_yarn_c1"; ValidationErrorCode vErrCod = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME; @@ -364,17 +384,18 @@ public void testIsValidServiceNameUpdationWithGreater255Characters() throws Exce when(store.getServiceDefByName("yarn")).thenReturn(rangerServiceDef); boolean valid = validator.isValid(rangerService, Action.UPDATE, failures); ValidationFailureDetails failureMessage = failures.get(0); - Assert.assertFalse(valid); - Assert.assertEquals("name", failureMessage.getFieldName()); - Assert.assertEquals(errorMessage, failureMessage.reason); - Assert.assertEquals(errorCode, failureMessage.errorCode); + assertFalse(valid); + assertEquals("name", failureMessage.getFieldName()); + assertEquals(errorMessage, failureMessage.reason); + assertEquals(errorCode, failureMessage.errorCode); } @Test public void testIsValid_failures() throws Exception { + initialize(); RangerService service = mock(RangerService.class); // passing in a null service to the check itself is an error - Assert.assertFalse(validator.isValid((RangerService) null, action, failures)); + assertFalse(validator.isValid((RangerService) null, action, failures)); utils.checkFailureForMissingValue(failures, "service"); // id is required for update @@ -430,6 +451,7 @@ public void testIsValid_failures() throws Exception { @Test public void test_isValid_missingRequiredParameter() throws Exception { + initialize(); // Create/Update: simulate a condition where required parameters are missing Object[][] input = new Object[][] { {"param1", true}, @@ -460,6 +482,7 @@ public void test_isValid_missingRequiredParameter() throws Exception { @Test public void test_isValid_happyPath() throws Exception { + initialize(); // create a service def with some required parameters Object[][] serviceDefInput = new Object[][] { {"param1", true}, @@ -486,7 +509,7 @@ public void test_isValid_happyPath() throws Exception { // service def exists when(store.getServiceDefByName("aType")).thenReturn(serviceDef); - Assert.assertTrue(validator.isValid(service, Action.CREATE, failures)); + assertTrue(validator.isValid(service, Action.CREATE, failures)); // for update to work the only additional requirement is that id is required and service should exist // if name is not null and it points to a service then it should match the id @@ -495,40 +518,42 @@ public void test_isValid_happyPath() throws Exception { when(existingService.getId()).thenReturn(7L); when(store.getService(7L)).thenReturn(existingService); when(store.getServiceByName("aName")).thenReturn(existingService); - Assert.assertTrue(validator.isValid(service, Action.UPDATE, failures)); + assertTrue(validator.isValid(service, Action.UPDATE, failures)); // name need not point to a service for update to work, of course. when(store.getServiceByName("aName")).thenReturn(null); - Assert.assertTrue(validator.isValid(service, Action.UPDATE, failures)); + assertTrue(validator.isValid(service, Action.UPDATE, failures)); } @Test public void test_isValid_withId_errorConditions() throws Exception { + initialize(); // api that takes in long is only supported for delete currently - Assert.assertFalse(validator.isValid(1L, Action.CREATE, failures)); + assertFalse(validator.isValid(1L, Action.CREATE, failures)); utils.checkFailureForInternalError(failures); // passing in a null id is a failure! validator = new RangerServiceValidator(store); failures.clear(); - Assert.assertFalse(validator.isValid((Long) null, Action.DELETE, failures)); + assertFalse(validator.isValid((Long) null, Action.DELETE, failures)); utils.checkFailureForMissingValue(failures, "id"); // if service with that id does not exist then that, is ok because delete is idempotent when(store.getService(1L)).thenReturn(null); when(store.getService(2L)).thenThrow(new Exception()); failures.clear(); - Assert.assertTrue(validator.isValid(1L, Action.DELETE, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(1L, Action.DELETE, failures)); + assertTrue(failures.isEmpty()); failures.clear(); - Assert.assertTrue(validator.isValid(2L, Action.DELETE, failures)); - Assert.assertTrue(failures.isEmpty()); + assertTrue(validator.isValid(2L, Action.DELETE, failures)); + assertTrue(failures.isEmpty()); } @Test public void test_isValid_withId_happyPath() throws Exception { + initialize(); validator = new RangerServiceValidator(store); RangerService service = mock(RangerService.class); when(store.getService(1L)).thenReturn(service); - Assert.assertTrue(validator.isValid(1L, Action.DELETE, failures)); + assertTrue(validator.isValid(1L, Action.DELETE, failures)); } void checkFailure_isValid(RangerServiceValidator validator, RangerService service, Action action, List failures, String errorType, String field) { @@ -537,7 +562,7 @@ void checkFailure_isValid(RangerServiceValidator validator, RangerService servic void checkFailure_isValid(RangerServiceValidator validator, RangerService service, Action action, List failures, String errorType, String field, String subField) { failures.clear(); - Assert.assertFalse(validator.isValid(service, action, failures)); + assertFalse(validator.isValid(service, action, failures)); switch (errorType) { case "missing": utils.checkFailureForMissingValue(failures, field, subField); @@ -549,7 +574,7 @@ void checkFailure_isValid(RangerServiceValidator validator, RangerService servic utils.checkFailureForInternalError(failures); break; default: - Assert.fail("Unsupported errorType[" + errorType + "]"); + fail("Unsupported errorType[" + errorType + "]"); break; } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestValidationFailureDetails.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestValidationFailureDetails.java new file mode 100644 index 0000000000..376853fbfc --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestValidationFailureDetails.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.plugin.model.validation; + +import org.apache.ranger.plugin.errors.ValidationErrorCode; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestValidationFailureDetails { + @Test + public void test01_equals_hashCode_builderVsCtor() { + ValidationFailureDetails a = new ValidationFailureDetailsBuilder().field("name").subField("sub").isMissing() + .errorCode(101).becauseOf("reason1").build(); + + ValidationFailureDetails b = new ValidationFailureDetails(101, "name", "sub", true, false, false, "reason1"); + + Assertions.assertEquals(a, b); + Assertions.assertEquals(a.hashCode(), b.hashCode()); + } + + @Test + public void test02_equals_differentFields() { + ValidationFailureDetails base = new ValidationFailureDetails(101, "f", "sf", true, false, false, "r"); + ValidationFailureDetails diffError = new ValidationFailureDetails(102, "f", "sf", true, false, false, "r"); + ValidationFailureDetails diffMissing = new ValidationFailureDetails(101, "f", "sf", false, false, false, "r"); + ValidationFailureDetails diffSemantic = new ValidationFailureDetails(101, "f", "sf", true, true, false, "r"); + ValidationFailureDetails diffInternal = new ValidationFailureDetails(101, "f", "sf", true, false, true, "r"); + ValidationFailureDetails diffField = new ValidationFailureDetails(101, "f2", "sf", true, false, false, "r"); + ValidationFailureDetails diffSub = new ValidationFailureDetails(101, "f", "sf2", true, false, false, "r"); + ValidationFailureDetails diffReason = new ValidationFailureDetails(101, "f", "sf", true, false, false, "r2"); + + Assertions.assertNotEquals(base, diffError); + Assertions.assertNotEquals(base, diffMissing); + Assertions.assertNotEquals(base, diffSemantic); + Assertions.assertNotEquals(base, diffInternal); + Assertions.assertNotEquals(base, diffField); + Assertions.assertNotEquals(base, diffSub); + Assertions.assertNotEquals(base, diffReason); + } + + @Test + public void test03_toString_includesType_missing() { + ValidationFailureDetails d = new ValidationFailureDetails(0, "f", "sf", true, false, false, "rr"); + String s = d.toString(); + Assertions.assertTrue(s.contains("type[missing]")); + } + + @Test + public void test04_toString_includesType_semantic() { + ValidationFailureDetails d = new ValidationFailureDetails(0, "f", "sf", false, true, false, "rr"); + String s = d.toString(); + Assertions.assertTrue(s.contains("type[semantically incorrect]")); + } + + @Test + public void test05_toString_includesType_internal() { + ValidationFailureDetails d = new ValidationFailureDetails(0, "f", "sf", false, false, true, "rr"); + String s = d.toString(); + Assertions.assertTrue(s.contains("type[internal error]")); + } + + @Test + public void test06_ctor_fromErrorCode_messageFormatting() { + ValidationFailureDetails d = new ValidationFailureDetails( + ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_ID, "id", 7L); + String s = d.toString(); + Assertions.assertTrue(s.contains( + "error code[" + ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_ID.getErrorCode() + "]")); + Assertions.assertTrue(s.contains("field[id]")); + Assertions.assertTrue(s.contains("reason[")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/ValidationTestUtils.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/ValidationTestUtils.java index 5a0dc52239..ce08a96baa 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/ValidationTestUtils.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/ValidationTestUtils.java @@ -30,7 +30,11 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.Arrays; @@ -41,6 +45,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class ValidationTestUtils { public Map createPolicyResourceMap(Object[][] input) { if (input == null) { @@ -52,14 +62,8 @@ public Map createPolicyResourceMap(Object[][] inpu String[] valuesArray = (String[]) row[1]; Boolean isExcludes = (Boolean) row[2]; Boolean isRecursive = (Boolean) row[3]; - RangerPolicyResource aResource = mock(RangerPolicyResource.class); - if (valuesArray == null) { - when(aResource.getValues()).thenReturn(null); - } else { - when(aResource.getValues()).thenReturn(Arrays.asList(valuesArray)); - } - when(aResource.getIsExcludes()).thenReturn(isExcludes); - when(aResource.getIsRecursive()).thenReturn(isRecursive); + List values = valuesArray == null ? null : Arrays.asList(valuesArray); + RangerPolicyResource aResource = new RangerPolicyResource(values, isExcludes, isRecursive); result.put(resourceName, aResource); } return result; @@ -78,9 +82,9 @@ List createServiceConditionDefs(Object[][] input) { List result = new ArrayList<>(); for (Object[] data : input) { - RangerServiceConfigDef aConfigDef = mock(RangerServiceConfigDef.class); - when(aConfigDef.getName()).thenReturn((String) data[0]); - when(aConfigDef.getMandatory()).thenReturn((boolean) data[1]); + RangerServiceConfigDef aConfigDef = new RangerServiceConfigDef(); + aConfigDef.setName((String) data[0]); + aConfigDef.setMandatory((boolean) data[1]); result.add(aConfigDef); } @@ -106,7 +110,7 @@ void checkFailureForMissingValue(List failures, String // check if any one of the sub-fields is present void checkFailureForMissingValue(List failures, String field, String[] subFields) { if (CollectionUtils.isEmpty(failures)) { - Assert.fail("List of failures is null/empty!"); + Assertions.fail("List of failures is null/empty!"); } else { boolean found = false; int i = 0; @@ -117,7 +121,7 @@ void checkFailureForMissingValue(List failures, String } i++; } - Assert.assertTrue(failures.toString(), found); + Assertions.assertTrue(found, failures.toString()); } } @@ -131,10 +135,10 @@ void checkFailureForInternalError(List failures) { void checkFailure(List failures, Boolean internalError, Boolean missing, Boolean semanticError, String field, String subField) { if (CollectionUtils.isEmpty(failures)) { - Assert.fail("List of failures is null/empty!"); + Assertions.fail("List of failures is null/empty!"); } else { boolean found = hasFailure(failures, internalError, missing, semanticError, field, subField); - Assert.assertTrue(failures.toString(), found); + Assertions.assertTrue(found, failures.toString()); } } @@ -156,7 +160,7 @@ boolean hasFailure(List failures, Boolean internalErro } List createAccessTypeDefs(String[] names) { - Assert.assertNotNull(names); // fail if null is passed in! + Assertions.assertNotNull(names); // fail if null is passed in! List defs = new ArrayList<>(); for (String name : names) { RangerAccessTypeDef def = mock(RangerAccessTypeDef.class); @@ -296,15 +300,15 @@ List createResourceDefs(Object[][] data) { case 1: name = (String) row[0]; } - aDef = mock(RangerResourceDef.class); - when(aDef.getName()).thenReturn(name); - when(aDef.getMandatory()).thenReturn(mandatory); - when(aDef.getValidationRegEx()).thenReturn(regExPattern); - when(aDef.getExcludesSupported()).thenReturn(isExcludesSupported); - when(aDef.getRecursiveSupported()).thenReturn(isRecursiveSupported); - when(aDef.getParent()).thenReturn(parent); - when(aDef.getLevel()).thenReturn(level); - when(aDef.getIsValidLeaf()).thenReturn(null); + aDef = new RangerResourceDef(); + aDef.setName(name); + aDef.setMandatory(mandatory); + aDef.setValidationRegEx(regExPattern); + aDef.setExcludesSupported(isExcludesSupported); + aDef.setRecursiveSupported(isRecursiveSupported); + aDef.setParent(parent); + aDef.setLevel(level); + aDef.setIsValidLeaf(null); } defs.add(aDef); } @@ -322,9 +326,9 @@ List createResourceDefsWithRegEx(String[][] data) { if (row != null) { String name = row[0]; String regEx = row[1]; - aDef = mock(RangerResourceDef.class); - when(aDef.getName()).thenReturn(name); - when(aDef.getValidationRegEx()).thenReturn(regEx); + aDef = new RangerResourceDef(); + aDef.setName(name); + aDef.setValidationRegEx(regEx); } defs.add(aDef); } @@ -343,10 +347,10 @@ List createResourceDefsWithIds(Object[][] data) { Long itemId = (Long) row[0]; Integer level = (Integer) row[1]; String name = (String) row[2]; - aDef = mock(RangerResourceDef.class); - when(aDef.getName()).thenReturn(name); - when(aDef.getItemId()).thenReturn(itemId); - when(aDef.getLevel()).thenReturn(level); + aDef = new RangerResourceDef(); + aDef.setName(name); + aDef.setItemId(itemId); + aDef.setLevel(level); } defs.add(aDef); }