1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hbase.security.visibility; 19 20 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME; 21 import static org.junit.Assert.*; 22 23 import java.security.PrivilegedExceptionAction; 24 import java.util.ArrayList; 25 import java.util.List; 26 27 import org.apache.hadoop.conf.Configuration; 28 import org.apache.hadoop.hbase.HBaseTestingUtility; 29 import org.apache.hadoop.hbase.HConstants; 30 import org.apache.hadoop.hbase.TableName; 31 import org.apache.hadoop.hbase.client.Connection; 32 import org.apache.hadoop.hbase.client.ConnectionFactory; 33 import org.apache.hadoop.hbase.client.Put; 34 import org.apache.hadoop.hbase.client.Result; 35 import org.apache.hadoop.hbase.client.ResultScanner; 36 import org.apache.hadoop.hbase.client.Scan; 37 import org.apache.hadoop.hbase.client.Table; 38 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse; 39 import org.apache.hadoop.hbase.security.User; 40 import org.apache.hadoop.hbase.security.access.SecureTestUtil; 41 import org.apache.hadoop.hbase.testclassification.LargeTests; 42 import org.apache.hadoop.hbase.util.Bytes; 43 import org.junit.AfterClass; 44 import org.junit.BeforeClass; 45 import org.junit.Rule; 46 import org.junit.Test; 47 import org.junit.experimental.categories.Category; 48 import org.junit.rules.TestName; 49 50 import com.google.protobuf.ByteString; 51 52 @Category(LargeTests.class) 53 public class TestWithDisabledAuthorization { 54 55 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 56 57 private static final String CONFIDENTIAL = "confidential"; 58 private static final String SECRET = "secret"; 59 private static final String PRIVATE = "private"; 60 private static final byte[] TEST_FAMILY = Bytes.toBytes("test"); 61 private static final byte[] TEST_QUALIFIER = Bytes.toBytes("q"); 62 private static final byte[] ZERO = Bytes.toBytes(0L); 63 64 65 @Rule 66 public final TestName TEST_NAME = new TestName(); 67 68 private static User SUPERUSER; 69 private static User USER_RW; 70 private static Configuration conf; 71 72 @BeforeClass setUpBeforeClass()73 public static void setUpBeforeClass() throws Exception { 74 conf = TEST_UTIL.getConfiguration(); 75 // Up the handlers; this test needs more than usual. 76 conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10); 77 // Set up superuser 78 SecureTestUtil.configureSuperuser(conf); 79 80 // Install the VisibilityController as a system processor 81 VisibilityTestUtil.enableVisiblityLabels(conf); 82 83 // Now, DISABLE active authorization 84 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false); 85 86 TEST_UTIL.startMiniCluster(); 87 88 // Wait for the labels table to become available 89 TEST_UTIL.waitUntilAllRegionsAssigned(LABELS_TABLE_NAME); 90 91 // create a set of test users 92 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" }); 93 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]); 94 95 // Define test labels 96 SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() { 97 public Void run() throws Exception { 98 try (Connection conn = ConnectionFactory.createConnection(conf)) { 99 VisibilityClient.addLabels(conn, 100 new String[] { SECRET, CONFIDENTIAL, PRIVATE }); 101 VisibilityClient.setAuths(conn, 102 new String[] { SECRET, CONFIDENTIAL }, 103 USER_RW.getShortName()); 104 } catch (Throwable t) { 105 fail("Should not have failed"); 106 } 107 return null; 108 } 109 }); 110 } 111 112 @AfterClass tearDownAfterClass()113 public static void tearDownAfterClass() throws Exception { 114 TEST_UTIL.shutdownMiniCluster(); 115 } 116 117 @Test (timeout=180000) testManageUserAuths()118 public void testManageUserAuths() throws Throwable { 119 // Even though authorization is disabled, we should be able to manage user auths 120 121 SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() { 122 public Void run() throws Exception { 123 try (Connection conn = ConnectionFactory.createConnection(conf)) { 124 VisibilityClient.setAuths(conn, 125 new String[] { SECRET, CONFIDENTIAL }, 126 USER_RW.getShortName()); 127 } catch (Throwable t) { 128 fail("Should not have failed"); 129 } 130 return null; 131 } 132 }); 133 134 PrivilegedExceptionAction<List<String>> getAuths = 135 new PrivilegedExceptionAction<List<String>>() { 136 public List<String> run() throws Exception { 137 GetAuthsResponse authsResponse = null; 138 try (Connection conn = ConnectionFactory.createConnection(conf)) { 139 authsResponse = VisibilityClient.getAuths(conn, 140 USER_RW.getShortName()); 141 } catch (Throwable t) { 142 fail("Should not have failed"); 143 } 144 List<String> authsList = new ArrayList<String>(); 145 for (ByteString authBS : authsResponse.getAuthList()) { 146 authsList.add(Bytes.toString(authBS.toByteArray())); 147 } 148 return authsList; 149 } 150 }; 151 152 List<String> authsList = SUPERUSER.runAs(getAuths); 153 assertEquals(2, authsList.size()); 154 assertTrue(authsList.contains(SECRET)); 155 assertTrue(authsList.contains(CONFIDENTIAL)); 156 157 SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() { 158 public Void run() throws Exception { 159 try (Connection conn = ConnectionFactory.createConnection(conf)) { 160 VisibilityClient.clearAuths(conn, 161 new String[] { SECRET }, 162 USER_RW.getShortName()); 163 } catch (Throwable t) { 164 fail("Should not have failed"); 165 } 166 return null; 167 } 168 }); 169 170 authsList = SUPERUSER.runAs(getAuths); 171 assertEquals(1, authsList.size()); 172 assertTrue(authsList.contains(CONFIDENTIAL)); 173 174 SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() { 175 public Void run() throws Exception { 176 try (Connection conn = ConnectionFactory.createConnection(conf)) { 177 VisibilityClient.clearAuths(conn, 178 new String[] { CONFIDENTIAL }, 179 USER_RW.getShortName()); 180 } catch (Throwable t) { 181 fail("Should not have failed"); 182 } 183 return null; 184 } 185 }); 186 187 authsList = SUPERUSER.runAs(getAuths); 188 assertEquals(0, authsList.size()); 189 } 190 191 @Test (timeout=180000) testPassiveVisibility()192 public void testPassiveVisibility() throws Exception { 193 // No values should be filtered regardless of authorization if we are passive 194 try (Table t = createTableAndWriteDataWithLabels( 195 TableName.valueOf(TEST_NAME.getMethodName()), 196 SECRET, 197 PRIVATE, 198 SECRET + "|" + CONFIDENTIAL, 199 PRIVATE + "|" + CONFIDENTIAL)) { 200 Scan s = new Scan(); 201 s.setAuthorizations(new Authorizations()); 202 try (ResultScanner scanner = t.getScanner(s)) { 203 Result[] next = scanner.next(10); 204 assertEquals(next.length, 4); 205 } 206 s = new Scan(); 207 s.setAuthorizations(new Authorizations(SECRET)); 208 try (ResultScanner scanner = t.getScanner(s)) { 209 Result[] next = scanner.next(10); 210 assertEquals(next.length, 4); 211 } 212 s = new Scan(); 213 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL)); 214 try (ResultScanner scanner = t.getScanner(s)) { 215 Result[] next = scanner.next(10); 216 assertEquals(next.length, 4); 217 } 218 s = new Scan(); 219 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE)); 220 try (ResultScanner scanner = t.getScanner(s)) { 221 Result[] next = scanner.next(10); 222 assertEquals(next.length, 4); 223 } 224 } 225 } 226 createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)227 static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps) 228 throws Exception { 229 List<Put> puts = new ArrayList<Put>(); 230 for (int i = 0; i < labelExps.length; i++) { 231 Put put = new Put(Bytes.toBytes("row" + (i+1))); 232 put.addColumn(TEST_FAMILY, TEST_QUALIFIER, HConstants.LATEST_TIMESTAMP, ZERO); 233 put.setCellVisibility(new CellVisibility(labelExps[i])); 234 puts.add(put); 235 } 236 Table table = TEST_UTIL.createTable(tableName, TEST_FAMILY); 237 table.put(puts); 238 return table; 239 } 240 } 241