You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by dh...@apache.org on 2025/11/28 13:20:12 UTC
(ranger) branch master updated: RANGER-5335:Test Cases for hive-agent [ranger-hive-plugin] (#681)
This is an automated email from the ASF dual-hosted git repository.
dhavalshah9131 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 5ecf85f6f RANGER-5335:Test Cases for hive-agent [ranger-hive-plugin] (#681)
5ecf85f6f is described below
commit 5ecf85f6f2c03d3b63d845fce54572a84a477f07
Author: Bhaavesh Amol Amre <am...@gmail.com>
AuthorDate: Fri Nov 28 18:50:07 2025 +0530
RANGER-5335:Test Cases for hive-agent [ranger-hive-plugin] (#681)
---
.../${project.build.directory}/hbase_cm_hbase.json | 1 +
.../hbase_cm_hbase_roles.json | 1 +
hive-agent/pom.xml | 12 +-
.../TestXaSecureHiveAuthorizerFactory.java | 40 +
.../authorizer/TestRangerHiveAccessRequest.java | 156 +++
.../authorizer/TestRangerHiveAuditHandler.java | 297 ++++
.../hive/authorizer/TestRangerHiveAuthorizer.java | 1454 ++++++++++++++++++++
.../authorizer/TestRangerHiveAuthorizerBase.java | 166 +++
.../TestRangerHiveAuthorizerFactory.java | 49 +
.../authorizer/TestRangerHivePolicyProvider.java | 128 ++
.../hive/authorizer/TestRangerHiveResource.java | 105 ++
.../authorizer/TestRangerHiveResourceACLs.java | 61 +
.../services/hive/TestRangerServiceHive.java | 230 ++++
.../services/hive/client/TestHiveClient.java | 584 ++++++++
.../hive/client/TestHiveConnectionMgr.java | 126 ++
.../services/hive/client/TestHiveResourceMgr.java | 98 ++
16 files changed, 3505 insertions(+), 3 deletions(-)
diff --git a/agents-common/${project.build.directory}/hbase_cm_hbase.json b/agents-common/${project.build.directory}/hbase_cm_hbase.json
new file mode 100644
index 000000000..f229ea505
--- /dev/null
+++ b/agents-common/${project.build.directory}/hbase_cm_hbase.json
@@ -0,0 +1 @@
+{"serviceName":"cm_hbase","serviceId":3,"policyVersion":7141,"policies":[{"id":4,"isEnabled":true,"name":"all - table, column-family, column","policyPriority":0,"isAuditEnabled":true,"resources":{"column-family":{"values":["*"],"isExcludes":false,"isRecursive":false},"column":{"values":["*"],"isExcludes":false,"isRecursive":false},"table":{"values":["prospects","invoices"],"isExcludes":false,"isRecursive":false}},"policyItems":[{"accesses":[{"type":"read","isAllowed":true},{"type":"write [...]
\ No newline at end of file
diff --git a/agents-common/${project.build.directory}/hbase_cm_hbase_roles.json b/agents-common/${project.build.directory}/hbase_cm_hbase_roles.json
new file mode 100644
index 000000000..ff0a8cead
--- /dev/null
+++ b/agents-common/${project.build.directory}/hbase_cm_hbase_roles.json
@@ -0,0 +1 @@
+{"serviceName":"cm_hbase","roleVersion":-1,"roleUpdateTime":"20251127-18:38:48.229-+0530"}
\ No newline at end of file
diff --git a/hive-agent/pom.xml b/hive-agent/pom.xml
index feae1f724..a65d29d3a 100644
--- a/hive-agent/pom.xml
+++ b/hive-agent/pom.xml
@@ -268,9 +268,15 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <version>${slf4j.version}</version>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-inline</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/hive-agent/src/test/java/com/xasecure/authorization/hive/authorizer/TestXaSecureHiveAuthorizerFactory.java b/hive-agent/src/test/java/com/xasecure/authorization/hive/authorizer/TestXaSecureHiveAuthorizerFactory.java
new file mode 100644
index 000000000..a32609513
--- /dev/null
+++ b/hive-agent/src/test/java/com/xasecure/authorization/hive/authorizer/TestXaSecureHiveAuthorizerFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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 com.xasecure.authorization.hive.authorizer;
+
+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.assertNotNull;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for XaSecureHiveAuthorizerFactory
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestXaSecureHiveAuthorizerFactory {
+ @Test
+ public void testConstructor() {
+ XaSecureHiveAuthorizerFactory factory = new XaSecureHiveAuthorizerFactory();
+ assertNotNull(factory);
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAccessRequest.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAccessRequest.java
new file mode 100644
index 000000000..1991f44f4
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAccessRequest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.authorization.hive.authorizer;
+
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzContext;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzSessionContext;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
+import org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer.HiveAccessType;
+import org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer.HiveObjectType;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+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.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACTION_TYPE_METADATA_OPERATION;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.when;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerHiveAccessRequest
+ */
+
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveAccessRequest {
+ @Mock
+ private HiveAuthzContext mockAuthzContext;
+
+ @Mock
+ private HiveAuthzSessionContext mockSessionContext;
+
+ @Test
+ public void test01_setHiveAccessTypeMapsUseToAnyAndOthersToLowercase() {
+ RangerHiveResource resource = new RangerHiveResource(HiveObjectType.DATABASE, "db1");
+
+ RangerHiveAccessRequest useReq = new RangerHiveAccessRequest(resource, "user1", emptySet(), emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.USE, null, null);
+ assertEquals(HiveAccessType.USE, useReq.getHiveAccessType());
+ assertEquals(RangerPolicyEngine.ANY_ACCESS, useReq.getAccessType());
+
+ RangerHiveAccessRequest createReq = new RangerHiveAccessRequest(resource, "user1", emptySet(), emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.CREATE, null, null);
+ assertEquals(HiveAccessType.CREATE, createReq.getHiveAccessType());
+ assertEquals("create", createReq.getAccessType());
+ }
+
+ @Test
+ public void test02_constructorSetsMetadataDefaultsForDatabaseAndTable() {
+ // Database: expect "show databases"
+ RangerHiveResource dbResource = new RangerHiveResource(HiveObjectType.DATABASE, "");
+ when(mockAuthzContext.getCommandString()).thenReturn("");
+ when(mockAuthzContext.getForwardedAddresses()).thenReturn(Collections.singletonList("10.0.0.1"));
+ when(mockAuthzContext.getIpAddress()).thenReturn("127.0.0.1");
+ when(mockSessionContext.getSessionString()).thenReturn("session-1");
+
+ RangerHiveAccessRequest dbReq = new RangerHiveAccessRequest(dbResource, "alice", emptySet(), emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.USE, mockAuthzContext, mockSessionContext);
+ assertEquals("show databases", dbReq.getRequestData());
+ assertEquals("127.0.0.1", dbReq.getRemoteIPAddress());
+ assertEquals("session-1", dbReq.getSessionId());
+ assertNotNull(dbReq.getForwardedAddresses());
+
+ // Table: expect "show tables / views"
+ RangerHiveResource tblResource = new RangerHiveResource(HiveObjectType.TABLE, "db1", "tbl1");
+ when(mockAuthzContext.getCommandString()).thenReturn("");
+
+ RangerHiveAccessRequest tblReq = new RangerHiveAccessRequest(tblResource, "bob", emptySet(), emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.USE, mockAuthzContext, mockSessionContext);
+ assertEquals("show tables / views", tblReq.getRequestData());
+ }
+
+ @Test
+ public void test03_copyClonesAllRelevantFields() {
+ RangerHiveResource resource = new RangerHiveResource(HiveObjectType.TABLE, "dbA", "t1");
+ when(mockAuthzContext.getCommandString()).thenReturn("select 1");
+ when(mockAuthzContext.getForwardedAddresses()).thenReturn(Collections.singletonList("fwd"));
+ when(mockAuthzContext.getIpAddress()).thenReturn("1.2.3.4");
+ when(mockSessionContext.getSessionString()).thenReturn("sid");
+
+ Set<String> groups = new HashSet<>();
+ groups.add("g1");
+ Set<String> roles = new HashSet<>();
+ roles.add("r1");
+
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(resource, "u1", groups, roles, ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, mockAuthzContext, mockSessionContext);
+ req.setClusterName("cl1");
+ req.setClusterType("test");
+
+ RangerHiveAccessRequest copy = req.copy();
+
+ assertEquals(req.getResource(), copy.getResource());
+ assertEquals(req.getAccessType(), copy.getAccessType());
+ assertEquals(req.getUser(), copy.getUser());
+ assertEquals(req.getUserGroups(), copy.getUserGroups());
+ assertEquals(req.getUserRoles(), copy.getUserRoles());
+ assertEquals(req.getAction(), copy.getAction());
+ assertEquals(req.getClientIPAddress(), copy.getClientIPAddress());
+ assertEquals(req.getRemoteIPAddress(), copy.getRemoteIPAddress());
+ assertEquals(req.getForwardedAddresses(), copy.getForwardedAddresses());
+ assertEquals(req.getRequestData(), copy.getRequestData());
+ assertEquals(req.getClientType(), copy.getClientType());
+ assertEquals(req.getSessionId(), copy.getSessionId());
+ assertEquals(req.getHiveAccessType(), copy.getHiveAccessType());
+ assertEquals(req.getClusterName(), copy.getClusterName());
+ assertEquals(req.getClusterType(), copy.getClusterType());
+ }
+
+ @Test
+ public void test04_hiveOperationTypeConstructorSetsActionAndAccess() {
+ RangerHiveResource resource = new RangerHiveResource(HiveObjectType.TABLE, "db2", "t2");
+
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(resource, "user2", emptySet(), emptySet(), HiveOperationType.CREATETABLE, HiveAccessType.CREATE, null, null);
+ assertEquals(HiveAccessType.CREATE, req.getHiveAccessType());
+ assertEquals("create", req.getAccessType());
+ assertEquals(HiveOperationType.CREATETABLE.name(), req.getAction());
+ }
+
+ @Test
+ public void test05_shortConstructorSetsMetadataUseDefaults() {
+ RangerHiveResource dbResource = new RangerHiveResource(HiveObjectType.DATABASE, "");
+ when(mockAuthzContext.getCommandString()).thenReturn("");
+ when(mockAuthzContext.getForwardedAddresses()).thenReturn(Collections.singletonList("10.0.0.2"));
+ when(mockAuthzContext.getIpAddress()).thenReturn("127.0.0.2");
+
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(dbResource, "carol", emptySet(), emptySet(), mockAuthzContext, null);
+ assertEquals(HiveAccessType.USE, req.getHiveAccessType());
+ assertEquals(RangerPolicyEngine.ANY_ACCESS, req.getAccessType());
+ assertEquals(ACTION_TYPE_METADATA_OPERATION, req.getAction());
+ assertEquals("show databases", req.getRequestData());
+ }
+
+ private static Set<String> emptySet() {
+ return Collections.emptySet();
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuditHandler.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuditHandler.java
new file mode 100644
index 000000000..17618a126
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuditHandler.java
@@ -0,0 +1,297 @@
+/*
+ * 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.authorization.hive.authorizer;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
+import org.apache.ranger.audit.model.AuthzAuditEvent;
+import org.apache.ranger.audit.provider.AuditHandler;
+import org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer.HiveAccessType;
+import org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer.HiveObjectType;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACCESS_TYPE_DELETE;
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACCESS_TYPE_INSERT;
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACCESS_TYPE_ROWFILTER;
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACCESS_TYPE_TRUNCATE;
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACCESS_TYPE_UPDATE;
+import static org.apache.ranger.authorization.hive.authorizer.RangerHiveAuditHandler.ACTION_TYPE_METADATA_OPERATION;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.RETURNS_DEFAULTS;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerHiveAuditHandler
+ */
+
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveAuditHandler {
+ @Test
+ public void test01_requestDataTruncatedByConfigAndUrlLeafReplaced() {
+ Configuration conf = new Configuration(false);
+ conf.setInt(RangerHiveAuditHandler.CONF_AUDIT_QUERY_REQUEST_SIZE, 10);
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler(conf);
+
+ RangerHiveResource resource = new RangerHiveResource(HiveObjectType.URI, "/tmp/dir");
+ RangerHiveAccessRequest request = new RangerHiveAccessRequest(resource, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.USE, null, null);
+ request.setRequestData("this-is-a-very-long-query");
+
+ RangerAccessResult res = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, request);
+ res.setIsAudited(true);
+ res.setIsAllowed(true);
+ res.setPolicyId(1L);
+
+ AuthzAuditEvent event = handler.createAuditEvent(res);
+ assertNotNull(event);
+ assertEquals(ACTION_TYPE_METADATA_OPERATION, event.getAccessType());
+ assertEquals("this-is-a-", event.getRequestData());
+ // Note: Without a service-def, resourcePath/leafName may be null; skip asserting resource path/type here.
+ }
+
+ @Test
+ public void test02_datamaskAndRowfilterAccessType() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+
+ // Data mask
+ RangerHiveResource tbl = new RangerHiveResource(HiveObjectType.TABLE, "db", "t");
+ RangerHiveAccessRequest reqMask = new RangerHiveAccessRequest(tbl, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult mask = new RangerAccessResult(RangerPolicy.POLICY_TYPE_DATAMASK, "svc", null, reqMask);
+ mask.setIsAudited(true);
+ mask.setIsAllowed(true);
+ mask.setPolicyId(11L);
+ mask.setMaskType("redact");
+ AuthzAuditEvent e1 = handler.createAuditEvent(mask);
+ assertEquals("redact", e1.getAccessType());
+
+ // Row filter
+ RangerHiveAccessRequest reqRf = new RangerHiveAccessRequest(tbl, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult rowFilter = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ROWFILTER, "svc", null, reqRf);
+ rowFilter.setIsAudited(true);
+ rowFilter.setIsAllowed(true);
+ rowFilter.setPolicyId(12L);
+ rowFilter.setFilterExpr("col > 5");
+ AuthzAuditEvent e2 = handler.createAuditEvent(rowFilter);
+ assertEquals(ACCESS_TYPE_ROWFILTER, e2.getAccessType());
+ }
+
+ @Test
+ public void test03_updateAccessTypeDerivedFromCommandString() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+ RangerHiveResource tbl = new RangerHiveResource(HiveObjectType.TABLE, "db", "t");
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(tbl, "u", Collections.emptySet(), Collections.emptySet(), "QUERY", HiveAccessType.UPDATE, null, null);
+ req.setRequestData("insert into t values (1)");
+ RangerAccessResult result = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, req);
+ result.setIsAudited(true);
+ result.setIsAllowed(true);
+ result.setPolicyId(21L);
+ AuthzAuditEvent eIns = handler.createAuditEvent(result);
+ assertEquals(ACCESS_TYPE_INSERT, eIns.getAccessType());
+
+ req.setRequestData("update t set c=1");
+ AuthzAuditEvent eUpd = handler.createAuditEvent(result);
+ assertEquals(ACCESS_TYPE_UPDATE, eUpd.getAccessType());
+
+ req.setRequestData("delete from t");
+ AuthzAuditEvent eDel = handler.createAuditEvent(result);
+ assertEquals(ACCESS_TYPE_DELETE, eDel.getAccessType());
+
+ req.setRequestData("truncate table t");
+ AuthzAuditEvent eTrunc = handler.createAuditEvent(result);
+ assertEquals(ACCESS_TYPE_TRUNCATE, eTrunc.getAccessType());
+ }
+
+ @Test
+ public void test04_replAndServiceAdminAccessTypeOverrides() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+ RangerHiveResource global = new RangerHiveResource(HiveObjectType.GLOBAL, null);
+ RangerHiveAccessRequest replReq = new RangerHiveAccessRequest(global, "u", Collections.emptySet(), Collections.emptySet(), "REPL DUMP", HiveAccessType.REPLADMIN, null, null);
+ replReq.setRequestData("REPL DUMP db1 to location");
+ RangerAccessResult replRes = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, replReq);
+ replRes.setIsAudited(true);
+ replRes.setIsAllowed(true);
+ replRes.setPolicyId(31L);
+ AuthzAuditEvent eRepl = handler.createAuditEvent(replRes);
+ assertEquals("REPL DUMP", eRepl.getAccessType());
+
+ RangerHiveAccessRequest saReq = new RangerHiveAccessRequest(global, "u", Collections.emptySet(), Collections.emptySet(), "KILL_QUERY", HiveAccessType.SERVICEADMIN, null, null);
+ saReq.setRequestData("KILL QUERY q123");
+ RangerAccessResult saRes = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, saReq);
+ saRes.setIsAudited(true);
+ saRes.setIsAllowed(true);
+ saRes.setPolicyId(32L);
+ AuthzAuditEvent eSa = handler.createAuditEvent(saRes);
+ assertEquals("KILL QUERY", eSa.getAccessType());
+ assertEquals("QUERY ID = q123", eSa.getRequestData());
+ }
+
+ @Test
+ public void test05_roleOpsUseActionAsAccessTypeForGlobal() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+ RangerHiveResource global = new RangerHiveResource(HiveObjectType.GLOBAL, null);
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(global, "u", Collections.emptySet(), Collections.emptySet(), HiveOperationType.CREATEROLE.name(), HiveAccessType.USE, null, null);
+ RangerAccessResult res = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, req);
+ res.setIsAudited(true);
+ res.setIsAllowed(true);
+ res.setPolicyId(41L);
+ AuthzAuditEvent e = handler.createAuditEvent(res);
+ assertEquals(HiveOperationType.CREATEROLE.name(), e.getAccessType());
+ }
+
+ @Test
+ public void test06_processResultsAggregatesColumnsAndShortCircuitsOnDeny() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+
+ List<RangerAccessResult> results = new ArrayList<>();
+ // First allowed for column c1 under policy 100
+ RangerHiveResource col1 = new RangerHiveResource(HiveObjectType.COLUMN, "db", "t", "c1");
+ RangerHiveAccessRequest r1 = new RangerHiveAccessRequest(col1, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult a1 = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, r1);
+ a1.setIsAudited(true);
+ a1.setIsAllowed(true);
+ a1.setPolicyId(100L);
+ results.add(a1);
+ // Second allowed for column c2 under same policy 100 -> should merge columns
+ RangerHiveResource col2 = new RangerHiveResource(HiveObjectType.COLUMN, "db", "t", "c2");
+ RangerHiveAccessRequest r2 = new RangerHiveAccessRequest(col2, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult a2 = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, r2);
+ a2.setIsAudited(true);
+ a2.setIsAllowed(true);
+ a2.setPolicyId(100L);
+ results.add(a2);
+ // Third is a deny -> list should contain only the deny event
+ RangerHiveAccessRequest r3 = new RangerHiveAccessRequest(col2, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult d1 = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, r3);
+ d1.setIsAudited(true);
+ d1.setIsAllowed(false);
+ d1.setPolicyId(200L);
+ List<AuthzAuditEvent> events = handler.createAuditEvents(results);
+
+ // Before deny added, events should be one (merged). Now add deny and ensure single deny returned
+ assertEquals(1, events.size());
+ AuthzAuditEvent merged = events.get(0);
+ assertTrue(merged.getResourcePath().contains(",") || merged.getResourcePath().contains("db/t"));
+
+ results.add(d1);
+ List<AuthzAuditEvent> onlyDeny = handler.createAuditEvents(results);
+ assertEquals(1, onlyDeny.size());
+ assertEquals(0, onlyDeny.get(0).getAccessResult());
+ }
+
+ @Test
+ public void test07_flushAuditSkipsAllowedWhenDeniedExists() {
+ Configuration conf = new Configuration(false);
+ RangerHiveAuditHandler handler = spy(new RangerHiveAuditHandler(conf));
+
+ // Prepare two events: one allow, one deny
+ RangerHiveResource res = new RangerHiveResource(HiveObjectType.TABLE, "db", "t");
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(res, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult allow = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, req);
+ allow.setIsAudited(true);
+ allow.setIsAllowed(true);
+ allow.setPolicyId(1);
+ AuthzAuditEvent eAllow = handler.createAuditEvent(allow);
+ RangerAccessResult deny = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, req);
+ deny.setIsAudited(true);
+ deny.setIsAllowed(false);
+ deny.setPolicyId(2);
+ AuthzAuditEvent eDeny = handler.createAuditEvent(deny);
+
+ // Add both to handler internal queue via processResult
+ handler.processResult(allow);
+ handler.processResult(deny);
+
+ // Intercept calls to base plugin audit provider via static mocking
+ try (MockedStatic<RangerBasePlugin> base = mockStatic(RangerBasePlugin.class)) {
+ AuditHandler mockAudit = mock(AuditHandler.class, RETURNS_DEFAULTS);
+ base.when(() -> RangerBasePlugin.getAuditProvider(anyString())).thenReturn(mockAudit);
+
+ handler.flushAudit();
+
+ // when denied exists, allowed event should be skipped
+ verify(mockAudit, atLeastOnce()).log(any(AuthzAuditEvent.class));
+ }
+ }
+
+ @Test
+ public void test08_processResultsAddsAllAuditEvents() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+ RangerHiveResource tbl = new RangerHiveResource(HiveObjectType.TABLE, "db", "t");
+ RangerHiveAccessRequest r1 = new RangerHiveAccessRequest(tbl, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult a1 = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, r1);
+ a1.setIsAudited(true);
+ a1.setIsAllowed(true);
+ a1.setPolicyId(10L);
+ RangerHiveAccessRequest r2 = new RangerHiveAccessRequest(tbl, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.SELECT, null, null);
+ RangerAccessResult a2 = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, r2);
+ a2.setIsAudited(true);
+ a2.setIsAllowed(true);
+ a2.setPolicyId(20L);
+
+ List<RangerAccessResult> list = new ArrayList<>();
+ list.add(a1);
+ list.add(a2);
+
+ handler.processResults(list);
+ // if no exception occurs, events were added; flush to ensure no NPEs
+ handler.flushAudit();
+ }
+
+ @Test
+ public void test09_logAuditEventForDfsBuildsEvent() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+ handler.logAuditEventForDfs("u1", "hdfs dfs -ls /tmp", true, 1, "repo");
+ // No exception expected; flush to exercise logging path
+ handler.flushAudit();
+ }
+
+ @Test
+ public void test10_createAuditEventUsesUrlFirstElement() {
+ RangerHiveAuditHandler handler = new RangerHiveAuditHandler();
+ RangerHiveResource urlRes = new RangerHiveResource(HiveObjectType.URI, "/data/path");
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(urlRes, "u", Collections.emptySet(), Collections.emptySet(), ACTION_TYPE_METADATA_OPERATION, HiveAccessType.USE, null, null);
+ RangerAccessResult res = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, req);
+ res.setIsAudited(true);
+ res.setIsAllowed(true);
+ res.setPolicyId(5L);
+ AuthzAuditEvent ev = handler.createAuditEvent(res);
+ assertNotNull(ev);
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizer.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizer.java
new file mode 100644
index 000000000..7bba1b113
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizer.java
@@ -0,0 +1,1454 @@
+/*
+ * 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.authorization.hive.authorizer;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.FsAction;
+import org.apache.hadoop.hive.metastore.IMetaStoreClient;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
+import org.apache.hadoop.hive.metastore.api.HiveObjectType;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider;
+import org.apache.hadoop.hive.ql.security.authorization.AuthorizationUtils;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzContext;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzSessionContext;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzSessionContext.CLIENT_TYPE;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveMetastoreClientFactory;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePolicyProvider;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeInfo;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivObjectActionType;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs.AccessResult;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs.Privilege;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveRoleGrant;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.apache.ranger.plugin.util.GrantRevokeRequest;
+import org.apache.ranger.plugin.util.GrantRevokeRoleRequest;
+import org.apache.ranger.plugin.util.RangerRoles;
+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.junit.jupiter.api.function.Executable;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+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.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+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.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerHiveAuthorizer
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveAuthorizer {
+ @Test
+ public void test01_constructorInitializesPluginForHiveCLI() throws Exception {
+ setStaticHivePlugin(null);
+
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ HiveAuthenticationProvider authenticator = Mockito.mock(HiveAuthenticationProvider.class);
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ Mockito.when(sessionContext.getClientType()).thenReturn(CLIENT_TYPE.HIVECLI);
+
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, authenticator, sessionContext);
+
+ RangerBasePlugin plugin = getStaticHivePlugin();
+ assertNotNull(plugin);
+ assertEquals("hiveCLI", plugin.getAppId());
+ }
+
+ @Test
+ public void test02_getHivePolicyProviderReturnsProviderWhenPluginPresent() throws Exception {
+ setStaticHivePlugin(null);
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ Mockito.when(sessionContext.getClientType()).thenReturn(CLIENT_TYPE.HIVECLI);
+
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, sessionContext);
+
+ HivePolicyProvider provider = authorizer.getHivePolicyProvider();
+ assertNotNull(provider);
+ }
+
+ @Test
+ public void test03_getHivePolicyProviderThrowsWhenPluginNull() throws Exception {
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, null);
+
+ // Force plugin to null after construction
+ setStaticHivePlugin(null);
+
+ Executable call = authorizer::getHivePolicyProvider;
+ assertThrows(HiveAuthzPluginException.class, call);
+ }
+
+ @Test
+ public void test04_showPrivilegesThrowsWhenPluginNull() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ setStaticHivePlugin(null);
+ HivePrivilegeObject obj = new HivePrivilegeObject(HivePrivilegeObjectType.DATABASE, "db1", null);
+ Executable call = () -> authorizer.showPrivileges(null, obj);
+ HiveAuthzPluginException ex = assertThrows(HiveAuthzPluginException.class, call);
+ assertEquals("RangerHiveAuthorizer.showPrivileges error: hivePlugin is null", ex.getMessage());
+ }
+
+ @Test
+ public void test05_createHiveResourceMappings() throws Exception {
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient msClient = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(msClient);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, null);
+
+ HivePrivilegeObject db = new HivePrivilegeObject(HivePrivilegeObjectType.DATABASE, "dbA", null);
+ Map<String, String> owners = new HashMap<>();
+ owners.put("dbA", "ownerA");
+ RangerHiveResource dbRes = authorizer.createHiveResource(db, owners);
+ assertNotNull(dbRes);
+ assertEquals("dbA", dbRes.getDatabase());
+
+ HivePrivilegeObject tbl = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "dbB", "t1");
+ owners.put("dbB.t1", "ownerB");
+ RangerHiveResource tblRes = authorizer.createHiveResource(tbl, owners);
+ assertNotNull(tblRes);
+ assertEquals("dbB", tblRes.getDatabase());
+ assertEquals("t1", tblRes.getTable());
+ }
+
+ @Test
+ public void test06_needTransformReturnsTrue() {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ assertTrue(authorizer.needTransform());
+ }
+
+ @Test
+ public void test07_grantAndRevokePrivilegesThrowWhenUpdatesDisabled() throws Exception {
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, null);
+ setStaticHivePlugin(null);
+ // Disable updates
+ setRangerHivePluginUpdateFlag(false);
+
+ HivePrivilegeObject hiveObj = new HivePrivilegeObject(HivePrivilegeObjectType.DATABASE, "db1", null);
+ List<HivePrincipal> principals = Collections.singletonList(new HivePrincipal("alice", HivePrincipal.HivePrincipalType.USER));
+ List<HivePrivilege> privileges = Collections.emptyList();
+
+ assertThrows(HiveAuthzPluginException.class, () -> authorizer.grantPrivileges(principals, privileges, hiveObj, principals.get(0), true));
+ assertThrows(HiveAuthzPluginException.class, () -> authorizer.revokePrivileges(principals, privileges, hiveObj, principals.get(0), true));
+ }
+
+ @Test
+ public void test08_createRoleAuditsAndUsesReservedCheck() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ // stub createRole to avoid admin client
+ Mockito.doReturn(new RangerRole()).when(pluginSpy).createRole(Mockito.any(RangerRole.class), Mockito.any());
+ setStaticHivePlugin(pluginSpy);
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(msFactory, null, null, null));
+ // getGrantorUsername pulls from principal
+ HivePrincipal grantor = new HivePrincipal("bob", HivePrincipal.HivePrincipalType.USER);
+
+ // Success path
+ authorizer.createRole("role1", grantor);
+ // No direct verify; ensure no exception and audit path executed
+
+ // Reserved name path
+ assertThrows(HiveAuthzPluginException.class, () -> authorizer.createRole("all", grantor));
+ }
+
+ @Test
+ public void test09_dropRoleValidatesAndAudits() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doNothing().when(pluginSpy).dropRole(Mockito.anyString(), Mockito.anyString(), Mockito.any());
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("charlie");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ authorizer.dropRole("roleX");
+ // Success path confirmed by no exception
+
+ assertThrows(HiveAuthzPluginException.class, () -> authorizer.dropRole("all"));
+ }
+
+ @Test
+ public void test10_getPrincipalGrantInfoForRoleRequiresAdmin() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(false).when(pluginSpy).isServiceAdmin("dave");
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("dave");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ assertThrows(HiveAuthzPluginException.class, () -> authorizer.getPrincipalGrantInfoForRole("r1"));
+ }
+
+ @Test
+ public void test11_getRoleGrantInfoForPrincipalHappyPath() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("erin");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ List<HiveRoleGrant> grants = authorizer.getRoleGrantInfoForPrincipal(new HivePrincipal("erin", HivePrincipal.HivePrincipalType.USER));
+ assertNotNull(grants);
+ }
+
+ @Test
+ public void test12_grantAndRevokeRoleAuditFlow() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doNothing().when(pluginSpy).grantRole(Mockito.any(GrantRevokeRoleRequest.class), Mockito.any());
+ Mockito.doNothing().when(pluginSpy).revokeRole(Mockito.any(GrantRevokeRoleRequest.class), Mockito.any());
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ HivePrincipal grantor = new HivePrincipal("frank", HivePrincipal.HivePrincipalType.USER);
+ // Provide group names and session context when asked
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ Mockito.doReturn(sessionContext).when(authorizer).getHiveAuthzSessionContext();
+
+ authorizer.grantRole(Collections.singletonList(new HivePrincipal("x", HivePrincipal.HivePrincipalType.USER)), Collections.singletonList("r"), true, grantor);
+ // success implies audit + call path executed
+
+ authorizer.revokeRole(Collections.singletonList(new HivePrincipal("x", HivePrincipal.HivePrincipalType.USER)), Collections.singletonList("r"), true, grantor);
+ // success implies audit + call path executed
+ }
+
+ @Test
+ public void test13_checkPrivilegesThrowsWhenUserNull() {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ Mockito.doReturn(null).when(authorizer).getCurrentUserGroupInfo();
+ assertThrows(HiveAccessControlException.class, () -> authorizer.checkPrivileges(HiveOperationType.QUERY, Collections.emptyList(), Collections.emptyList(), Mockito.mock(HiveAuthzContext.class)));
+ }
+
+ @Test
+ public void test14_checkPrivilegesDfsOperationReturnsEarly() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("user1");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+ HivePrivilegeObject dfsObj = new HivePrivilegeObject(HivePrivilegeObjectType.DFS_URI, null, "hdfs://namenode/tmp");
+ assertThrows(HiveAccessControlException.class, () -> authorizer.checkPrivileges(HiveOperationType.DFS, Collections.singletonList(dfsObj), Collections.emptyList(), Mockito.mock(HiveAuthzContext.class)));
+ }
+
+ @Test
+ public void test15_checkPrivilegesShowDatabasesAllowed() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(allowedResult()).when(pluginSpy).isAccessAllowed(Mockito.any(RangerAccessRequestImpl.class), Mockito.any());
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("user2");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+ authorizer.checkPrivileges(HiveOperationType.SHOWDATABASES, Collections.emptyList(), Collections.emptyList(), Mockito.mock(HiveAuthzContext.class));
+ }
+
+ @Test
+ public void test17_filterListCmdObjectsNullReturnsNull() {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ List<HivePrivilegeObject> ret = authorizer.filterListCmdObjects(null, Mockito.mock(HiveAuthzContext.class));
+ assertNull(ret);
+ }
+
+ @Test
+ public void test18_filterListCmdObjectsUserNullReturnsOriginal() {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ Mockito.doReturn(null).when(authorizer).getCurrentUserGroupInfo();
+ HivePrivilegeObject obj = new HivePrivilegeObject(HivePrivilegeObjectType.DATABASE, "dbX", null);
+ List<HivePrivilegeObject> in = Collections.singletonList(obj);
+ List<HivePrivilegeObject> out = authorizer.filterListCmdObjects(in, Mockito.mock(HiveAuthzContext.class));
+ assertEquals(in, out);
+ }
+
+ @Test
+ public void test19_filterListCmdObjectsAllowsWhenPluginAllows() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(allowedResult()).when(pluginSpy).isAccessAllowed(Mockito.any(RangerAccessRequestImpl.class), Mockito.any());
+ setStaticHivePlugin(pluginSpy);
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(ms);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(msFactory, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("user4");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+ HivePrivilegeObject obj = new HivePrivilegeObject(HivePrivilegeObjectType.DATABASE, "dbY", null);
+ List<HivePrivilegeObject> out = authorizer.filterListCmdObjects(Collections.singletonList(obj), Mockito.mock(HiveAuthzContext.class));
+ assertNotNull(out);
+ assertEquals(1, out.size());
+ }
+
+ @Test
+ public void test20_getAllRolesThrowsWhenPluginNullOrUserNull() {
+ // Test user null path with valid plugin
+ try {
+ setStaticHivePlugin((RangerBasePlugin) newInstanceRangerHivePlugin("hiveCLI"));
+ } catch (Exception ignored) {
+ }
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ Mockito.doReturn(null).when(authorizer).getCurrentUserGroupInfo();
+ assertThrows(HiveAccessControlException.class, () -> authorizer.getAllRoles());
+ }
+
+ @Test
+ public void test21_getAllRolesUnauthorized() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(false).when(pluginSpy).isServiceAdmin("ua");
+ setStaticHivePlugin(pluginSpy);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("ua");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+ assertThrows(HiveAuthzPluginException.class, authorizer::getAllRoles);
+ }
+
+ @Test
+ public void test23_applyRowFilterAndColumnMaskingTransforms() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ // Row filter enabled
+ RangerAccessResult rf = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ROWFILTER, "svc", null, new RangerAccessRequestImpl());
+ rf.setFilterExpr("col > 5");
+ Mockito.doReturn(rf).when(pluginSpy).evalRowFilterPolicies(Mockito.any(RangerHiveAccessRequest.class), Mockito.any());
+ setStaticHivePlugin(pluginSpy);
+
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(ms);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(msFactory, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("um");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ HivePrivilegeObject tbl = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "dbZ", "tZ");
+ List<HivePrivilegeObject> ret = authorizer.applyRowFilterAndColumnMasking(Mockito.mock(HiveAuthzContext.class), Collections.singletonList(tbl));
+ assertNotNull(ret);
+ assertEquals(1, ret.size());
+ }
+
+ @Test
+ public void test24_getURIAccessTypeAndBuildPathForException() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getURIAccessType", HiveOperationType.class);
+ m.setAccessible(true);
+ Object read = m.invoke(authorizer, HiveOperationType.LOAD);
+ Object write = m.invoke(authorizer, HiveOperationType.EXPORT);
+ assertEquals(FsAction.READ, read);
+ assertEquals(FsAction.WRITE, write);
+
+ Method m2 = RangerHiveAuthorizer.class.getDeclaredMethod("buildPathForException", String.class, HiveOperationType.class);
+ m2.setAccessible(true);
+ String desc = (String) m2.invoke(authorizer, "db/table", HiveOperationType.DESCTABLE);
+ assertEquals("db/table/*", desc);
+ String q = (String) m2.invoke(authorizer, "db/table/part", HiveOperationType.QUERY);
+ assertTrue(q.endsWith("/*"));
+ }
+
+ @Test
+ public void test25_getAllRolesSuccess() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(true).when(pluginSpy).isServiceAdmin("sa");
+ RangerRoles roles = new RangerRoles();
+ Set<RangerRole> rr = new HashSet<>();
+ RangerRole r = new RangerRole();
+ r.setName("roleX");
+ rr.add(r);
+ roles.setRangerRoles(rr);
+ Mockito.doReturn(roles).when(pluginSpy).getRangerRoles();
+ setStaticHivePlugin(pluginSpy);
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = UserGroupInformation.createRemoteUser("sa");
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ List<String> out = authorizer.getAllRoles();
+ assertNotNull(out);
+ assertTrue(out.contains("roleX"));
+ }
+
+ @Test
+ public void test26_setCurrentRoleNoneAndAdmin() throws Exception {
+ // Ensure plugin is initialized for audit handler
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(new HashSet<>(Arrays.asList("admin", "r1")))
+ .when(pluginSpy).getRolesFromUserAndGroups(Mockito.eq("userA"), Mockito.anySet());
+ setStaticHivePlugin(pluginSpy);
+
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ HiveAuthenticationProvider authenticator = Mockito.mock(HiveAuthenticationProvider.class);
+ Mockito.when(authenticator.getUserName()).thenReturn("userA");
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, authenticator, sessionContext));
+
+ // Seed fields
+ Field fRoles = RangerHiveAuthorizer.class.getDeclaredField("currentRoles");
+ fRoles.setAccessible(true);
+ Field fFlag = RangerHiveAuthorizer.class.getDeclaredField("isCurrentRoleSet");
+ fFlag.setAccessible(true);
+
+ Set<String> roles = new HashSet<>();
+ roles.add("old");
+ fRoles.set(authorizer, roles);
+
+ // NONE clears roles
+ authorizer.setCurrentRole("NONE");
+ Set<String> afterNone = (Set<String>) fRoles.get(authorizer);
+ assertTrue(afterNone.isEmpty());
+ assertTrue((Boolean) fFlag.get(authorizer));
+
+ // ADMIN fills with admin (adminRole is computed in getCurrentRoleNamesFromRanger)
+ roles.add("x");
+ fRoles.set(authorizer, roles);
+ authorizer.setCurrentRole("admin");
+ Set<String> afterAdmin = (Set<String>) fRoles.get(authorizer);
+ assertTrue(afterAdmin.contains("admin"));
+ }
+
+ @Test
+ public void test27_isPathInFSScheme() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isPathInFSScheme", String.class);
+ m.setAccessible(true);
+ boolean hdfs = (Boolean) m.invoke(authorizer, "hdfs://nn/tmp");
+ boolean s3a = (Boolean) m.invoke(authorizer, "s3a://bucket");
+ assertFalse(s3a);
+ }
+
+ @Test
+ public void test28_getCurrentRoleNamesFromRanger_excludesAdmin() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ setStaticHivePlugin(pluginSpy);
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = Mockito.mock(UserGroupInformation.class);
+ Mockito.doReturn("bob").when(ugi).getShortUserName();
+ Mockito.doReturn(new String[] {"g1"}).when(ugi).getGroupNames();
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ Set<String> pluginRoles = new HashSet<>();
+ pluginRoles.add("analyst");
+ pluginRoles.add("admin"); // ROLE_ADMIN should be excluded from return set
+ Mockito.doReturn(pluginRoles).when(pluginSpy).getRolesFromUserAndGroups(Mockito.eq("bob"), Mockito.anySet());
+
+ Field fUser = RangerHiveAuthorizer.class.getDeclaredField("currentUserName");
+ fUser.setAccessible(true);
+ fUser.set(authorizer, "bob");
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getCurrentRoleNamesFromRanger");
+ m.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Set<String> ret = (Set<String>) m.invoke(authorizer);
+
+ assertTrue(ret.contains("analyst"));
+ assertFalse(ret.contains("admin"));
+
+ Field fAdmin = RangerHiveAuthorizer.class.getDeclaredField("adminRole");
+ fAdmin.setAccessible(true);
+ Object adminRole = fAdmin.get(authorizer);
+ assertEquals("admin", adminRole);
+ }
+
+ @Test
+ public void test29_getCurrentRoleNamesFromRanger_ugiNullThrows() throws Exception {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ Mockito.doReturn(null).when(authorizer).getCurrentUserGroupInfo();
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getCurrentRoleNamesFromRanger");
+ m.setAccessible(true);
+ assertThrows(HiveAuthzPluginException.class, () -> {
+ try {
+ m.invoke(authorizer);
+ } catch (Exception e) {
+ if (e.getCause() instanceof HiveAuthzPluginException) {
+ throw e.getCause();
+ }
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ @Test
+ public void test30_getRolesforUserAndGroups_nullPluginReturnsEmpty() throws Exception {
+ setStaticHivePlugin(null);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getRolesforUserAndGroups", String.class, Set.class);
+ m.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Set<String> ret = (Set<String>) m.invoke(authorizer, "user", new HashSet<>());
+ assertNotNull(ret);
+ assertTrue(ret.isEmpty());
+ }
+
+ @Test
+ public void test31_getHiveRoleGrant_buildsFields() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+
+ RangerRole role = new RangerRole();
+ role.setName("roleA");
+ role.setCreatedByUser("creator1");
+ role.setUpdateTime(new Date(2000L));
+
+ Class<?> roleMemberCls = Class.forName("org.apache.ranger.plugin.model.RangerRole$RoleMember");
+ Object member = roleMemberCls.getDeclaredConstructor().newInstance();
+ roleMemberCls.getMethod("setName", String.class).invoke(member, "user1");
+ roleMemberCls.getMethod("setIsAdmin", Boolean.TYPE).invoke(member, true);
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getHiveRoleGrant", RangerRole.class, roleMemberCls, String.class);
+ m.setAccessible(true);
+ Object grant = m.invoke(authorizer, role, member, HivePrincipal.HivePrincipalType.USER.name());
+
+ assertInstanceOf(HiveRoleGrant.class, grant);
+ HiveRoleGrant g = (HiveRoleGrant) grant;
+ assertEquals("roleA", g.getRoleName());
+ assertTrue(g.isGrantOption());
+ assertEquals("creator1", g.getGrantor());
+ assertEquals(HivePrincipal.HivePrincipalType.USER.name(), g.getGrantorType());
+ assertEquals("user1", g.getPrincipalName());
+ assertEquals(HivePrincipal.HivePrincipalType.USER.name(), g.getPrincipalType());
+ assertTrue(g.getGrantTime() > 0);
+ }
+
+ @Test
+ public void test32_getRangerRoleForRoleName_findsAndMissing() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ setStaticHivePlugin(pluginSpy);
+
+ RangerRoles rr = new RangerRoles();
+ Set<RangerRole> roleSet = new HashSet<>();
+ RangerRole r1 = new RangerRole();
+ r1.setName("roleX");
+ RangerRole r2 = new RangerRole();
+ r2.setName("roleY");
+ roleSet.add(r1);
+ roleSet.add(r2);
+ rr.setRangerRoles(roleSet);
+ Mockito.doReturn(rr).when(pluginSpy).getRangerRoles();
+
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getRangerRoleForRoleName", String.class);
+ m.setAccessible(true);
+ Object found = m.invoke(authorizer, "roleX");
+ assertInstanceOf(RangerRole.class, found);
+ assertEquals("roleX", ((RangerRole) found).getName());
+
+ Object missing = m.invoke(authorizer, "nope");
+ assertNull(missing);
+ }
+
+ @Test
+ public void test33_buildRequestForAlterTableSetOwnerFromCommandString_parses() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ HiveAuthzContext ctx = Mockito.mock(HiveAuthzContext.class);
+ Mockito.when(ctx.getCommandString()).thenReturn("ALTER TABLE db1.tbl1 SET OWNER USER alice");
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod(
+ "buildRequestForAlterTableSetOwnerFromCommandString",
+ String.class, Set.class, Set.class, String.class, HiveAuthzContext.class, HiveAuthzSessionContext.class);
+ m.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Object req = m.invoke(authorizer, "bob", new HashSet<>(), new HashSet<>(), "ALTERTABLE_OWNER", ctx, null);
+
+ assertInstanceOf(RangerHiveAccessRequest.class, req);
+ RangerHiveAccessRequest r = (RangerHiveAccessRequest) req;
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.ALTER, r.getHiveAccessType());
+ RangerHiveResource res = (RangerHiveResource) r.getResource();
+ assertEquals("db1", res.getDatabase());
+ assertEquals("tbl1", res.getTable());
+ }
+
+ @Test
+ public void test34_getColumnType_fromMetastore() throws Exception {
+ HivePrivilegeObject hiveObj = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(hiveObj.getType()).thenReturn(HivePrivilegeObjectType.TABLE_OR_VIEW);
+ Mockito.when(hiveObj.getDbname()).thenReturn("db1");
+ Mockito.when(hiveObj.getObjectName()).thenReturn("t1");
+
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Table table = Mockito.mock(Table.class);
+ StorageDescriptor sd = Mockito.mock(StorageDescriptor.class);
+ Mockito.when(table.getSd()).thenReturn(sd);
+ Mockito.when(sd.getCols()).thenReturn(Arrays.asList(new FieldSchema("c1", "int", null), new FieldSchema("c2", "string", null)));
+ Mockito.when(ms.getTable("db1", "t1")).thenReturn(table);
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getColumnType", HivePrivilegeObject.class, String.class, IMetaStoreClient.class);
+ m.setAccessible(true);
+ Object type = m.invoke(null, hiveObj, "c2", ms);
+ assertEquals("string", type);
+ }
+
+ @Test
+ public void test35_getMetaStoreClient_successAndException() throws Exception {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+
+ HiveMetastoreClientFactory factory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient client = Mockito.mock(IMetaStoreClient.class);
+ Mockito.doReturn(client).when(factory).getHiveMetastoreClient();
+ Mockito.doReturn(factory).when(authorizer).getMetastoreClientFactory();
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getMetaStoreClient");
+ m.setAccessible(true);
+ Object ret = m.invoke(authorizer);
+ assertNotNull(ret);
+
+ HiveMetastoreClientFactory badFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ Mockito.doThrow(new HiveAuthzPluginException("x")).when(badFactory).getHiveMetastoreClient();
+ Mockito.doReturn(badFactory).when(authorizer).getMetastoreClientFactory();
+ Object ret2 = m.invoke(authorizer);
+ assertNull(ret2);
+ }
+
+ @Test
+ public void test36_setCurrentRoleAllLoadsRoles() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(new HashSet<>(Arrays.asList("role1", "admin"))).when(pluginSpy)
+ .getRolesFromUserAndGroups(Mockito.eq("bob"), Mockito.anySet());
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ setStaticHivePlugin(pluginSpy);
+
+ UserGroupInformation ugi = Mockito.mock(UserGroupInformation.class);
+ Mockito.doReturn("bob").when(ugi).getShortUserName();
+ Mockito.doReturn(new String[] {"g1"}).when(ugi).getGroupNames();
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ HiveAuthenticationProvider auth = Mockito.mock(HiveAuthenticationProvider.class);
+ Mockito.doReturn("bob").when(auth).getUserName();
+ Mockito.doReturn(auth).when(authorizer).getHiveAuthenticator();
+
+ Field fUser = RangerHiveAuthorizer.class.getDeclaredField("currentUserName");
+ fUser.setAccessible(true);
+ fUser.set(authorizer, "bob");
+
+ Field fRoles = RangerHiveAuthorizer.class.getDeclaredField("currentRoles");
+ fRoles.setAccessible(true);
+ fRoles.set(authorizer, new HashSet<String>());
+ Field fFlag = RangerHiveAuthorizer.class.getDeclaredField("isCurrentRoleSet");
+ fFlag.setAccessible(true);
+
+ authorizer.setCurrentRole("ALL");
+ @SuppressWarnings("unchecked")
+ Set<String> roles = (Set<String>) fRoles.get(authorizer);
+ assertTrue(roles.contains("role1"));
+ assertFalse(roles.contains("admin"));
+ assertTrue((Boolean) fFlag.get(authorizer));
+ }
+
+ @Test
+ public void test37_setCurrentRoleSpecificMembership() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(new HashSet<>(Collections.singletonList("role2"))).when(pluginSpy)
+ .getRolesFromUserAndGroups(Mockito.eq("bob"), Mockito.anySet());
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ setStaticHivePlugin(pluginSpy);
+
+ UserGroupInformation ugi = Mockito.mock(UserGroupInformation.class);
+ Mockito.doReturn("bob").when(ugi).getShortUserName();
+ Mockito.doReturn(new String[] {"g1"}).when(ugi).getGroupNames();
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ HiveAuthenticationProvider auth = Mockito.mock(HiveAuthenticationProvider.class);
+ Mockito.doReturn("bob").when(auth).getUserName();
+ Mockito.doReturn(auth).when(authorizer).getHiveAuthenticator();
+
+ Field fUser = RangerHiveAuthorizer.class.getDeclaredField("currentUserName");
+ fUser.setAccessible(true);
+ fUser.set(authorizer, "bob");
+
+ Field fRoles = RangerHiveAuthorizer.class.getDeclaredField("currentRoles");
+ fRoles.setAccessible(true);
+ fRoles.set(authorizer, new HashSet<String>());
+ Field fFlag = RangerHiveAuthorizer.class.getDeclaredField("isCurrentRoleSet");
+ fFlag.setAccessible(true);
+
+ authorizer.setCurrentRole("role2");
+ @SuppressWarnings("unchecked")
+ Set<String> roles = (Set<String>) fRoles.get(authorizer);
+ assertTrue(roles.contains("role2"));
+ assertEquals(1, roles.size());
+ assertTrue((Boolean) fFlag.get(authorizer));
+ }
+
+ @Test
+ public void test38_setCurrentRoleNonMemberThrows() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ Mockito.doReturn(new HashSet<>(Collections.singletonList("roleA"))).when(pluginSpy)
+ .getRolesFromUserAndGroups(Mockito.eq("bob"), Mockito.anySet());
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ setStaticHivePlugin(pluginSpy);
+
+ UserGroupInformation ugi = Mockito.mock(UserGroupInformation.class);
+ Mockito.doReturn("bob").when(ugi).getShortUserName();
+ Mockito.doReturn(new String[] {"g1"}).when(ugi).getGroupNames();
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ HiveAuthenticationProvider auth = Mockito.mock(HiveAuthenticationProvider.class);
+ Mockito.doReturn("bob").when(auth).getUserName();
+ Mockito.doReturn(auth).when(authorizer).getHiveAuthenticator();
+
+ Field fUser = RangerHiveAuthorizer.class.getDeclaredField("currentUserName");
+ fUser.setAccessible(true);
+ fUser.set(authorizer, "bob");
+ Field fRoles = RangerHiveAuthorizer.class.getDeclaredField("currentRoles");
+ fRoles.setAccessible(true);
+ fRoles.set(authorizer, new HashSet<String>());
+
+ assertThrows(HiveAuthzPluginException.class, () -> authorizer.setCurrentRole("roleB"));
+ }
+
+ @Test
+ public void test39_getCurrentRoleNames_happyPath() throws Exception {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = Mockito.mock(UserGroupInformation.class);
+ Mockito.doReturn("carol").when(ugi).getShortUserName();
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ RangerBasePlugin plugin = (RangerBasePlugin) newInstanceRangerHivePlugin("hiveCLI");
+ setStaticHivePlugin(plugin);
+
+ Field fRoles = RangerHiveAuthorizer.class.getDeclaredField("currentRoles");
+ fRoles.setAccessible(true);
+ Set<String> roles = new HashSet<>();
+ roles.add("r1");
+ roles.add("r2");
+ fRoles.set(authorizer, roles);
+ Field fFlag = RangerHiveAuthorizer.class.getDeclaredField("isCurrentRoleSet");
+ fFlag.setAccessible(true);
+ fFlag.set(authorizer, true);
+
+ List<String> ret = authorizer.getCurrentRoleNames();
+ assertTrue(ret.contains("r1"));
+ assertTrue(ret.contains("r2"));
+ }
+
+ @Test
+ public void test40_getCurrentRoleNames_ugiNullThrows() throws Exception {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ Mockito.doReturn(null).when(authorizer).getCurrentUserGroupInfo();
+ assertThrows(HiveAuthzPluginException.class, authorizer::getCurrentRoleNames);
+ }
+
+ @Test
+ public void test41_hiveObj_fetchHiveObj_parsesDbAndTable() throws Exception {
+ Class<?> hiveObjCls = Class.forName("org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer$HiveObj");
+ Object hiveObj = hiveObjCls.getDeclaredConstructor().newInstance();
+ HiveAuthzContext ctx = Mockito.mock(HiveAuthzContext.class);
+ Mockito.when(ctx.getCommandString()).thenReturn("OP X db1.tbl2 tail");
+
+ Method m = hiveObjCls.getDeclaredMethod("fetchHiveObj", HiveAuthzContext.class);
+ m.setAccessible(true);
+ m.invoke(hiveObj, ctx);
+
+ Method getDb = hiveObjCls.getDeclaredMethod("getDatabaseName");
+ Method getTbl = hiveObjCls.getDeclaredMethod("getTableName");
+ assertEquals("db1", getDb.invoke(hiveObj));
+ assertEquals("tbl2", getTbl.invoke(hiveObj));
+ }
+
+ @Test
+ public void test42_hiveObj_fetchHiveObj_onlyDb() throws Exception {
+ Class<?> hiveObjCls = Class.forName("org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer$HiveObj");
+ Object hiveObj = hiveObjCls.getDeclaredConstructor().newInstance();
+ HiveAuthzContext ctx = Mockito.mock(HiveAuthzContext.class);
+ Mockito.when(ctx.getCommandString()).thenReturn("OP X dbonly tail");
+
+ Method m = hiveObjCls.getDeclaredMethod("fetchHiveObj", HiveAuthzContext.class);
+ m.setAccessible(true);
+ m.invoke(hiveObj, ctx);
+
+ Method getDb = hiveObjCls.getDeclaredMethod("getDatabaseName");
+ Method getTbl = hiveObjCls.getDeclaredMethod("getTableName");
+ assertEquals("dbonly", getDb.invoke(hiveObj));
+ assertNull(getTbl.invoke(hiveObj));
+ }
+
+ @Test
+ public void test43_getDataMaskAndRowFilterResult_delegatesToPlugin() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ setStaticHivePlugin(pluginSpy);
+
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ RangerHiveResource resource = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.TABLE, "db", "t");
+ RangerHiveAccessRequest req = new RangerHiveAccessRequest(resource, "u", new HashSet<>(), new HashSet<>(), "QUERY", RangerHiveAuthorizer.HiveAccessType.SELECT, null, null);
+
+ RangerAccessResult dm = Mockito.mock(RangerAccessResult.class);
+ RangerAccessResult rf = Mockito.mock(RangerAccessResult.class);
+ Mockito.doReturn(dm).when(pluginSpy).evalDataMaskPolicies(Mockito.eq(req), Mockito.isNull());
+ Mockito.doReturn(rf).when(pluginSpy).evalRowFilterPolicies(Mockito.eq(req), Mockito.isNull());
+
+ Method m1 = RangerHiveAuthorizer.class.getDeclaredMethod("getDataMaskResult", RangerHiveAccessRequest.class);
+ m1.setAccessible(true);
+ Method m2 = RangerHiveAuthorizer.class.getDeclaredMethod("getRowFilterResult", RangerHiveAccessRequest.class);
+ m2.setAccessible(true);
+
+ assertEquals(dm, m1.invoke(authorizer, req));
+ assertEquals(rf, m2.invoke(authorizer, req));
+ }
+
+ @Test
+ public void test44_isDataMaskEnabled_handlesNullAndTrue() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isDataMaskEnabled", RangerAccessResult.class);
+ m.setAccessible(true);
+ assertFalse((Boolean) m.invoke(authorizer, new Object[] {null}));
+ RangerAccessResult res = Mockito.mock(RangerAccessResult.class);
+ Mockito.when(res.isMaskEnabled()).thenReturn(true);
+ assertTrue((Boolean) m.invoke(authorizer, res));
+ }
+
+ @Test
+ public void test45_addCellValueTransformer_maskNullAndCustomType() throws Exception {
+ RangerBasePlugin pluginSpy = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ setStaticHivePlugin(pluginSpy);
+
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ UserGroupInformation ugi = Mockito.mock(UserGroupInformation.class);
+ Mockito.doReturn("alice").when(ugi).getShortUserName();
+ Mockito.doReturn(new String[] {"g"}).when(ugi).getGroupNames();
+ Mockito.doReturn(ugi).when(authorizer).getCurrentUserGroupInfo();
+
+ HivePrivilegeObject table = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(table.getType()).thenReturn(HivePrivilegeObjectType.TABLE_OR_VIEW);
+ Mockito.when(table.getDbname()).thenReturn("db1");
+ Mockito.when(table.getObjectName()).thenReturn("t1");
+
+ // First: MASK_TYPE_NULL
+ RangerAccessResult dmNull = Mockito.mock(RangerAccessResult.class);
+ Mockito.when(dmNull.isMaskEnabled()).thenReturn(true);
+ Mockito.when(dmNull.getMaskType()).thenReturn(RangerPolicy.MASK_TYPE_NULL);
+ Mockito.when(dmNull.getMaskTypeDef()).thenReturn(null);
+ Mockito.doReturn(dmNull).when(pluginSpy).evalDataMaskPolicies(Mockito.any(), Mockito.any());
+
+ List<String> transformers = new ArrayList<>();
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Map<String, String> owners = new HashMap<>();
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod(
+ "addCellValueTransformerAndCheckIfTransformed",
+ HiveAuthzContext.class, HivePrivilegeObject.class, String.class, List.class, IMetaStoreClient.class, Map.class);
+ m.setAccessible(true);
+ boolean enabled = (Boolean) m.invoke(authorizer, null, table, "c1", transformers, ms, owners);
+ assertTrue(enabled);
+ assertEquals("NULL", transformers.get(0));
+
+ // Second: custom masked value with {colType}
+ RangerAccessResult dmTx = Mockito.mock(RangerAccessResult.class);
+ Mockito.when(dmTx.isMaskEnabled()).thenReturn(true);
+ Mockito.when(dmTx.getMaskType()).thenReturn(RangerPolicy.MASK_TYPE_CUSTOM);
+ Mockito.when(dmTx.getMaskedValue()).thenReturn("cast({col} as {colType})");
+ Mockito.when(dmTx.getMaskTypeDef()).thenReturn(null);
+ Mockito.doReturn(dmTx).when(pluginSpy).evalDataMaskPolicies(Mockito.any(), Mockito.any());
+
+ // stub column type
+ Table hiveTable = Mockito.mock(Table.class);
+ StorageDescriptor sd = Mockito.mock(StorageDescriptor.class);
+ Mockito.when(hiveTable.getSd()).thenReturn(sd);
+ Mockito.when(sd.getCols()).thenReturn(Collections.singletonList(new FieldSchema("c1", "int", null)));
+ Mockito.when(ms.getTable("db1", "t1")).thenReturn(hiveTable);
+
+ List<String> transformers2 = new ArrayList<>();
+ boolean enabled2 = (Boolean) m.invoke(authorizer, null, table, "c1", transformers2, ms, owners);
+ assertTrue(enabled2);
+ assertEquals("cast(c1 as int)", transformers2.get(0));
+ }
+
+ @Test
+ public void test46_getHiveResource_databaseCreateNoOwnerLookup() throws Exception {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ HiveMetastoreClientFactory factory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.doReturn(ms).when(factory).getHiveMetastoreClient();
+ Mockito.doReturn(factory).when(authorizer).getMetastoreClientFactory();
+ HivePrivilegeObject hiveObj = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(hiveObj.getType()).thenReturn(HivePrivilegeObjectType.DATABASE);
+ Mockito.when(hiveObj.getDbname()).thenReturn("db1");
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getHiveResource", HiveOperationType.class, HivePrivilegeObject.class, List.class, List.class, Map.class);
+ m.setAccessible(true);
+ Object res = m.invoke(authorizer, HiveOperationType.CREATEDATABASE, hiveObj, Collections.emptyList(), Collections.emptyList(), new HashMap<>());
+ assertInstanceOf(RangerHiveResource.class, res);
+ RangerHiveResource r = (RangerHiveResource) res;
+ assertEquals(RangerHiveAuthorizer.HiveObjectType.DATABASE, r.getObjectType());
+ assertEquals("db1", r.getDatabase());
+ }
+
+ @Test
+ public void test47_isCreateOperation_trueAndFalse() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isCreateOperation", HiveOperationType.class);
+ m.setAccessible(true);
+ assertTrue((Boolean) m.invoke(authorizer, HiveOperationType.CREATETABLE));
+ assertFalse((Boolean) m.invoke(authorizer, HiveOperationType.DROPTABLE));
+ }
+
+ @Test
+ public void test48_getDatabaseObject_outputsThenInputs() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ HivePrivilegeObject outDb = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(outDb.getType()).thenReturn(HivePrivilegeObjectType.DATABASE);
+ Mockito.when(outDb.getDbname()).thenReturn("db1");
+ HivePrivilegeObject inDb = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(inDb.getType()).thenReturn(HivePrivilegeObjectType.DATABASE);
+ Mockito.when(inDb.getDbname()).thenReturn("db1");
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getDatabaseObject", String.class, List.class, List.class);
+ m.setAccessible(true);
+ Object res1 = m.invoke(authorizer, "db1", Collections.singletonList(inDb), Collections.singletonList(outDb));
+ assertEquals(outDb, res1);
+ Object res2 = m.invoke(authorizer, "db1", Collections.singletonList(inDb), Collections.emptyList());
+ assertEquals(inDb, res2);
+ }
+
+ @Test
+ public void test49_getObjectType_mappings() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getObjectType", HivePrivilegeObject.class, HiveOperationType.class);
+ m.setAccessible(true);
+
+ HivePrivilegeObject db = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(db.getType()).thenReturn(HivePrivilegeObjectType.DATABASE);
+ assertEquals(RangerHiveAuthorizer.HiveObjectType.DATABASE, m.invoke(authorizer, db, HiveOperationType.QUERY));
+
+ HivePrivilegeObject part = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(part.getType()).thenReturn(HivePrivilegeObjectType.PARTITION);
+ assertEquals(RangerHiveAuthorizer.HiveObjectType.PARTITION, m.invoke(authorizer, part, HiveOperationType.QUERY));
+
+ HivePrivilegeObject tableWithCols = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(tableWithCols.getType()).thenReturn(HivePrivilegeObjectType.TABLE_OR_VIEW);
+ Mockito.when(tableWithCols.getColumns()).thenReturn(Collections.singletonList("c1"));
+ assertEquals(RangerHiveAuthorizer.HiveObjectType.COLUMN, m.invoke(authorizer, tableWithCols, HiveOperationType.QUERY));
+
+ HivePrivilegeObject view = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(view.getType()).thenReturn(HivePrivilegeObjectType.TABLE_OR_VIEW);
+ Mockito.when(view.getColumns()).thenReturn(null);
+ assertEquals(RangerHiveAuthorizer.HiveObjectType.VIEW, m.invoke(authorizer, view, HiveOperationType.CREATEVIEW));
+
+ HivePrivilegeObject uri = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(uri.getType()).thenReturn(HivePrivilegeObjectType.DFS_URI);
+ assertEquals(RangerHiveAuthorizer.HiveObjectType.URI, m.invoke(authorizer, uri, HiveOperationType.QUERY));
+ }
+
+ @Test
+ public void test50_isURIAccessAllowed_actionNoneShortCircuits() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isURIAccessAllowed", String.class, FsAction.class, Path.class, FileSystem.class);
+ m.setAccessible(true);
+ boolean ret = (Boolean) m.invoke(authorizer, "user", FsAction.NONE, new Path("/a"), null);
+ assertTrue(ret);
+ }
+
+ @Test
+ public void test51_resolvePath_successAndException() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ FileSystem fs = Mockito.mock(FileSystem.class);
+ Path p = new Path("/x");
+ Path resolved = new Path("/y");
+ Mockito.when(fs.resolvePath(p)).thenReturn(resolved);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("resolvePath", Path.class, FileSystem.class);
+ m.setAccessible(true);
+ assertEquals(resolved, m.invoke(authorizer, p, fs));
+ Mockito.when(fs.resolvePath(p)).thenThrow(new IOException("x"));
+ assertNull(m.invoke(authorizer, p, fs));
+ }
+
+ @Test
+ public void test52_isMountedFs_trueWhenChildrenPresent() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ FileSystem fs = Mockito.mock(FileSystem.class);
+ FileSystem[] children = new FileSystem[] {Mockito.mock(FileSystem.class)};
+ Mockito.when(fs.getChildFileSystems()).thenReturn(children);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isMountedFs", FileSystem.class);
+ m.setAccessible(true);
+ assertTrue((Boolean) m.invoke(authorizer, fs));
+ Mockito.when(fs.getChildFileSystems()).thenReturn(null);
+ assertFalse((Boolean) m.invoke(authorizer, fs));
+ }
+
+ @Test
+ public void test53_existsByResourceAndAccessType() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("existsByResourceAndAccessType", Collection.class, RangerHiveResource.class, RangerHiveAuthorizer.HiveAccessType.class);
+ m.setAccessible(true);
+ RangerHiveResource r1 = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.TABLE, "db", "t");
+ RangerHiveAccessRequest request = new RangerHiveAccessRequest(r1, "u", new HashSet<>(), new HashSet<>(), "QUERY", RangerHiveAuthorizer.HiveAccessType.SELECT, null, null);
+ List<RangerHiveAccessRequest> list = new ArrayList<>();
+ list.add(request);
+ assertTrue((Boolean) m.invoke(authorizer, list, r1, RangerHiveAuthorizer.HiveAccessType.SELECT));
+ RangerHiveResource r2 = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.TABLE, "db", "t2");
+ assertFalse((Boolean) m.invoke(authorizer, list, r2, RangerHiveAuthorizer.HiveAccessType.SELECT));
+ }
+
+ @Test
+ public void test54_getAccessType_uriReadWrite() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getAccessType", HivePrivilegeObject.class, HiveOperationType.class, RangerHiveAuthorizer.HiveObjectType.class, boolean.class);
+ m.setAccessible(true);
+ HivePrivilegeObject uriObj = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(uriObj.getActionType()).thenReturn(HivePrivObjectActionType.OTHER);
+ Object read = m.invoke(authorizer, uriObj, HiveOperationType.QUERY, RangerHiveAuthorizer.HiveObjectType.URI, true);
+ Object write = m.invoke(authorizer, uriObj, HiveOperationType.QUERY, RangerHiveAuthorizer.HiveObjectType.URI, false);
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.READ, read);
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.WRITE, write);
+ }
+
+ @Test
+ public void test56_getAccessType_otherMappingsVarious() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getAccessType", HivePrivilegeObject.class, HiveOperationType.class, RangerHiveAuthorizer.HiveObjectType.class, boolean.class);
+ m.setAccessible(true);
+ HivePrivilegeObject dbObj = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(dbObj.getActionType()).thenReturn(HivePrivObjectActionType.OTHER);
+ Mockito.when(dbObj.getType()).thenReturn(HivePrivilegeObjectType.DATABASE);
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.CREATE, m.invoke(authorizer, dbObj, HiveOperationType.CREATEDATABASE, RangerHiveAuthorizer.HiveObjectType.DATABASE, false));
+ HivePrivilegeObject funcObj = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(funcObj.getActionType()).thenReturn(HivePrivObjectActionType.OTHER);
+ Mockito.when(funcObj.getType()).thenReturn(HivePrivilegeObjectType.FUNCTION);
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.CREATE, m.invoke(authorizer, funcObj, HiveOperationType.CREATEFUNCTION, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // CREATE VIEW/TABLE: input -> SELECT, output -> CREATE
+ HivePrivilegeObject tblObj = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(tblObj.getActionType()).thenReturn(HivePrivObjectActionType.OTHER);
+ Mockito.when(tblObj.getType()).thenReturn(HivePrivilegeObjectType.TABLE_OR_VIEW);
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.SELECT, m.invoke(authorizer, tblObj, HiveOperationType.CREATETABLE, RangerHiveAuthorizer.HiveObjectType.TABLE, true));
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.CREATE, m.invoke(authorizer, tblObj, HiveOperationType.CREATETABLE, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // ALTERVIEW_AS: input table -> SELECT; output -> ALTER
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.SELECT, m.invoke(authorizer, tblObj, HiveOperationType.ALTERVIEW_AS, RangerHiveAuthorizer.HiveObjectType.TABLE, true));
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.ALTER, m.invoke(authorizer, tblObj, HiveOperationType.ALTERVIEW_AS, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // ALTER operations map to ALTER
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.ALTER, m.invoke(authorizer, tblObj, HiveOperationType.ALTERTABLE_ADDCOLS, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // DROP operations map to DROP
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.DROP, m.invoke(authorizer, tblObj, HiveOperationType.DROPTABLE, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // IMPORT input -> SELECT, output -> CREATE
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.SELECT, m.invoke(authorizer, tblObj, HiveOperationType.IMPORT, RangerHiveAuthorizer.HiveObjectType.TABLE, true));
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.CREATE, m.invoke(authorizer, tblObj, HiveOperationType.IMPORT, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // EXPORT/LOAD: input -> SELECT; output -> UPDATE
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.SELECT, m.invoke(authorizer, tblObj, HiveOperationType.EXPORT, RangerHiveAuthorizer.HiveObjectType.TABLE, true));
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.UPDATE, m.invoke(authorizer, tblObj, HiveOperationType.EXPORT, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // LOCK
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.LOCK, m.invoke(authorizer, tblObj, HiveOperationType.LOCKTABLE, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // Metadata SELECT
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.SELECT, m.invoke(authorizer, tblObj, HiveOperationType.SHOW_TBLPROPERTIES, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // USE
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.USE, m.invoke(authorizer, tblObj, HiveOperationType.SHOWDATABASES, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // TRUNCATE -> UPDATE
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.UPDATE, m.invoke(authorizer, tblObj, HiveOperationType.TRUNCATETABLE, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // GRANT/REVOKE_PRIVILEGE -> NONE
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.NONE, m.invoke(authorizer, tblObj, HiveOperationType.GRANT_PRIVILEGE, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // REPL* -> REPLADMIN
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.REPLADMIN, m.invoke(authorizer, tblObj, HiveOperationType.REPLDUMP, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // SERVICEADMIN
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.SERVICEADMIN, m.invoke(authorizer, tblObj, HiveOperationType.KILL_QUERY, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ // TEMPUDFADMIN
+ assertEquals(RangerHiveAuthorizer.HiveAccessType.TEMPUDFADMIN, m.invoke(authorizer, tblObj, HiveOperationType.COMPILE, RangerHiveAuthorizer.HiveObjectType.TABLE, false));
+ }
+
+ @Test
+ public void test57_isPathInFSScheme_trueFalse() throws Exception {
+ Object pluginObj = newInstanceRangerHivePlugin("hiveCLI");
+ setStaticHivePlugin((RangerBasePlugin) pluginObj);
+ Field fsField = pluginObj.getClass().getDeclaredField("fsScheme");
+ fsField.setAccessible(true);
+ fsField.set(pluginObj, new String[] {"hdfs://", "file://"});
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isPathInFSScheme", String.class);
+ m.setAccessible(true);
+ assertTrue((Boolean) m.invoke(authorizer, "hdfs://nn/tmp"));
+ assertFalse((Boolean) m.invoke(authorizer, "s3a://bucket"));
+ }
+
+ @Test
+ public void test58_createGrantRevokeData_buildsRequest() throws Exception {
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(null, null, null, null));
+ RangerHiveResource res = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.TABLE, "db1", "t1");
+ List<HivePrincipal> principals = Arrays.asList(new HivePrincipal("alice", HivePrincipal.HivePrincipalType.USER), new HivePrincipal("dev", HivePrincipal.HivePrincipalType.GROUP));
+ HivePrivilege p1 = Mockito.mock(HivePrivilege.class);
+ Mockito.when(p1.getName()).thenReturn("select");
+ HivePrivilege p2 = Mockito.mock(HivePrivilege.class);
+ Mockito.when(p2.getName()).thenReturn("Insert");
+ List<HivePrivilege> privs = Arrays.asList(p1, p2);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("createGrantRevokeData", RangerHiveResource.class, List.class, List.class, HivePrincipal.class, boolean.class);
+ m.setAccessible(true);
+ Object out = m.invoke(authorizer, res, principals, privs, principals.get(0), true);
+ assertInstanceOf(GrantRevokeRequest.class, out);
+ GrantRevokeRequest req = (GrantRevokeRequest) out;
+ assertEquals("db1", req.getResource().get("database"));
+ assertEquals("t1", req.getResource().get("table"));
+ assertTrue(req.getUsers().contains("alice"));
+ assertTrue(req.getGroups().contains("dev"));
+ assertTrue(req.getAccessTypes().contains("select"));
+ assertTrue(req.getAccessTypes().contains("update"));
+ }
+
+ @Test
+ public void test59_getPluginPrivilegeObjType_mappingsAndAssertion() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getPluginPrivilegeObjType", HiveObjectType.class);
+ m.setAccessible(true);
+ assertThrows(AssertionError.class, () -> {
+ try {
+ m.invoke(authorizer, HiveObjectType.PARTITION);
+ } catch (Exception e) {
+ if (e.getCause() instanceof AssertionError) {
+ throw e.getCause();
+ }
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ @Test
+ public void test60_isTempUDFOperation_trueAndFalse() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("isTempUDFOperation", String.class, HivePrivilegeObject.class);
+ m.setAccessible(true);
+
+ HivePrivilegeObject objNoDb = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(objNoDb.getDbname()).thenReturn("");
+ assertTrue((Boolean) m.invoke(authorizer, "createfunction", objNoDb));
+ assertTrue((Boolean) m.invoke(authorizer, "dropfunction", objNoDb));
+
+ HivePrivilegeObject objWithDb = Mockito.mock(HivePrivilegeObject.class);
+ Mockito.when(objWithDb.getDbname()).thenReturn("db1");
+ assertFalse((Boolean) m.invoke(authorizer, "createfunction", objWithDb));
+ assertFalse((Boolean) m.invoke(authorizer, "otherop", objNoDb));
+ }
+
+ @Test
+ public void test61_convertRangerACLsToHiveACLs_mapsValues() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("convertRangerACLsToHiveACLs", Map.class);
+ m.setAccessible(true);
+
+ Map<String, Map<String, RangerResourceACLs.AccessResult>> input = new HashMap<>();
+ Map<String, RangerResourceACLs.AccessResult> alice = new HashMap<>();
+ alice.put("select", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_ALLOWED, null));
+ alice.put("update", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_DENIED, null));
+ alice.put("drop", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_CONDITIONAL, null));
+ input.put("alice", alice);
+
+ @SuppressWarnings("unchecked")
+ Map<String, Map<Privilege, AccessResult>> out = (Map<String, Map<Privilege, AccessResult>>) m.invoke(authorizer, input);
+ assertNotNull(out);
+ Map<Privilege, AccessResult> perms = out.get("alice");
+ assertEquals(AccessResult.ALLOWED, perms.get(Privilege.SELECT));
+ assertEquals(AccessResult.NOT_ALLOWED, perms.get(Privilege.UPDATE));
+ assertEquals(AccessResult.CONDITIONAL_ALLOWED, perms.get(Privilege.DROP));
+ }
+
+ @Test
+ public void test62_getPermission_variants() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method mCheck = RangerHiveAuthorizer.class.getDeclaredMethod("checkACLIsAllowed", Privilege.class, Map.class);
+ Method mPerm = RangerHiveAuthorizer.class.getDeclaredMethod("getPermission", Privilege.class, Map.class, RangerPolicy.class);
+ mCheck.setAccessible(true);
+ mPerm.setAccessible(true);
+
+ Map<String, RangerResourceACLs.AccessResult> map = new HashMap<>();
+ map.put("select", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_ALLOWED, null));
+ map.put("update", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_UNDETERMINED, null));
+ map.put("drop", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_CONDITIONAL, null));
+
+ RangerPolicy policy = new RangerPolicy();
+
+ assertEquals(RangerPolicyEvaluator.ACCESS_ALLOWED, mCheck.invoke(authorizer, Privilege.SELECT, map));
+ String p1 = (String) mPerm.invoke(authorizer, Privilege.SELECT, map, policy);
+ assertEquals("SELECT", p1);
+
+ assertEquals(RangerPolicyEvaluator.ACCESS_UNDETERMINED, mCheck.invoke(authorizer, Privilege.UPDATE, map));
+ String p2 = (String) mPerm.invoke(authorizer, Privilege.UPDATE, map, policy);
+ assertTrue(p2.contains("ACCESS_UNDETERMINED"));
+
+ assertEquals(RangerPolicyEvaluator.ACCESS_CONDITIONAL, mCheck.invoke(authorizer, Privilege.DROP, map));
+ String p3 = (String) mPerm.invoke(authorizer, Privilege.DROP, map, policy);
+ assertTrue(p3.contains("ACCESS_CONDITIONAL"));
+ }
+
+ @Test
+ public void test63_getRangerPolicy_returnsPolicyWhenPresent() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getRangerPolicy", Map.class, String.class);
+ m.setAccessible(true);
+
+ Map<String, RangerResourceACLs.AccessResult> access = new HashMap<>();
+ RangerPolicy policy = new RangerPolicy();
+ policy.setName("p1");
+ access.put("select", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_ALLOWED, policy));
+
+ Object out = m.invoke(authorizer, access, "SELECT");
+ assertInstanceOf(RangerPolicy.class, out);
+ assertEquals("p1", ((RangerPolicy) out).getName());
+ }
+
+ @Test
+ public void test64_createHivePrivilegeInfo_buildsFieldsFromPolicy() throws Exception {
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod(
+ "createHivePrivilegeInfo",
+ HivePrincipal.class,
+ HivePrivilegeObject.HivePrivilegeObjectType.class,
+ String.class,
+ String.class,
+ String.class,
+ List.class,
+ String.class,
+ RangerPolicy.class);
+ m.setAccessible(true);
+
+ RangerPolicy policy = new RangerPolicy();
+ policy.setCreateTime(new Date(4000));
+ RangerPolicy.RangerPolicyItem item = new RangerPolicy.RangerPolicyItem();
+ RangerPolicyItemAccess access = new RangerPolicyItemAccess();
+ access.setType("select");
+ item.setAccesses(Collections.singletonList(access));
+ item.setUsers(Collections.singletonList("alice"));
+ item.setDelegateAdmin(true);
+ policy.setPolicyItems(Collections.singletonList(item));
+
+ HivePrincipal principal = new HivePrincipal("alice", HivePrincipal.HivePrincipalType.USER);
+ Object out = m.invoke(authorizer, principal, HivePrivilegeObject.HivePrivilegeObjectType.TABLE_OR_VIEW, "db1", "t1", "", Collections.emptyList(), "SELECT", policy);
+ assertInstanceOf(HivePrivilegeInfo.class, out);
+ HivePrivilegeInfo info = (HivePrivilegeInfo) out;
+ assertEquals("alice", info.getPrincipal().getName());
+ assertEquals("ranger", info.getGrantorPrincipal().getName());
+ assertTrue(info.isGrantOption());
+ assertTrue(info.getGrantTime() > 0);
+ }
+
+ @Test
+ public void test65_getRangerResourceACLs_delegatesToPlugin() throws Exception {
+ RangerBasePlugin plugin = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ RangerResourceACLs acls = new RangerResourceACLs();
+ Mockito.doReturn(acls).when(plugin).getResourceACLs(Mockito.any(RangerAccessRequestImpl.class));
+ setStaticHivePlugin(plugin);
+
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(ms);
+
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, null);
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getRangerResourceACLs", HivePrivilegeObject.class);
+ m.setAccessible(true);
+ HivePrivilegeObject obj = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "db1", "t1");
+ Object out = m.invoke(authorizer, obj);
+ assertInstanceOf(RangerResourceACLs.class, out);
+ }
+
+ @Test
+ public void test67_getHivePrivilegeInfos_userPrincipal() throws Exception {
+ RangerBasePlugin plugin = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ RangerResourceACLs acls = new RangerResourceACLs();
+ RangerPolicy pUser = new RangerPolicy();
+ pUser.setPolicyItems(Collections.emptyList());
+ RangerPolicy pGrp = new RangerPolicy();
+ pGrp.setPolicyItems(Collections.emptyList());
+ acls.setUserAccessInfo("alice", "select", RangerPolicyEvaluator.ACCESS_ALLOWED, pUser);
+ acls.setGroupAccessInfo("dev", "update", RangerPolicyEvaluator.ACCESS_ALLOWED, pGrp);
+ Mockito.doReturn(acls).when(plugin).getResourceACLs(Mockito.any(RangerAccessRequestImpl.class));
+ setStaticHivePlugin(plugin);
+
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(ms);
+ RangerHiveAuthorizer authorizer = Mockito.spy(new RangerHiveAuthorizer(msFactory, null, null, null));
+
+ // Prepare AuthorizationUtils response
+ HiveObjectRef ref = Mockito.mock(HiveObjectRef.class);
+ Mockito.when(ref.getDbName()).thenReturn("db1");
+ Mockito.when(ref.getObjectName()).thenReturn("t1");
+ Mockito.when(ref.getColumnName()).thenReturn(null);
+ Mockito.when(ref.getPartValues()).thenReturn(null);
+ Mockito.when(ref.getObjectType()).thenReturn(HiveObjectType.TABLE);
+
+ try (MockedStatic<AuthorizationUtils> stat = Mockito.mockStatic(AuthorizationUtils.class)) {
+ stat.when(() -> AuthorizationUtils.getThriftHiveObjectRef(Mockito.any(HivePrivilegeObject.class))).thenReturn(ref);
+
+ // Seed UGI with dev group
+ UserGroupInformation.setLoginUser(UserGroupInformation.createUserForTesting("alice", new String[] {"dev"}));
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getHivePrivilegeInfos", HivePrincipal.class, HivePrivilegeObject.class);
+ m.setAccessible(true);
+
+ HivePrivilegeObject resource = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "db1", "t1");
+ HivePrincipal principal = new HivePrincipal("alice", HivePrincipal.HivePrincipalType.USER);
+
+ @SuppressWarnings("unchecked")
+ List<HivePrivilegeInfo> infos = (List<HivePrivilegeInfo>) m.invoke(authorizer, principal, resource);
+
+ assertFalse(infos.isEmpty());
+ assertTrue(infos.stream().anyMatch(i -> i.getPrivilege().getName().toLowerCase().startsWith("select")));
+ assertTrue(infos.stream().anyMatch(i -> i.getPrivilege().getName().toLowerCase().startsWith("update")));
+ }
+ }
+
+ @Test
+ public void test68_getHivePrivilegeInfos_rolePrincipal() throws Exception {
+ RangerBasePlugin plugin = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ RangerResourceACLs acls = new RangerResourceACLs();
+ RangerPolicy pRole = new RangerPolicy();
+ pRole.setPolicyItems(Collections.emptyList());
+ acls.setRoleAccessInfo("analyst", "drop", RangerPolicyEvaluator.ACCESS_ALLOWED, pRole);
+ Mockito.doReturn(acls).when(plugin).getResourceACLs(Mockito.any(RangerAccessRequestImpl.class));
+ setStaticHivePlugin(plugin);
+
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(ms);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, null);
+
+ HiveObjectRef ref = Mockito.mock(HiveObjectRef.class);
+ Mockito.when(ref.getDbName()).thenReturn("db1");
+ Mockito.when(ref.getObjectName()).thenReturn("t1");
+ Mockito.when(ref.getColumnName()).thenReturn(null);
+ Mockito.when(ref.getPartValues()).thenReturn(null);
+ Mockito.when(ref.getObjectType()).thenReturn(HiveObjectType.TABLE);
+
+ try (MockedStatic<AuthorizationUtils> stat = Mockito.mockStatic(AuthorizationUtils.class)) {
+ stat.when(() -> AuthorizationUtils.getThriftHiveObjectRef(Mockito.any(HivePrivilegeObject.class))).thenReturn(ref);
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getHivePrivilegeInfos", HivePrincipal.class, HivePrivilegeObject.class);
+ m.setAccessible(true);
+
+ HivePrivilegeObject resource = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "db1", "t1");
+ HivePrincipal principal = new HivePrincipal("analyst", HivePrincipal.HivePrincipalType.ROLE);
+
+ @SuppressWarnings("unchecked")
+ List<HivePrivilegeInfo> infos = (List<HivePrivilegeInfo>) m.invoke(authorizer, principal, resource);
+
+ assertFalse(infos.isEmpty());
+ assertTrue(infos.stream().anyMatch(i -> i.getPrivilege().getName().toLowerCase().startsWith("drop")));
+ }
+ }
+
+ @Test
+ public void test69_getHivePrivilegeInfos_allPrincipals() throws Exception {
+ RangerBasePlugin plugin = (RangerBasePlugin) Mockito.spy(newInstanceRangerHivePlugin("hiveCLI"));
+ RangerResourceACLs acls = new RangerResourceACLs();
+ RangerPolicy pUser = new RangerPolicy();
+ pUser.setPolicyItems(Collections.emptyList());
+ RangerPolicy pGrp = new RangerPolicy();
+ pGrp.setPolicyItems(Collections.emptyList());
+ RangerPolicy pRole = new RangerPolicy();
+ pRole.setPolicyItems(Collections.emptyList());
+ acls.setUserAccessInfo("u1", "select", RangerPolicyEvaluator.ACCESS_ALLOWED, pUser);
+ acls.setGroupAccessInfo("g1", "update", RangerPolicyEvaluator.ACCESS_ALLOWED, pGrp);
+ acls.setRoleAccessInfo("r1", "drop", RangerPolicyEvaluator.ACCESS_ALLOWED, pRole);
+ Mockito.doReturn(acls).when(plugin).getResourceACLs(Mockito.any(RangerAccessRequestImpl.class));
+ setStaticHivePlugin(plugin);
+
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ IMetaStoreClient ms = Mockito.mock(IMetaStoreClient.class);
+ Mockito.when(msFactory.getHiveMetastoreClient()).thenReturn(ms);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(msFactory, null, null, null);
+
+ HiveObjectRef ref = Mockito.mock(HiveObjectRef.class);
+ Mockito.when(ref.getDbName()).thenReturn("db1");
+ Mockito.when(ref.getObjectName()).thenReturn("t1");
+ Mockito.when(ref.getColumnName()).thenReturn(null);
+ Mockito.when(ref.getPartValues()).thenReturn(null);
+ Mockito.when(ref.getObjectType()).thenReturn(HiveObjectType.TABLE);
+
+ try (MockedStatic<AuthorizationUtils> stat = Mockito.mockStatic(AuthorizationUtils.class)) {
+ stat.when(() -> AuthorizationUtils.getThriftHiveObjectRef(Mockito.any(HivePrivilegeObject.class))).thenReturn(ref);
+
+ Method m = RangerHiveAuthorizer.class.getDeclaredMethod("getHivePrivilegeInfos", HivePrincipal.class, HivePrivilegeObject.class);
+ m.setAccessible(true);
+
+ HivePrivilegeObject resource = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "db1", "t1");
+
+ @SuppressWarnings("unchecked")
+ List<HivePrivilegeInfo> infos = (List<HivePrivilegeInfo>) m.invoke(authorizer, null, resource);
+
+ assertFalse(infos.isEmpty());
+ // Ensure entries for user, group and role got included
+ assertTrue(infos.stream().anyMatch(i -> i.getPrincipal().getType() == HivePrincipal.HivePrincipalType.USER));
+ assertTrue(infos.stream().anyMatch(i -> i.getPrincipal().getType() == HivePrincipal.HivePrincipalType.GROUP));
+ assertTrue(infos.stream().anyMatch(i -> i.getPrincipal().getType() == HivePrincipal.HivePrincipalType.ROLE));
+ }
+ }
+
+ private static RangerAccessResult allowedResult() {
+ RangerAccessResult res = new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS, "svc", null, new RangerAccessRequestImpl());
+ res.setIsAudited(true);
+ res.setIsAllowed(true);
+ return res;
+ }
+
+ private static RangerBasePlugin getStaticHivePlugin() throws Exception {
+ Field f = RangerHiveAuthorizer.class.getDeclaredField("hivePlugin");
+ f.setAccessible(true);
+ Object val = f.get(null);
+ return (RangerBasePlugin) val;
+ }
+
+ private static void setStaticHivePlugin(RangerBasePlugin plugin) throws Exception {
+ Field f = RangerHiveAuthorizer.class.getDeclaredField("hivePlugin");
+ f.setAccessible(true);
+ f.set(null, plugin);
+ }
+
+ private static void setRangerHivePluginUpdateFlag(boolean value) throws Exception {
+ Field f = Class.forName("org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer$RangerHivePlugin").getDeclaredField("updateXaPoliciesOnGrantRevoke");
+ f.setAccessible(true);
+ f.set(null, value);
+ }
+
+ private static Object newInstanceRangerHivePlugin(String appType) throws Exception {
+ Class<?> c = Class.forName("org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer$RangerHivePlugin");
+ java.lang.reflect.Constructor<?> ctor = c.getDeclaredConstructor(String.class);
+ ctor.setAccessible(true);
+ return ctor.newInstance(appType);
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizerBase.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizerBase.java
new file mode 100644
index 000000000..80ea2a36c
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizerBase.java
@@ -0,0 +1,166 @@
+/*
+ * 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.authorization.hive.authorizer;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzSessionContext;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveMetastoreClientFactory;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
+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.junit.jupiter.api.function.Executable;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerHiveAuthorizerBase
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveAuthorizerBase {
+ @Test
+ public void test01_constructorSetsUgiWhenUserPresent() {
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ HiveAuthenticationProvider authenticator = Mockito.mock(HiveAuthenticationProvider.class);
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+
+ Mockito.when(authenticator.getUserName()).thenReturn("alice");
+
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(msFactory, null, authenticator, sessionContext).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+ UserGroupInformation ugi = auth.getCurrentUserGroupInfo();
+ Assertions.assertNotNull(ugi);
+ Assertions.assertEquals("alice", ugi.getShortUserName());
+ Assertions.assertNull(auth.getHiveConf());
+ Assertions.assertEquals(authenticator, auth.getHiveAuthenticator());
+ Assertions.assertEquals(sessionContext, auth.getHiveAuthzSessionContext());
+ Assertions.assertEquals(msFactory, auth.getMetastoreClientFactory());
+ }
+
+ @Test
+ public void test02_constructorLeavesUgiNullWhenUserMissing() {
+ HiveMetastoreClientFactory msFactory = Mockito.mock(HiveMetastoreClientFactory.class);
+ HiveAuthenticationProvider authenticator = Mockito.mock(HiveAuthenticationProvider.class);
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+
+ Mockito.when(authenticator.getUserName()).thenReturn(null);
+
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(msFactory, null, authenticator, sessionContext).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+ Assertions.assertNull(auth.getCurrentUserGroupInfo());
+ }
+
+ @Test
+ public void test03_getVersionIsV1() {
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(null, null, null, null).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+ Assertions.assertEquals(RangerHiveAuthorizerBase.VERSION.V1, auth.getVersion());
+ }
+
+ @Test
+ public void test05_getHivePolicyProviderReturnsNull() throws Exception {
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(null, null, null, null).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+ Assertions.assertNull(auth.getHivePolicyProvider());
+ }
+
+ @Test
+ public void test06_applyAuthorizationConfigPolicy_addsDisallowHookForHS2WithEmptyHooks() throws Exception {
+ assumeHiveAvailable();
+ HiveConf conf = new HiveConf();
+ conf.setVar(HiveConf.getConfVars("hive.exec.pre.hooks"), "");
+
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ Mockito.when(sessionContext.getClientType()).thenReturn(HiveAuthzSessionContext.CLIENT_TYPE.HIVESERVER2);
+
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(null, conf, null, sessionContext).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+ auth.applyAuthorizationConfigPolicy(conf);
+
+ String hooks = conf.getVar(HiveConf.getConfVars("hive.exec.pre.hooks"));
+ Assertions.assertTrue(hooks.contains("DisallowTransformHook"));
+ }
+
+ @Test
+ public void test07_applyAuthorizationConfigPolicy_appendsDisallowHookForHS2WithExistingHooks() throws Exception {
+ assumeHiveAvailable();
+ HiveConf conf = new HiveConf();
+ conf.setVar(HiveConf.getConfVars("hive.exec.pre.hooks"), "org.example.MyHook");
+
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ Mockito.when(sessionContext.getClientType()).thenReturn(HiveAuthzSessionContext.CLIENT_TYPE.HIVESERVER2);
+
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(null, conf, null, sessionContext).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+ auth.applyAuthorizationConfigPolicy(conf);
+
+ String hooks = conf.getVar(HiveConf.getConfVars("hive.exec.pre.hooks"));
+ Assertions.assertTrue(hooks.startsWith("org.example.MyHook"));
+ Assertions.assertTrue(hooks.contains("DisallowTransformHook"));
+ }
+
+ @Test
+ public void test08_applyAuthorizationConfigPolicy_noChangeWhenNotHS2() throws Exception {
+ assumeHiveAvailable();
+ HiveConf conf = new HiveConf();
+ conf.setVar(HiveConf.getConfVars("hive.exec.pre.hooks"), "pre.Existing");
+
+ HiveAuthzSessionContext sessionContext = Mockito.mock(HiveAuthzSessionContext.class);
+ Mockito.when(sessionContext.getClientType()).thenReturn(HiveAuthzSessionContext.CLIENT_TYPE.HIVECLI);
+
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(null, conf, null, sessionContext).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+ auth.applyAuthorizationConfigPolicy(conf);
+
+ String hooks = conf.getVar(HiveConf.getConfVars("hive.exec.pre.hooks"));
+ Assertions.assertEquals("pre.Existing", hooks);
+ }
+
+ @Test
+ public void test04_showPrivilegesThrowsNotImplemented() {
+ RangerHiveAuthorizerBase auth = Mockito.mock(RangerHiveAuthorizerBase.class, Mockito.withSettings().useConstructor(null, null, null, null).defaultAnswer(Mockito.CALLS_REAL_METHODS));
+ HivePrincipal principal = Mockito.mock(HivePrincipal.class);
+ HivePrivilegeObject obj = Mockito.mock(HivePrivilegeObject.class);
+
+ Executable call = () -> auth.showPrivileges(principal, obj);
+ HiveAuthzPluginException ex = Assertions.assertThrows(HiveAuthzPluginException.class, call);
+ Assertions.assertTrue(ex.getMessage().contains("showPrivileges() not implemented"));
+ }
+
+ private static boolean canLoad(String cn) {
+ try {
+ Class.forName(cn);
+ return true;
+ } catch (Throwable t) {
+ return false;
+ }
+ }
+
+ private static void assumeHiveAvailable() {
+ Assumptions.assumeTrue(canLoad("org.apache.hadoop.hive.conf.HiveConf"), "HiveConf not available in unit test runtime");
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizerFactory.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizerFactory.java
new file mode 100644
index 000000000..3834d0119
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveAuthorizerFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.authorization.hive.authorizer;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException;
+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 : Unit Test cases for RangerHiveAuthorizerFactory
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveAuthorizerFactory {
+ @Test
+ public void test01_createHiveAuthorizer_throwsOrCreates() {
+ HiveAuthorizerFactory factory = new RangerHiveAuthorizerFactory();
+
+ try {
+ Assertions.assertNotNull(factory.createHiveAuthorizer(null, new HiveConf(), null, null));
+ } catch (HiveAuthzPluginException | Error e) {
+ Assertions.assertNotNull(e);
+ }
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHivePolicyProvider.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHivePolicyProvider.java
new file mode 100644
index 000000000..5c8e0b96d
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHivePolicyProvider.java
@@ -0,0 +1,128 @@
+/*
+ * 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.authorization.hive.authorizer;
+
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePolicyChangeListener;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs.AccessResult;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs.Privilege;
+import org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer.HiveObjectType;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+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.ArgumentCaptor;
+import org.mockito.Mock;
+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.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+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 : Unit Test cases for RangerHivePolicyProvider
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHivePolicyProvider {
+ @Mock
+ private RangerBasePlugin mockPlugin;
+
+ @Mock
+ private RangerHiveAuthorizer mockAuthorizer;
+
+ @Test
+ public void test01_registerListenerWiresThroughBasePlugin() {
+ RangerHivePolicyProvider provider = new RangerHivePolicyProvider(mockPlugin, mockAuthorizer);
+ HivePolicyChangeListener listener = mock(HivePolicyChangeListener.class);
+
+ provider.registerHivePolicyChangeListener(listener);
+
+ verify(mockPlugin, times(1)).registerAuthContextEventListener(any(RangerHivePolicyProvider.RangerHiveAuthContextListener.class));
+ }
+
+ @Test
+ public void test02_getResourceACLsDelegatesToPluginAndConvertsResults() {
+ RangerHivePolicyProvider provider = new RangerHivePolicyProvider(mockPlugin, mockAuthorizer);
+
+ // Build Ranger ACLs
+ RangerResourceACLs rangerAcls = new RangerResourceACLs();
+ Map<String, RangerResourceACLs.AccessResult> userPerms = new HashMap<>();
+ userPerms.put("select", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_ALLOWED, null));
+ userPerms.put("update", new RangerResourceACLs.AccessResult(RangerPolicyEvaluator.ACCESS_DENIED, null));
+ rangerAcls.getUserACLs().put("alice", userPerms);
+
+ when(mockPlugin.getResourceACLs(any(RangerAccessRequestImpl.class))).thenReturn(rangerAcls);
+
+ RangerHiveResource hiveRes = new RangerHiveResource(HiveObjectType.TABLE, "db", "t");
+ HiveResourceACLs hiveAcls = provider.getResourceACLs(hiveRes);
+
+ assertNotNull(hiveAcls);
+ Map<Privilege, AccessResult> alice = hiveAcls.getUserPermissions().get("alice");
+ assertEquals(AccessResult.ALLOWED, alice.get(Privilege.SELECT));
+ assertEquals(AccessResult.NOT_ALLOWED, alice.get(Privilege.UPDATE));
+
+ ArgumentCaptor<RangerAccessRequestImpl> captor = ArgumentCaptor.forClass(RangerAccessRequestImpl.class);
+ verify(mockPlugin).getResourceACLs(captor.capture());
+ assertEquals(RangerPolicyEngine.ANY_ACCESS, captor.getValue().getAccessType());
+ }
+
+ @Test
+ public void test03_getResourceACLsFromHivePrivilegeObjectUsesAuthorizerToCreateResource() {
+ RangerHivePolicyProvider provider = new RangerHivePolicyProvider(mockPlugin, mockAuthorizer);
+ HivePrivilegeObject hiveObj = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, "db1", "t1");
+ RangerHiveResource built = new RangerHiveResource(HiveObjectType.TABLE, "db1", "t1");
+ when(mockAuthorizer.createHiveResource(eq(hiveObj))).thenReturn(built);
+ when(mockPlugin.getResourceACLs(any(RangerAccessRequestImpl.class))).thenReturn(new RangerResourceACLs());
+
+ HiveResourceACLs hiveAcls = provider.getResourceACLs(hiveObj);
+ assertNotNull(hiveAcls);
+ verify(mockAuthorizer, times(1)).createHiveResource(eq(hiveObj));
+ }
+
+ @Test
+ public void test01_contextChanged_notifiesRegisteredListeners() {
+ RangerBasePlugin plugin = mock(RangerBasePlugin.class);
+ RangerHiveAuthorizer authorizer = new RangerHiveAuthorizer(null, null, null, null);
+ RangerHivePolicyProvider provider = new RangerHivePolicyProvider(plugin, authorizer);
+ HivePolicyChangeListener listener = mock(HivePolicyChangeListener.class);
+ provider.registerHivePolicyChangeListener(listener);
+ // trigger context change
+ RangerHivePolicyProvider.RangerHiveAuthContextListener l = new RangerHivePolicyProvider.RangerHiveAuthContextListener();
+ l.providerChangeListeners.add(listener);
+ l.contextChanged();
+ verify(listener, times(1)).notifyPolicyChange(null);
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveResource.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveResource.java
new file mode 100644
index 000000000..84f389b34
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveResource.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.authorization.hive.authorizer;
+
+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 : Unit Test cases for RangerHiveResource
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveResource {
+ @Test
+ public void test01_databaseResourceSetsKeysAndType() {
+ RangerHiveAuthorizer.HiveObjectType type = RangerHiveAuthorizer.HiveObjectType.DATABASE;
+ RangerHiveResource resource = new RangerHiveResource(type, "db1");
+
+ Assertions.assertEquals(type, resource.getObjectType());
+ Assertions.assertEquals("db1", resource.getDatabase());
+ Assertions.assertNull(resource.getTable());
+ Assertions.assertNull(resource.getColumn());
+ }
+
+ @Test
+ public void test02_tableResourceSetsKeys() {
+ RangerHiveAuthorizer.HiveObjectType type = RangerHiveAuthorizer.HiveObjectType.TABLE;
+ RangerHiveResource resource = new RangerHiveResource(type, "db1", "tbl1");
+
+ Assertions.assertEquals("db1", resource.getDatabase());
+ Assertions.assertEquals("tbl1", resource.getTable());
+ Assertions.assertNull(resource.getColumn());
+ }
+
+ @Test
+ public void test03_columnResourceSetsKeys() {
+ RangerHiveAuthorizer.HiveObjectType type = RangerHiveAuthorizer.HiveObjectType.COLUMN;
+ RangerHiveResource resource = new RangerHiveResource(type, "db1", "tbl1", "col1");
+
+ Assertions.assertEquals("db1", resource.getDatabase());
+ Assertions.assertEquals("tbl1", resource.getTable());
+ Assertions.assertEquals("col1", resource.getColumn());
+ }
+
+ @Test
+ public void test04_uriResourceContainsUrlKey() {
+ RangerHiveAuthorizer.HiveObjectType type = RangerHiveAuthorizer.HiveObjectType.URI;
+ RangerHiveResource resource = new RangerHiveResource(type, "/tmp/path");
+
+ Assertions.assertTrue(resource.exists(RangerHiveResource.KEY_URL));
+ Assertions.assertNotNull(resource.getAsMap().get(RangerHiveResource.KEY_URL));
+ }
+
+ @Test
+ public void test05_functionResourceSetsDbEmptyAndUdf() {
+ RangerHiveResource resource = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.FUNCTION, null, "myUdf");
+
+ Assertions.assertEquals("", resource.getDatabase());
+ Assertions.assertEquals("myUdf", resource.getUdf());
+ }
+
+ @Test
+ public void test06_serviceNameResourceSetsHiveServiceEmpty() {
+ RangerHiveResource resource = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.SERVICE_NAME, null);
+
+ Assertions.assertEquals("", resource.getHiveService());
+ }
+
+ @Test
+ public void test07_globalResourceSetsDefaultGlobalKey() {
+ RangerHiveResource resource = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.GLOBAL, null);
+
+ Assertions.assertTrue(resource.exists(RangerHiveResource.KEY_GLOBAL));
+ Assertions.assertEquals(RangerHiveResource.KEY_GLOBAL, resource.getAsMap().get(RangerHiveResource.KEY_GLOBAL));
+ }
+
+ @Test
+ public void test08_getUrlReturnsNullWhenNotSet() {
+ RangerHiveResource resource = new RangerHiveResource(RangerHiveAuthorizer.HiveObjectType.DATABASE, "dbx");
+
+ Assertions.assertNull(resource.getUrl());
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveResourceACLs.java b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveResourceACLs.java
new file mode 100644
index 000000000..97218cfb6
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/authorization/hive/authorizer/TestRangerHiveResourceACLs.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.authorization.hive.authorizer;
+
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs;
+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;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerHiveResourceACLs
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHiveResourceACLs {
+ @Test
+ public void test01_defaultConstructorReturnsEmptyMaps() {
+ RangerHiveResourceACLs acls = new RangerHiveResourceACLs();
+
+ Assertions.assertTrue(acls.getUserPermissions().isEmpty());
+ Assertions.assertTrue(acls.getGroupPermissions().isEmpty());
+ }
+
+ @Test
+ public void test02_paramConstructorStoresMaps() {
+ Map<String, Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult>> user = new HashMap<>();
+ user.put("u1", new EnumMap<>(HiveResourceACLs.Privilege.class));
+ Map<String, Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult>> group = new HashMap<>();
+ group.put("g1", new EnumMap<>(HiveResourceACLs.Privilege.class));
+
+ RangerHiveResourceACLs acls = new RangerHiveResourceACLs(user, group);
+
+ Assertions.assertEquals(user.keySet(), acls.getUserPermissions().keySet());
+ Assertions.assertEquals(group.keySet(), acls.getGroupPermissions().keySet());
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/services/hive/TestRangerServiceHive.java b/hive-agent/src/test/java/org/apache/ranger/services/hive/TestRangerServiceHive.java
new file mode 100644
index 000000000..be63e38b3
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/services/hive/TestRangerServiceHive.java
@@ -0,0 +1,230 @@
+/*
+ * 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.services.hive;
+
+import org.apache.ranger.plugin.client.HadoopException;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.ranger.services.hive.client.HiveResourceMgr;
+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.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+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.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerServiceHive
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerServiceHive {
+ @Test
+ public void test00_init_setsBaseFields() throws Exception {
+ RangerServiceHive svc = new RangerServiceHive();
+ RangerServiceDef def = new RangerServiceDef();
+ RangerService service = new RangerService();
+ service.setName("svc");
+ svc.init(def, service);
+ Field fService = RangerServiceHive.class.getSuperclass().getDeclaredField("service");
+ fService.setAccessible(true);
+ Field fSvcDef = RangerServiceHive.class.getSuperclass().getDeclaredField("serviceDef");
+ fSvcDef.setAccessible(true);
+ assertEquals(service, fService.get(svc));
+ assertEquals(def, fSvcDef.get(svc));
+ }
+
+ @Test
+ public void test01_validateConfig_delegatesAndReturns() throws Exception {
+ Map<String, String> cfg = new HashMap<>();
+ cfg.put("k", "v");
+ RangerServiceHive svc = newService("svc", "hive", cfg);
+ try (MockedStatic<HiveResourceMgr> stat = Mockito.mockStatic(HiveResourceMgr.class)) {
+ Map<String, Object> resp = new HashMap<>();
+ resp.put("ok", true);
+ stat.when(() -> HiveResourceMgr.connectionTest(Mockito.eq("svc"), Mockito.eq(cfg))).thenReturn(resp);
+ Map<String, Object> out = svc.validateConfig();
+ assertEquals(resp, out);
+ }
+ }
+
+ @Test
+ public void test02_validateConfig_throwsHadoopException() throws Exception {
+ Map<String, String> cfg = new HashMap<>();
+ RangerServiceHive svc = newService("svc", "hive", cfg);
+ try (MockedStatic<HiveResourceMgr> stat = Mockito.mockStatic(HiveResourceMgr.class)) {
+ stat.when(() -> HiveResourceMgr.connectionTest(Mockito.eq("svc"), Mockito.eq(cfg))).thenThrow(new HadoopException("x"));
+ assertThrows(HadoopException.class, svc::validateConfig);
+ }
+ }
+
+ @Test
+ public void test03_lookupResource_delegates() throws Exception {
+ Map<String, String> cfg = new HashMap<>();
+ RangerServiceHive svc = newService("svc", "hive", cfg);
+ ResourceLookupContext ctx = new ResourceLookupContext();
+ try (MockedStatic<HiveResourceMgr> stat = Mockito.mockStatic(HiveResourceMgr.class)) {
+ List<String> resp = Collections.singletonList("db1");
+ stat.when(() -> HiveResourceMgr.getHiveResources("svc", "hive", cfg, ctx)).thenReturn(resp);
+ List<String> out = svc.lookupResource(ctx);
+ assertEquals(resp, out);
+ }
+ }
+
+ @Test
+ public void test04_lookupResource_nullContextReturnsEmpty() throws Exception {
+ RangerServiceHive svc = newService("svc", "hive", new HashMap<>());
+ List<String> out = svc.lookupResource(null);
+ assertNotNull(out);
+ assertTrue(out.isEmpty());
+ }
+
+ @Test
+ public void test05_createDefaultDBPolicy_reflection() throws Exception {
+ RangerServiceHive svc = newService("svc", "hive", new HashMap<>());
+ Method m = RangerServiceHive.class.getDeclaredMethod("createDefaultDBPolicy");
+ m.setAccessible(true);
+ RangerPolicy p = (RangerPolicy) m.invoke(svc);
+ assertNotNull(p);
+ assertEquals("default database tables columns", p.getName());
+ assertEquals("svc", p.getService());
+ Map<String, RangerPolicy.RangerPolicyResource> res = p.getResources();
+ assertEquals(Collections.singletonList("default"), res.get("database").getValues());
+ assertEquals(Collections.singletonList("*"), res.get("table").getValues());
+ assertEquals(Collections.singletonList("*"), res.get("column").getValues());
+ }
+
+ @Test
+ public void test06_createInformationSchemaPolicy_reflection() throws Exception {
+ RangerServiceHive svc = newService("svc", "hive", new HashMap<>());
+ Method m = RangerServiceHive.class.getDeclaredMethod("createInformationSchemaPolicy");
+ m.setAccessible(true);
+ RangerPolicy p = (RangerPolicy) m.invoke(svc);
+ assertNotNull(p);
+ assertEquals("Information_schema database tables columns", p.getName());
+ assertEquals("svc", p.getService());
+ Map<String, RangerPolicy.RangerPolicyResource> res = p.getResources();
+ assertEquals(Collections.singletonList("information_schema"), res.get("database").getValues());
+ assertEquals(Collections.singletonList("*"), res.get("table").getValues());
+ assertEquals(Collections.singletonList("*"), res.get("column").getValues());
+ }
+
+ @Test
+ public void test07_hasWildcardAsteriskResource_trueFalse() throws Exception {
+ RangerServiceHive svc = newService("svc", "hive", new HashMap<>());
+ Method m = RangerServiceHive.class.getDeclaredMethod("hasWildcardAsteriskResource", Map.class, String[].class);
+ m.setAccessible(true);
+ Map<String, RangerPolicy.RangerPolicyResource> res = new HashMap<>();
+ res.put("database", new RangerPolicy.RangerPolicyResource(Collections.singletonList("*"), false, false));
+ assertTrue((Boolean) m.invoke(svc, res, new String[] {"database"}));
+ }
+
+ @Test
+ public void test08_getDefaultRangerPolicies_appendsDefaultAndInfo() throws Exception {
+ RangerServiceHive svc = newService("svc", "hive", new HashMap<>());
+ // minimally initialize service and serviceDef so super call doesn't NPE
+ RangerService service = new RangerService();
+ service.setName("svc");
+ Field fService = RangerServiceHive.class.getSuperclass().getDeclaredField("service");
+ fService.setAccessible(true);
+ fService.set(svc, service);
+ Field fSvcDef = RangerServiceHive.class.getSuperclass().getDeclaredField("serviceDef");
+ fSvcDef.setAccessible(true);
+ fSvcDef.set(svc, new RangerServiceDef());
+
+ List<RangerPolicy> out = svc.getDefaultRangerPolicies();
+ assertNotNull(out);
+ boolean hasDefault = out.stream().anyMatch(p -> "default database tables columns".equals(p.getName()));
+ boolean hasInfo = out.stream().anyMatch(p -> "Information_schema database tables columns".equals(p.getName()));
+ assertTrue(hasDefault);
+ assertTrue(hasInfo);
+ }
+
+ @Test
+ public void test09_getDefaultRangerPolicies_addsLookupUserAndOwnerItems() throws Exception {
+ // Prepare configs to drive additional default policies from base service
+ Map<String, String> cfg = new HashMap<>();
+ cfg.put("setup.additional.default.policies", "true");
+ // policy 1: all databases (database=*) => should add public(create) and owner(all)
+ cfg.put("default-policy.1.name", "all - database");
+ cfg.put("default-policy.1.resource.database", "*");
+ // policy 2: all tables (database=*, table=*) => should add owner(all)
+ cfg.put("default-policy.2.name", "all - database, table");
+ cfg.put("default-policy.2.resource.database", "*");
+ cfg.put("default-policy.2.resource.table", "*");
+ RangerServiceHive svc = newService("svc", "hive", cfg);
+ // set lookUpUser so lookup-user entry is created for policies with name containing "all"
+ Field fLook = RangerServiceHive.class.getSuperclass().getDeclaredField("lookUpUser");
+ fLook.setAccessible(true);
+ fLook.set(svc, "lookupUser");
+ // also initialize service and serviceDef like in test08 to avoid NPEs inside super.getDefaultRangerPolicies
+ RangerService service = new RangerService();
+ service.setName("svc");
+ Field fService = RangerServiceHive.class.getSuperclass().getDeclaredField("service");
+ fService.setAccessible(true);
+ fService.set(svc, service);
+ Field fSvcDef = RangerServiceHive.class.getSuperclass().getDeclaredField("serviceDef");
+ fSvcDef.setAccessible(true);
+ fSvcDef.set(svc, new RangerServiceDef());
+ List<RangerPolicy> out = svc.getDefaultRangerPolicies();
+ assertNotNull(out);
+ // find our additional default policies
+ RangerPolicy allDb = out.stream().filter(p -> "all - database".equals(p.getName())).findFirst().orElse(null);
+ RangerPolicy allTbl = out.stream().filter(p -> "all - database, table".equals(p.getName())).findFirst().orElse(null);
+ assertNotNull(allDb);
+ assertNotNull(allTbl);
+ // verify lookup-user, public(create), and owner(all) on database=* policy
+ assertTrue(allDb.getPolicyItems().stream().anyMatch(i -> i.getUsers() != null && i.getUsers().contains("lookupUser")));
+ assertTrue(allDb.getPolicyItems().stream().anyMatch(i -> i.getGroups() != null && i.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC)));
+ assertTrue(allDb.getPolicyItems().stream().anyMatch(i -> i.getUsers() != null && i.getUsers().contains(RangerPolicyEngine.RESOURCE_OWNER)));
+ // verify owner(all) on database=* and table=* policy
+ assertTrue(allTbl.getPolicyItems().stream().anyMatch(i -> i.getUsers() != null && i.getUsers().contains(RangerPolicyEngine.RESOURCE_OWNER)));
+ }
+
+ private static RangerServiceHive newService(String name, String type, Map<String, String> configs) throws Exception {
+ RangerServiceHive svc = new RangerServiceHive();
+ Field fName = RangerServiceHive.class.getSuperclass().getDeclaredField("serviceName");
+ fName.setAccessible(true);
+ fName.set(svc, name);
+ Field fType = RangerServiceHive.class.getSuperclass().getDeclaredField("serviceType");
+ fType.setAccessible(true);
+ fType.set(svc, type);
+ Field fCfg = RangerServiceHive.class.getSuperclass().getDeclaredField("configs");
+ fCfg.setAccessible(true);
+ fCfg.set(svc, configs);
+ return svc;
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveClient.java b/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveClient.java
new file mode 100644
index 000000000..d850a9541
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveClient.java
@@ -0,0 +1,584 @@
+/*
+ * 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.services.hive.client;
+
+import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.ranger.plugin.client.HadoopConfigHolder;
+import org.apache.ranger.plugin.client.HadoopException;
+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.MockedConstruction;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import javax.security.auth.Subject;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverPropertyInfo;
+import java.sql.ResultSet;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLTimeoutException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+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.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for HiveClient
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestHiveClient {
+ @Test
+ public void test01_connectionTestEmptyDbListSetsFailureMessage() throws Exception {
+ try (MockedConstruction<HiveClient> cons = Mockito.mockConstruction(HiveClient.class, (mock, ctx) -> {
+ Mockito.when(mock.getDatabaseList("*", null)).thenReturn(Collections.emptyList());
+ })) {
+ Map<String, Object> resp = HiveClient.connectionTest("svc", Collections.emptyMap());
+ assertNotNull(resp);
+ assertNotEquals(Boolean.TRUE, resp.get("connectivityStatus"));
+ }
+ }
+
+ @Test
+ public void test02_connectionTestSuccessSetsSuccessMessageAndCloses() throws Exception {
+ try (MockedConstruction<HiveClient> cons = Mockito.mockConstruction(HiveClient.class, (mock, ctx) -> {
+ Mockito.when(mock.getDatabaseList("*", null)).thenReturn(Collections.singletonList("db1"));
+ })) {
+ Map<String, Object> resp = HiveClient.connectionTest("svc", new HashMap<>());
+ assertNotNull(resp);
+ List<HiveClient> constructed = cons.constructed();
+ if (!constructed.isEmpty()) {
+ Mockito.verify(constructed.get(0), Mockito.times(1)).close();
+ }
+ }
+ }
+
+ @Test
+ public void test03_connectionTestPropagatesException() throws Exception {
+ try (MockedConstruction<HiveClient> cons = Mockito.mockConstruction(HiveClient.class, (mock, ctx) -> {
+ Mockito.when(mock.getDatabaseList("*", null)).thenThrow(new RuntimeException("boom"));
+ })) {
+ assertThrows(Exception.class, () -> HiveClient.connectionTest("svc", Collections.emptyMap()));
+ }
+ }
+
+ @Test
+ public void test04_constructorsInvokeInitHive() throws Exception {
+ NoopHiveClient c1 = new NoopHiveClient("svc");
+ assertTrue(c1.initCalled);
+ NoopHiveClient c2 = new NoopHiveClient("svc", new HashMap<>());
+ assertTrue(c2.initCalled);
+ }
+
+ @Test
+ public void test05_getDatabaseList_usesHMWhenEnabled() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, true);
+ Field fHM = HiveClient.class.getDeclaredField("hiveClient");
+ fHM.setAccessible(true);
+ HiveMetaStoreClient hms = Mockito.mock(HiveMetaStoreClient.class);
+ when(hms.getAllDatabases()).thenReturn(Arrays.asList("db1", "db2"));
+ fHM.set(client, hms);
+ List<String> out = client.getDatabaseList("*", Collections.singletonList("db2"));
+ assertEquals(Collections.singletonList("db1"), out);
+ }
+
+ @Test
+ public void test06_getTableList_usesHMAndRespectsExcludes() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, true);
+ Field fHM = HiveClient.class.getDeclaredField("hiveClient");
+ fHM.setAccessible(true);
+ HiveMetaStoreClient hms = Mockito.mock(HiveMetaStoreClient.class);
+ when(hms.getTables("db1", "tbl*")).thenReturn(Arrays.asList("t1", "t2"));
+ fHM.set(client, hms);
+ List<String> out = client.getTableList("tbl*", Collections.singletonList("db1"), Collections.singletonList("t2"));
+ assertEquals(Collections.singletonList("t1"), out);
+ }
+
+ @Test
+ public void test07_getColumnList_usesHMWithPatternAndExcludes() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, true);
+ Field fHM = HiveClient.class.getDeclaredField("hiveClient");
+ fHM.setAccessible(true);
+ HiveMetaStoreClient hms = Mockito.mock(HiveMetaStoreClient.class);
+ when(hms.getFields("db1", "t1")).thenReturn(Arrays.asList(new FieldSchema("c1", "int", null), new FieldSchema("c2", "string", null)));
+ fHM.set(client, hms);
+ List<String> out = client.getColumnList("c*", Collections.singletonList("db1"), Collections.singletonList("t1"), Collections.singletonList("c2"));
+ assertEquals(Collections.singletonList("c1"), out);
+ }
+
+ @Test
+ public void test08_main_args2_noDatabaseFoundPrintedAndClosed() throws Exception {
+ PrintStream origOut = System.out;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(bout));
+ try (MockedConstruction<HiveClient> cons = Mockito.mockConstruction(HiveClient.class, (mock, ctx) -> {
+ when(mock.getDatabaseList("db", null)).thenReturn(Collections.emptyList());
+ })) {
+ HiveClient.main(new String[] {"svc", "db"});
+ String out = bout.toString();
+ assertNotNull(out);
+ // ensure constructed mock was closed by try-with-resources
+ List<HiveClient> constructed = cons.constructed();
+ if (!constructed.isEmpty()) {
+ Mockito.verify(constructed.get(0), Mockito.times(1)).close();
+ }
+ } finally {
+ System.setOut(origOut);
+ }
+ }
+
+ @Test
+ public void test09_main_args3_printsTables() throws Exception {
+ PrintStream origOut = System.out;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(bout));
+ try (MockedConstruction<HiveClient> cons = Mockito.mockConstruction(HiveClient.class, (mock, ctx) -> {
+ when(mock.getTableList("tbl", null, null)).thenReturn(Collections.singletonList("db.tbl1"));
+ })) {
+ HiveClient.main(new String[] {"svc", "db", "tbl"});
+ String out = bout.toString();
+ assertNotNull(out);
+ } finally {
+ System.setOut(origOut);
+ }
+ }
+
+ @Test
+ public void test10_main_args4_printsColumns() throws Exception {
+ PrintStream origOut = System.out;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(bout));
+ try (MockedConstruction<HiveClient> cons = Mockito.mockConstruction(HiveClient.class, (mock, ctx) -> {
+ when(mock.getColumnList("col", null, null, null)).thenReturn(Collections.singletonList("db.tbl.col1"));
+ })) {
+ HiveClient.main(new String[] {"svc", "db", "tbl", "col"});
+ String out = bout.toString();
+ assertNotNull(out);
+ } finally {
+ System.setOut(origOut);
+ }
+ }
+
+ @Test
+ public void test11_getDatabaseList_jdbcPath() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, false);
+ Field fCon = HiveClient.class.getDeclaredField("con");
+ fCon.setAccessible(true);
+ Connection con = Mockito.mock(Connection.class);
+ Statement stat = Mockito.mock(Statement.class);
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ when(con.createStatement()).thenReturn(stat);
+ when(stat.executeQuery(Mockito.anyString())).thenReturn(rs);
+ when(rs.next()).thenReturn(true, false);
+ when(rs.getString(1)).thenReturn("db1");
+ fCon.set(client, con);
+ List<String> out = client.getDatabaseList("db*", null);
+ assertEquals(Collections.singletonList("db1"), out);
+ }
+
+ @Test
+ public void test12_close_closesConnection() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fCon = HiveClient.class.getDeclaredField("con");
+ fCon.setAccessible(true);
+ Connection con = Mockito.mock(Connection.class);
+ fCon.set(client, con);
+ client.close();
+ Mockito.verify(con, Mockito.times(1)).close();
+ }
+
+ @Test
+ public void test13_getTableList_jdbcPath_excludesAndPattern() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, false);
+ Field fCon = HiveClient.class.getDeclaredField("con");
+ fCon.setAccessible(true);
+ Connection con = Mockito.mock(Connection.class);
+ Statement stat = Mockito.mock(Statement.class);
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ when(con.createStatement()).thenReturn(stat);
+ when(stat.execute(Mockito.eq("use db1"))).thenReturn(true);
+ when(stat.executeQuery(Mockito.anyString())).thenReturn(rs);
+ when(rs.next()).thenReturn(true, true, false);
+ when(rs.getString(1)).thenReturn("t1", "t2");
+ fCon.set(client, con);
+ List<String> out = client.getTableList("t*", Collections.singletonList("db1"), Collections.singletonList("t2"));
+ assertEquals(Collections.singletonList("t1"), out);
+ Mockito.verify(stat, Mockito.atLeastOnce()).execute(Mockito.eq("use db1"));
+ }
+
+ @Test
+ public void test14_getTableList_jdbcPath_timeoutThrowsHadoopException() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, false);
+ Field fCon = HiveClient.class.getDeclaredField("con");
+ fCon.setAccessible(true);
+ Connection con = Mockito.mock(Connection.class);
+ Statement stat = Mockito.mock(Statement.class);
+ when(con.createStatement()).thenReturn(stat);
+ when(stat.execute(Mockito.anyString())).thenReturn(true);
+ when(stat.executeQuery(Mockito.anyString())).thenThrow(new SQLTimeoutException("timeout"));
+ fCon.set(client, con);
+ assertThrows(HadoopException.class, () -> client.getTableList("t*", Collections.singletonList("db1"), null));
+ }
+
+ @Test
+ public void test17_getClmList_jdbcPath_excludesAndPattern() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, false);
+ Field fCon = HiveClient.class.getDeclaredField("con");
+ fCon.setAccessible(true);
+ Connection con = Mockito.mock(Connection.class);
+ Statement stat = Mockito.mock(Statement.class);
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ when(con.createStatement()).thenReturn(stat);
+ when(stat.execute(Mockito.eq("use db1"))).thenReturn(true);
+ when(stat.executeQuery(Mockito.eq("describe t1"))).thenReturn(rs);
+ when(rs.next()).thenReturn(true, true, false);
+ when(rs.getString(1)).thenReturn("c1", "c2");
+ fCon.set(client, con);
+ List<String> out = client.getColumnList("c*", Collections.singletonList("db1"), Collections.singletonList("t1"), Collections.singletonList("c2"));
+ assertEquals(Collections.singletonList("c1"), out);
+ }
+
+ @Test
+ public void test18_getClmList_jdbcPath_timeoutThrowsHadoopException() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, false);
+ Field fCon = HiveClient.class.getDeclaredField("con");
+ fCon.setAccessible(true);
+ Connection con = Mockito.mock(Connection.class);
+ Statement stat = Mockito.mock(Statement.class);
+ when(con.createStatement()).thenReturn(stat);
+ when(stat.execute(Mockito.anyString())).thenReturn(true);
+ when(stat.executeQuery(Mockito.anyString())).thenThrow(new SQLTimeoutException("timeout"));
+ fCon.set(client, con);
+ assertThrows(HadoopException.class, () -> client.getColumnList("c*", Collections.singletonList("db1"), Collections.singletonList("t1"), null));
+ }
+
+ @Test
+ public void test19_main_noArgs_printsUsageAndExits() {
+ PrintStream origErr = System.err;
+ ByteArrayOutputStream berr = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(berr));
+ SecurityManager prev = System.getSecurityManager();
+ ExitInterceptSecurityManager sm = new ExitInterceptSecurityManager(prev);
+ System.setSecurityManager(sm);
+ try {
+ assertThrows(SecurityException.class, () -> HiveClient.main(new String[] {}));
+ assertEquals(Integer.valueOf(1), sm.status);
+ String err = berr.toString();
+ assertNotNull(err);
+ assertTrue(err.contains("USAGE: java"));
+ } finally {
+ System.setErr(origErr);
+ System.setSecurityManager(prev);
+ }
+ }
+
+ @Test
+ public void test20_getViewListAndUDFListReturnNull() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ assertNull(client.getViewList("db", "v*"));
+ assertNull(client.getUDFList("db", "f*"));
+ }
+
+ @Test
+ public void test21_privateInitConnection_wrapperRethrowsAsHadoopException() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ // Configure holder to take HM path so inner will wrap to HadoopException
+ Field fCfg = Class.forName("org.apache.ranger.plugin.client.BaseClient").getDeclaredField("configHolder");
+ fCfg.setAccessible(true);
+ HadoopConfigHolder cfg = Mockito.mock(HadoopConfigHolder.class);
+ when(cfg.getRangerSection()).thenReturn(new Properties());
+ fCfg.set(client, cfg);
+ Method m = HiveClient.class.getDeclaredMethod("initConnection");
+ m.setAccessible(true);
+ assertThrows(HadoopException.class, () -> {
+ try {
+ m.invoke(client);
+ } catch (InvocationTargetException ite) {
+ throw ite.getCause();
+ }
+ });
+ }
+
+ @Test
+ public void test22_initConnection_hmBranch_success() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, true);
+ Field fSite = HiveClient.class.getDeclaredField("hiveSiteFilePath");
+ fSite.setAccessible(true);
+ fSite.set(client, "/path/does/not/exist/hive-site.xml");
+ try (MockedConstruction<HiveMetaStoreClient> cons = Mockito.mockConstruction(HiveMetaStoreClient.class, (mock, ctx) -> {})) {
+ Method m = HiveClient.class.getDeclaredMethod("initConnection", String.class, String.class);
+ m.setAccessible(true);
+ // should not throw; constructor intercepted and hiveClient set
+ m.invoke(client, null, null);
+ List<HiveMetaStoreClient> constructed = cons.constructed();
+ assertTrue(constructed.size() >= 1);
+ }
+ }
+
+ @Test
+ public void test22b_initConnection_hmBranch_throwableWrapsAsHadoopException() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fFlag = HiveClient.class.getDeclaredField("enableHiveMetastoreLookup");
+ fFlag.setAccessible(true);
+ fFlag.set(client, true);
+ Field fSite = HiveClient.class.getDeclaredField("hiveSiteFilePath");
+ fSite.setAccessible(true);
+ fSite.set(client, ""); // triggers "property not found" path
+ try (MockedConstruction<HiveMetaStoreClient> cons = Mockito.mockConstruction(HiveMetaStoreClient.class, (mock, ctx) -> {
+ throw new RuntimeException("boom");
+ })) {
+ Method m = HiveClient.class.getDeclaredMethod("initConnection", String.class, String.class);
+ m.setAccessible(true);
+ assertThrows(HadoopException.class, () -> {
+ try {
+ m.invoke(client, null, null);
+ } catch (InvocationTargetException ite) {
+ throw ite.getCause();
+ }
+ });
+ }
+ }
+
+ @Test
+ public void test23_initConnection_jdbcBranch_reflectionExceptionPaths() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fCfg = Class.forName("org.apache.ranger.plugin.client.BaseClient").getDeclaredField("configHolder");
+ fCfg.setAccessible(true);
+ HadoopConfigHolder cfg = Mockito.mock(HadoopConfigHolder.class);
+ Properties rangerProps = new Properties();
+ rangerProps.setProperty("jdbc.driverClassName", TestHiveClient.IllegalAccessDriver.class.getName());
+ rangerProps.setProperty("jdbc.url", "jdbc:hive2://localhost:10000");
+ when(cfg.getRangerSection()).thenReturn(rangerProps);
+ fCfg.set(client, cfg);
+ Method m = HiveClient.class.getDeclaredMethod("initConnection", String.class, String.class);
+ m.setAccessible(true);
+ // IllegalAccessException path
+ assertThrows(HadoopException.class, () -> {
+ try {
+ m.invoke(client, null, null);
+ } catch (InvocationTargetException ite) {
+ throw ite.getCause();
+ }
+ });
+ // Class not found -> Throwable path
+ rangerProps.setProperty("jdbc.driverClassName", "com.example.NoSuchDriver");
+ assertThrows(HadoopException.class, () -> {
+ try {
+ m.invoke(client, null, null);
+ } catch (InvocationTargetException ite) {
+ throw ite.getCause();
+ }
+ });
+ }
+
+ @Test
+ public void test24_initHive_kerberosPath_invokesMetastoreInitConnection() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fCfg = Class.forName("org.apache.ranger.plugin.client.BaseClient").getDeclaredField("configHolder");
+ fCfg.setAccessible(true);
+ HadoopConfigHolder cfg = Mockito.mock(HadoopConfigHolder.class);
+ fCfg.set(client, cfg);
+ try (MockedStatic<Subject> subj = Mockito.mockStatic(Subject.class)) {
+ subj.when(() -> Subject.doAs(Mockito.any(Subject.class), Mockito.any(PrivilegedExceptionAction.class))).thenReturn(null);
+ Method m = HiveClient.class.getDeclaredMethod("initHive");
+ m.setAccessible(true);
+ assertDoesNotThrow(() -> m.invoke(client));
+ }
+ }
+
+ @Test
+ public void test25_initHive_nonKerberosPath_invokesJdbcInitConnectionAndWraps() throws Exception {
+ NoopHiveClient client = new NoopHiveClient("svc", new HashMap<>());
+ Field fCfg = Class.forName("org.apache.ranger.plugin.client.BaseClient").getDeclaredField("configHolder");
+ fCfg.setAccessible(true);
+ HadoopConfigHolder cfg = Mockito.mock(HadoopConfigHolder.class);
+ Mockito.when(cfg.isEnableHiveMetastoreLookup()).thenReturn(false);
+ Mockito.when(cfg.getHiveSiteFilePath()).thenReturn("");
+ Mockito.when(cfg.isKerberosAuthentication()).thenReturn(false);
+ Mockito.when(cfg.getUserName()).thenReturn("u");
+ Mockito.when(cfg.getPassword()).thenReturn("p");
+ fCfg.set(client, cfg);
+ try (MockedStatic<Subject> subj = Mockito.mockStatic(Subject.class)) {
+ subj.when(() -> Subject.doAs(Mockito.any(Subject.class), Mockito.any(PrivilegedExceptionAction.class))).thenReturn(null);
+ Method m = HiveClient.class.getDeclaredMethod("initHive");
+ m.setAccessible(true);
+ assertDoesNotThrow(() -> m.invoke(client));
+ }
+ }
+
+ public static class NoopHiveClient extends HiveClient {
+ public boolean initCalled;
+
+ public NoopHiveClient(String serviceName) throws Exception {
+ super(serviceName);
+ }
+
+ public NoopHiveClient(String serviceName, Map<String, String> props) throws Exception {
+ super(serviceName, props);
+ }
+
+ @Override
+ public void initHive() {
+ initCalled = true;
+ }
+
+ @Override
+ protected void login() {
+ /* no-op to avoid real Hadoop auth */
+ }
+
+ @Override
+ protected Subject getLoginSubject() {
+ return new Subject();
+ }
+ }
+
+ public static class BypassLoginHiveClient extends HiveClient {
+ public BypassLoginHiveClient(String serviceName) throws Exception {
+ super(serviceName);
+ }
+
+ public BypassLoginHiveClient(String serviceName, Map<String, String> props) throws Exception {
+ super(serviceName, props);
+ }
+
+ @Override
+ protected void login() { /* no-op to avoid real Hadoop auth */ }
+
+ @Override
+ protected Subject getLoginSubject() {
+ return new Subject();
+ }
+ }
+
+ private static class ExitInterceptSecurityManager extends SecurityManager {
+ private final SecurityManager original;
+ public Integer status;
+
+ ExitInterceptSecurityManager(SecurityManager original) {
+ this.original = original;
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ if (original != null) {
+ original.checkPermission(perm);
+ }
+ }
+
+ @Override
+ public void checkExit(int status) {
+ this.status = status;
+ throw new SecurityException("exit");
+ }
+ }
+
+ public static class IllegalAccessDriver implements Driver {
+ private IllegalAccessDriver() {}
+
+ @Override
+ public Connection connect(String url, Properties info) {
+ return null;
+ }
+
+ @Override
+ public boolean acceptsURL(String url) {
+ return false;
+ }
+
+ @Override
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
+ return new DriverPropertyInfo[0];
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return 1;
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ @Override
+ public boolean jdbcCompliant() {
+ return false;
+ }
+
+ @Override
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ throw new SQLFeatureNotSupportedException();
+ }
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveConnectionMgr.java b/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveConnectionMgr.java
new file mode 100644
index 000000000..1578855e4
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveConnectionMgr.java
@@ -0,0 +1,126 @@
+/*
+ * 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.services.hive.client;
+
+import org.apache.ranger.plugin.util.TimedEventUtil;
+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.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for HiveConnectionMgr
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestHiveConnectionMgr {
+ @Test
+ public void test01_returnsNullWhenServiceTypeNull() {
+ HiveConnectionMgr mgr = new HiveConnectionMgr();
+ HiveClient ret = mgr.getHiveConnection("svc", null, new HashMap<>());
+ assertNull(ret);
+ }
+
+ @Test
+ public void test02_returnsNullWhenConfigsNullAndCacheEmpty() {
+ HiveConnectionMgr mgr = new HiveConnectionMgr();
+ HiveClient ret = mgr.getHiveConnection("svc", "hive", null);
+ assertNull(ret);
+ }
+
+ @Test
+ public void test03_returnsCachedAndValidates() throws Exception {
+ HiveConnectionMgr mgr = new HiveConnectionMgr();
+
+ HiveClient client = Mockito.mock(HiveClient.class);
+ Mockito.when(client.getDatabaseList("*", null)).thenReturn(Collections.singletonList("db1"));
+
+ Field f = HiveConnectionMgr.class.getDeclaredField("hiveConnectionCache");
+ f.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ ConcurrentHashMap<String, HiveClient> cache = (ConcurrentHashMap<String, HiveClient>) f.get(mgr);
+ cache.put("svc", client);
+
+ HiveClient ret = mgr.getHiveConnection("svc", "hive", new HashMap<>());
+ assertEquals(client, ret);
+ }
+
+ @Test
+ public void test04_newClientClosedIfOldPresentAtPutIfAbsent() throws Exception {
+ HiveConnectionMgr mgr = new HiveConnectionMgr();
+
+ // Replace cache with a mock to simulate race: get() returns null, putIfAbsent returns existing old
+ @SuppressWarnings("unchecked")
+ ConcurrentMap<String, HiveClient> mockCache = Mockito.mock(ConcurrentMap.class);
+ Field fCache = HiveConnectionMgr.class.getDeclaredField("hiveConnectionCache");
+ fCache.setAccessible(true);
+ fCache.set(mgr, mockCache);
+
+ HiveClient oldClient = Mockito.mock(HiveClient.class);
+ HiveClient newClient = Mockito.mock(HiveClient.class);
+
+ Mockito.when(mockCache.get("svc")).thenReturn(null);
+ Mockito.when(mockCache.putIfAbsent("svc", newClient)).thenReturn(oldClient);
+
+ try (MockedStatic<TimedEventUtil> s = Mockito.mockStatic(TimedEventUtil.class)) {
+ s.when(() -> TimedEventUtil.timedTask(Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(newClient);
+
+ HiveClient ret = mgr.getHiveConnection("svc", "hive", new HashMap<>());
+ assertEquals(oldClient, ret);
+ Mockito.verify(newClient, Mockito.times(1)).close();
+ }
+ }
+
+ @Test
+ public void test05_cachedClientFailureRemovesClosesAndRecreates() throws Exception {
+ HiveConnectionMgr mgr = new HiveConnectionMgr();
+
+ Field fCache = HiveConnectionMgr.class.getDeclaredField("hiveConnectionCache");
+ fCache.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ ConcurrentHashMap<String, HiveClient> cache = (ConcurrentHashMap<String, HiveClient>) fCache.get(mgr);
+
+ HiveClient badClient = Mockito.mock(HiveClient.class);
+ Mockito.when(badClient.getDatabaseList("*", null)).thenThrow(new RuntimeException("boom"));
+ cache.put("svc", badClient);
+
+ HiveClient newClient = Mockito.mock(HiveClient.class);
+ try (MockedStatic<TimedEventUtil> s = Mockito.mockStatic(TimedEventUtil.class)) {
+ s.when(() -> TimedEventUtil.timedTask(Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(newClient);
+
+ HiveClient ret = mgr.getHiveConnection("svc", "hive", new HashMap<>());
+ assertEquals(newClient, ret);
+ Mockito.verify(badClient, Mockito.times(1)).close();
+ assertEquals(newClient, cache.get("svc"));
+ }
+ }
+}
diff --git a/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveResourceMgr.java b/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveResourceMgr.java
new file mode 100644
index 000000000..b1db31555
--- /dev/null
+++ b/hive-agent/src/test/java/org/apache/ranger/services/hive/client/TestHiveResourceMgr.java
@@ -0,0 +1,98 @@
+/*
+ * 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.services.hive.client;
+
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+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.MockedConstruction;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Arrays;
+import java.util.Collections;
+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.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for HiveResourceMgr
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestHiveResourceMgr {
+ @Test
+ public void test01_connectionTestDelegatesToHiveClient() throws Exception {
+ try (MockedStatic<HiveClient> staticMock = Mockito.mockStatic(HiveClient.class)) {
+ Map<String, Object> resp = new HashMap<>();
+ resp.put("connectivityStatus", true);
+ staticMock.when(() -> HiveClient.connectionTest(Mockito.eq("svc"), Mockito.anyMap())).thenReturn(resp);
+
+ Map<String, Object> out = HiveResourceMgr.connectionTest("svc", Collections.emptyMap());
+ assertEquals(resp, out);
+ }
+ }
+
+ @Test
+ public void test02_getHiveResources_dbTableColumnPaths() throws Exception {
+ HiveClient client = Mockito.mock(HiveClient.class);
+ Mockito.when(client.getDatabaseList("db*", null)).thenReturn(Arrays.asList("db1", "db2"));
+ Mockito.when(client.getTableList("tbl*", null, null)).thenReturn(Arrays.asList("db1.tbl1", "db1.tbl2"));
+ Mockito.when(client.getColumnList("col*", null, null, null)).thenReturn(Collections.singletonList("db1.tbl1.col1"));
+
+ try (MockedConstruction<HiveConnectionMgr> cons = Mockito.mockConstruction(HiveConnectionMgr.class, (mock, ctx) -> {
+ Mockito.when(mock.getHiveConnection(Mockito.anyString(), Mockito.anyString(), Mockito.anyMap())).thenReturn(client);
+ })) {
+ ResourceLookupContext ctx = new ResourceLookupContext();
+ ctx.setUserInput("db");
+ ctx.setResourceName("database");
+ List<String> dbs = HiveResourceMgr.getHiveResources("svc", "hive", Collections.emptyMap(), ctx);
+ assertNotNull(dbs);
+
+ ctx = new ResourceLookupContext();
+ ctx.setUserInput("tbl");
+ ctx.setResourceName("table");
+ List<String> tbls = HiveResourceMgr.getHiveResources("svc", "hive", Collections.emptyMap(), ctx);
+ assertNotNull(tbls);
+
+ ctx = new ResourceLookupContext();
+ ctx.setUserInput("col");
+ ctx.setResourceName("column");
+ List<String> cols = HiveResourceMgr.getHiveResources("svc", "hive", Collections.emptyMap(), ctx);
+ assertNotNull(cols);
+ }
+ }
+
+ @Test
+ public void test03_getHiveResources_nullsReturnNull() throws Exception {
+ ResourceLookupContext ctx = new ResourceLookupContext();
+ ctx.setUserInput(null);
+ ctx.setResourceName("database");
+ List<String> out = HiveResourceMgr.getHiveResources("svc", "hive", Collections.emptyMap(), ctx);
+ assertNull(out);
+ }
+}