blob: c10060f8171d8e6ce93d9b94666006b7be796d30 [file] [log] [blame]
/*
* 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.metastore;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege;
import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.PrincipalType;
import org.apache.hadoop.hive.metastore.api.PrivilegeBag;
import org.apache.hadoop.hive.metastore.api.Role;
import org.apache.hadoop.hive.ql.security.authorization.MetaStoreAuthzAPIAuthorizerEmbedOnly;
import org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener;
import org.apache.thrift.TException;
import org.junit.Test;
/**
* Test case for {@link MetaStoreAuthzAPIAuthorizerEmbedOnly} The authorizer is
* supposed to allow api calls for metastore in embedded mode while disallowing
* them in remote metastore mode. Note that this is an abstract class, the
* subclasses that set the mode and the tests here get run as part of their
* testing.
*/
public abstract class AbstractTestAuthorizationApiAuthorizer {
protected static boolean isRemoteMetastoreMode;
private static HiveConf hiveConf;
private static HiveMetaStoreClient msc;
protected static void setup() throws Exception {
System.err.println("Running with remoteMode = " + isRemoteMetastoreMode);
System.setProperty("hive.metastore.pre.event.listeners",
AuthorizationPreEventListener.class.getName());
System.setProperty("hive.security.metastore.authorization.manager",
MetaStoreAuthzAPIAuthorizerEmbedOnly.class.getName());
hiveConf = new HiveConf();
if (isRemoteMetastoreMode) {
MetaStoreTestUtils.startMetaStoreWithRetry(hiveConf);
}
hiveConf.setIntVar(HiveConf.ConfVars.METASTORETHRIFTCONNECTIONRETRIES, 3);
hiveConf.set(HiveConf.ConfVars.PREEXECHOOKS.varname, "");
hiveConf.set(HiveConf.ConfVars.POSTEXECHOOKS.varname, "");
hiveConf.set(HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname, "false");
msc = new HiveMetaStoreClient(hiveConf);
}
interface FunctionInvoker {
public void invoke() throws Exception;
}
/**
* Test the if authorization failed/passed for FunctionInvoker that invokes a metastore client
* api call
* @param mscFunctionInvoker
* @throws Exception
*/
private void testFunction(FunctionInvoker mscFunctionInvoker) throws Exception {
boolean caughtEx = false;
try {
try {
mscFunctionInvoker.invoke();
} catch (RuntimeException e) {
// A hack to verify that authorization check passed. Exception can be thrown be cause
// the functions are not being called with valid params.
// verify that exception has come from ObjectStore code, which means that the
// authorization checks passed.
String exStackString = ExceptionUtils.getStackTrace(e);
assertTrue("Verifying this exception came after authorization check",
exStackString.contains("org.apache.hadoop.hive.metastore.ObjectStore"));
// If its not an exception caused by auth check, ignore it
}
assertFalse("Authz Exception should have been thrown in remote mode", isRemoteMetastoreMode);
System.err.println("No auth exception thrown");
} catch (MetaException e) {
System.err.println("Caught exception");
String exStackString = ExceptionUtils.getStackTrace(e);
// Check if MetaException has one of InvalidObjectException or NoSuchObjectExcetion or any exception thrown from ObjectStore , which means that the
// authorization checks passed.
if(exStackString.contains("org.apache.hadoop.hive.metastore.api.NoSuchObjectException") ||
exStackString.contains("org.apache.hadoop.hive.metastore.api.InvalidObjectException")) {
assertFalse("No Authz exception thrown in embedded mode", isRemoteMetastoreMode);
} else {
caughtEx = true;
assertTrue(e.getMessage().contains(MetaStoreAuthzAPIAuthorizerEmbedOnly.errMsg));
}
} catch (TException e) {
String exStackString = ExceptionUtils.getStackTrace(e);
assertTrue("Verifying this exception came after authorization check",
exStackString.contains("org.apache.hadoop.hive.metastore.ObjectStore"));
}
if (!isRemoteMetastoreMode) {
assertFalse("No exception should be thrown in embedded mode", caughtEx);
}
}
@Test
public void testGrantPriv() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.grant_privileges(new PrivilegeBag(new ArrayList<HiveObjectPrivilege>()));
}
};
testFunction(invoker);
}
@Test
public void testRevokePriv() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.revoke_privileges(new PrivilegeBag(new ArrayList<HiveObjectPrivilege>()), false);
}
};
testFunction(invoker);
}
@Test
public void testGrantRole() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.grant_role(null, null, null, null, null, true);
}
};
testFunction(invoker);
}
@Test
public void testRevokeRole() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.revoke_role(null, null, null, false);
}
};
testFunction(invoker);
}
@Test
public void testCreateRole() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.create_role(new Role("role1", 0, "owner"));
}
};
testFunction(invoker);
}
@Test
public void testDropRole() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.drop_role(null);
}
};
testFunction(invoker);
}
@Test
public void testListRoles() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.list_roles(null, null);
}
};
testFunction(invoker);
}
@Test
public void testGetPrivSet() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.get_privilege_set(new HiveObjectRef(), null, new ArrayList<String>());
}
};
testFunction(invoker);
}
@Test
public void testListPriv() throws Exception {
FunctionInvoker invoker = new FunctionInvoker() {
@Override
public void invoke() throws Exception {
msc.list_privileges(null, PrincipalType.USER, new HiveObjectRef());
}
};
testFunction(invoker);
}
}