| /* |
| * 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.drill.exec.server; |
| |
| import com.google.common.base.Joiner; |
| import com.typesafe.config.ConfigValueFactory; |
| import org.apache.drill.test.BaseTestQuery; |
| import org.apache.drill.common.config.DrillProperties; |
| import org.apache.drill.common.config.DrillConfig; |
| import org.apache.drill.common.util.DrillStringUtils; |
| import org.apache.drill.exec.ExecConstants; |
| import org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl; |
| import org.apache.drill.exec.server.options.OptionManager; |
| import org.apache.drill.exec.util.ImpersonationUtil; |
| import org.apache.drill.test.ClientFixture; |
| import org.apache.drill.test.ClusterFixture; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.ADMIN_GROUP; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.ADMIN_USER; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.ADMIN_USER_PASSWORD; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.PROCESS_USER; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.PROCESS_USER_PASSWORD; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_1; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_1_PASSWORD; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_2; |
| import static org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_2_PASSWORD; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.util.Properties; |
| |
| /** |
| * Test setting system scoped options with user authentication enabled. (DRILL-3622) |
| */ |
| public class TestOptionsAuthEnabled extends BaseTestQuery { |
| private static final String setSysOptionQuery = |
| String.format("ALTER SYSTEM SET `%s` = %d;", ExecConstants.SLICE_TARGET, 200); |
| |
| @BeforeClass |
| public static void setupCluster() throws Exception { |
| // Create a new DrillConfig which has user authentication enabled and test authenticator set |
| final DrillConfig config = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties()) |
| .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED, ConfigValueFactory.fromAnyRef(true)) |
| .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL, |
| ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))); |
| |
| final Properties connectionProps = new Properties(); |
| connectionProps.setProperty(DrillProperties.USER, PROCESS_USER); |
| connectionProps.setProperty(DrillProperties.PASSWORD, PROCESS_USER_PASSWORD); |
| |
| updateTestCluster(1, config, connectionProps); |
| |
| // Add user "admin" to admin username list |
| test(String.format("ALTER SYSTEM SET `%s`='%s,%s'", ExecConstants.ADMIN_USERS_KEY, ADMIN_USER, PROCESS_USER)); |
| |
| // Set "admingrp" to admin username list |
| test(String.format("ALTER SYSTEM SET `%s`='%s'", ExecConstants.ADMIN_USER_GROUPS_KEY, ADMIN_GROUP)); |
| } |
| |
| @Test |
| public void updateSysOptAsAdminUser() throws Exception { |
| updateClient(ADMIN_USER, ADMIN_USER_PASSWORD); |
| setOptHelper(); |
| } |
| |
| @Test |
| public void updateSysOptAsNonAdminUser() throws Exception { |
| updateClient(TEST_USER_2, TEST_USER_2_PASSWORD); |
| errorMsgTestHelper(setSysOptionQuery, "Not authorized to change SYSTEM options."); |
| } |
| |
| @Test |
| public void updateSysOptAsUserInAdminGroup() throws Exception { |
| updateClient(TEST_USER_1, TEST_USER_1_PASSWORD); |
| setOptHelper(); |
| } |
| |
| @Test |
| public void trySettingAdminOptsAtSessionScopeAsAdmin() throws Exception { |
| updateClient(ADMIN_USER, ADMIN_USER_PASSWORD); |
| final String setOptionQuery = |
| String.format("ALTER SESSION SET `%s`='%s,%s'", ExecConstants.ADMIN_USERS_KEY, ADMIN_USER, PROCESS_USER); |
| errorMsgTestHelper(setOptionQuery, "PERMISSION ERROR: Cannot change option security.admin.users in scope SESSION"); |
| } |
| |
| @Test |
| public void trySettingAdminOptsAtSessionScopeAsNonAdmin() throws Exception { |
| updateClient(TEST_USER_2, TEST_USER_2_PASSWORD); |
| final String setOptionQuery = |
| String.format("ALTER SESSION SET `%s`='%s,%s'", ExecConstants.ADMIN_USERS_KEY, ADMIN_USER, PROCESS_USER); |
| errorMsgTestHelper(setOptionQuery, "PERMISSION ERROR: Cannot change option security.admin.users in scope SESSION"); |
| } |
| |
| private void setOptHelper() throws Exception { |
| try { |
| test(setSysOptionQuery); |
| testBuilder() |
| .sqlQuery(String.format("SELECT val FROM sys.options WHERE name = '%s' AND optionScope = 'SYSTEM'", |
| ExecConstants.SLICE_TARGET)) |
| .unOrdered() |
| .baselineColumns("val") |
| .baselineValues(String.valueOf(200L)) |
| .go(); |
| } finally { |
| test(String.format("ALTER SYSTEM SET `%s` = %d;", ExecConstants.SLICE_TARGET, ExecConstants.SLICE_TARGET_DEFAULT)); |
| } |
| } |
| |
| @Test |
| public void testAdminUserOptions() throws Exception { |
| |
| try (ClusterFixture cluster = ClusterFixture.standardCluster(dirTestWatcher); |
| ClientFixture client = cluster.clientFixture()) { |
| OptionManager optionManager = cluster.drillbit().getContext().getOptionManager(); |
| |
| // Admin Users Tests |
| // config file should have the 'fake' default admin user and it should be returned |
| // by the option manager if the option has not been set by the user |
| String configAdminUser = optionManager.getOption(ExecConstants.ADMIN_USERS_VALIDATOR); |
| assertEquals(configAdminUser, ExecConstants.ADMIN_USERS_VALIDATOR.DEFAULT_ADMIN_USERS); |
| |
| // Option accessor should never return the 'fake' default from the config |
| String adminUser1 = ExecConstants.ADMIN_USERS_VALIDATOR.getAdminUsers(optionManager); |
| assertNotEquals(adminUser1, ExecConstants.ADMIN_USERS_VALIDATOR.DEFAULT_ADMIN_USERS); |
| |
| // Change testAdminUser if necessary |
| String testAdminUser = "ronswanson"; |
| if (adminUser1.equals(testAdminUser)) { |
| testAdminUser += "thefirst"; |
| } |
| // Check if the admin option accessor honors a user-supplied value |
| client.alterSystem(ExecConstants.ADMIN_USERS_KEY, testAdminUser); |
| String adminUser2 = ExecConstants.ADMIN_USERS_VALIDATOR.getAdminUsers(optionManager); |
| assertEquals(adminUser2, testAdminUser); |
| |
| // Ensure that the default admin users have admin privileges |
| client.resetSystem(ExecConstants.ADMIN_USERS_KEY); |
| client.resetSystem(ExecConstants.ADMIN_USER_GROUPS_KEY); |
| String systemAdminUsersList0 = ExecConstants.ADMIN_USERS_VALIDATOR.getAdminUsers(optionManager); |
| String systemAdminUserGroupsList0 = ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(optionManager); |
| for (String user : systemAdminUsersList0.split(",")) { |
| assertTrue(ImpersonationUtil.hasAdminPrivileges(user, systemAdminUsersList0, systemAdminUserGroupsList0)); |
| } |
| |
| // test if admin users, set by the user, have admin privileges |
| // test if we can handle a user-supplied list that is not well formatted |
| String crummyTestAdminUsersList = " alice, bob bob, charlie ,, dave "; |
| client.alterSystem(ExecConstants.ADMIN_USERS_KEY, crummyTestAdminUsersList); |
| String[] sanitizedAdminUsers = {"alice", "bob bob", "charlie", "dave"}; |
| // also test the CSV sanitizer |
| assertEquals(Joiner.on(",").join(sanitizedAdminUsers), DrillStringUtils.sanitizeCSV(crummyTestAdminUsersList)); |
| String systemAdminUsersList1 = ExecConstants.ADMIN_USERS_VALIDATOR.getAdminUsers(optionManager); |
| String systemAdminUserGroupsList1 = ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(optionManager); |
| for (String user : sanitizedAdminUsers) { |
| assertTrue(ImpersonationUtil.hasAdminPrivileges(user, systemAdminUsersList1, systemAdminUserGroupsList1)); |
| } |
| |
| // Admin User Groups Tests |
| // config file should have the 'fake' default admin user and it should be returned |
| // by the option manager if the option has not been set by the user |
| String configAdminUserGroups = optionManager.getOption(ExecConstants.ADMIN_USER_GROUPS_VALIDATOR); |
| assertEquals(configAdminUserGroups, ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.DEFAULT_ADMIN_USER_GROUPS); |
| |
| // Option accessor should never return the 'fake' default from the config |
| String adminUserGroups1 = ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(optionManager); |
| assertNotEquals(adminUserGroups1, ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.DEFAULT_ADMIN_USER_GROUPS); |
| |
| // Change testAdminUserGroups if necessary |
| String testAdminUserGroups = "yakshavers"; |
| if (adminUserGroups1.equals(testAdminUserGroups)) { |
| testAdminUserGroups += ",wormracers"; |
| } |
| // Check if the admin option accessor honors a user-supplied values |
| client.alterSystem(ExecConstants.ADMIN_USER_GROUPS_KEY, testAdminUserGroups); |
| String adminUserGroups2 = ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(optionManager); |
| assertEquals(adminUserGroups2, testAdminUserGroups); |
| |
| // Test if we can handle a user-supplied admin user groups list that is not well formatted |
| String crummyTestAdminUserGroupsList = " g1, g 2, g4 ,, g5 "; |
| client.alterSystem(ExecConstants.ADMIN_USER_GROUPS_KEY, crummyTestAdminUserGroupsList); |
| String systemAdminUserGroupsList2 = ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(optionManager); |
| // test if all the group tokens are well-formed |
| // Note: A hasAdminPrivilege() test cannot be done here, like in the tests for handling a crummy admin user list. |
| // This is because ImpersonationUtil currently does not implement an API that takes a group as an input to check |
| // for admin privileges |
| for (String group : systemAdminUserGroupsList2.split(",")) { |
| assertTrue(group.length() != 0); |
| assertTrue(group.trim().equals(group)); |
| } |
| } |
| } |
| } |