diff --git a/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerNoInvocation.java b/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerNoInvocation.java new file mode 100644 index 0000000000..4632d21142 --- /dev/null +++ b/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerNoInvocation.java @@ -0,0 +1,118 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; + +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.conf.HiveConf.ConfVars; +import org.apache.hadoop.hive.ql.CommandNeedRetryException; +import org.apache.hadoop.hive.ql.Driver; +import org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; +import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse; +import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; +import org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator; +import org.apache.hadoop.hive.ql.session.SessionState; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; + +/** + * Test HiveAuthorizer api invocation + */ +public class TestHiveAuthorizerNoInvocation { + protected static HiveConf conf; + protected static Driver driver; + private static final String tableName = TestHiveAuthorizerNoInvocation.class.getSimpleName() + + "Table"; + static HiveAuthorizationValidator mockValidator; + static HiveAccessController mockController; + /** + * This factory creates a mocked HiveAuthorizer class. Use the mocked class to + * capture the argument passed to it in the test case. + */ + static class MockedHiveAuthorizerFactory implements HiveAuthorizerFactory { + @Override + public HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory, + HiveConf conf, HiveAuthenticationProvider authenticator, HiveAuthzSessionContext ctx) { + mockController = Mockito.mock(HiveAccessController.class); + mockValidator = Mockito.mock(HiveAuthorizationValidator.class); + return new HiveAuthorizerImpl(mockController, mockValidator); + } + + } + + @BeforeClass + public static void beforeTest() throws Exception { + conf = new HiveConf(); + + // Turn on mocked authorization + conf.setVar(ConfVars.HIVE_AUTHORIZATION_MANAGER, MockedHiveAuthorizerFactory.class.getName()); + conf.setVar(ConfVars.HIVE_AUTHENTICATOR_MANAGER, SessionStateUserAuthenticator.class.getName()); + conf.setBoolVar(ConfVars.HIVE_AUTHORIZATION_ENABLED, true); + conf.setBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS, false); + conf.setBoolVar(ConfVars.HIVE_SUPPORT_CONCURRENCY, true); + conf.setVar(ConfVars.HIVE_TXN_MANAGER, DbTxnManager.class.getName()); + conf.setVar(HiveConf.ConfVars.HIVEMAPREDMODE, "nonstrict"); + + SessionState.start(conf); + driver = new Driver(conf); + runCmd("create table " + tableName + + " (i int, j int, k string) partitioned by (city string, `date` string) "); + } + + private static void runCmd(String cmd) throws CommandNeedRetryException { + CommandProcessorResponse resp = driver.run(cmd); + assertEquals(0, resp.getResponseCode()); + } + + @AfterClass + public static void afterTests() throws Exception { + // Drop the tables when we're done. This makes the test work inside an IDE + runCmd("drop table if exists " + tableName); + driver.close(); + } + + @Test + public void testCommandsNoAuthorizationRequired() throws HiveAuthzPluginException, HiveAccessControlException, + CommandNeedRetryException { + + reset(mockController); + reset(mockValidator); + + int status = driver.compile("select 3"); + status = driver.compile("drop database if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("drop function if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("drop index if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("drop micro if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("drop table if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("drop view if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("drop table if exists testCommandsNoAuthorizationRequired"); + status = driver.compile("alter table tableName drop if exists partition (city='random', date='random')"); + + verify(mockValidator, never()).checkPrivileges(any(HiveOperationType.class), + any(), any(), + any(HiveAuthzContext.class)); + } +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java index 3a51d1b0a1..c0bdcba852 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java @@ -83,6 +83,22 @@ public void revokeRole(List hivePrincipals, List roles, public void checkPrivileges(HiveOperationType hiveOpType, List inputHObjs, List outputHObjs, HiveAuthzContext context) throws HiveAuthzPluginException, HiveAccessControlException { + // Skip calling authorizator for these cases + // 1. drop command with 'if exists' option but the object doesn't exist, + // 2. query doesn't need any inputs + if ((inputHObjs == null || inputHObjs.isEmpty()) && + (outputHObjs == null || outputHObjs.isEmpty()) && + (hiveOpType == HiveOperationType.QUERY || + hiveOpType == HiveOperationType.DROPDATABASE || + hiveOpType == HiveOperationType.DROPFUNCTION || + hiveOpType == HiveOperationType.DROPINDEX || + hiveOpType == HiveOperationType.DROPMACRO || + hiveOpType == HiveOperationType.DROPTABLE || + hiveOpType == HiveOperationType.DROPVIEW || + hiveOpType == HiveOperationType.ALTERTABLE_DROPPARTS)) { + return; + } + authValidator.checkPrivileges(hiveOpType, inputHObjs, outputHObjs, context); }