View Javadoc

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.assertFalse;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.io.IOException;
25  import java.security.PrivilegedExceptionAction;
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.testclassification.MediumTests;
31  import org.apache.hadoop.hbase.TableName;
32  import org.apache.hadoop.hbase.client.Connection;
33  import org.apache.hadoop.hbase.client.ConnectionFactory;
34  import org.apache.hadoop.hbase.client.Get;
35  import org.apache.hadoop.hbase.client.HTable;
36  import org.apache.hadoop.hbase.client.Put;
37  import org.apache.hadoop.hbase.client.Result;
38  import org.apache.hadoop.hbase.client.Table;
39  import org.apache.hadoop.hbase.security.User;
40  import org.apache.hadoop.hbase.util.Bytes;
41  import org.junit.AfterClass;
42  import org.junit.BeforeClass;
43  import org.junit.Rule;
44  import org.junit.Test;
45  import org.junit.experimental.categories.Category;
46  import org.junit.rules.TestName;
47  
48  @Category(MediumTests.class)
49  public class TestEnforcingScanLabelGenerator {
50  
51    public static final String CONFIDENTIAL = "confidential";
52    private static final String SECRET = "secret";
53    public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
54    private static final byte[] ROW_1 = Bytes.toBytes("row1");
55    private final static byte[] CF = Bytes.toBytes("f");
56    private final static byte[] Q1 = Bytes.toBytes("q1");
57    private final static byte[] Q2 = Bytes.toBytes("q2");
58    private final static byte[] Q3 = Bytes.toBytes("q3");
59    private final static byte[] value = Bytes.toBytes("value");
60    public static Configuration conf;
61  
62    @Rule
63    public final TestName TEST_NAME = new TestName();
64    public static User SUPERUSER;
65    public static User TESTUSER;
66  
67    @BeforeClass
68    public static void setupBeforeClass() throws Exception {
69      // setup configuration
70      conf = TEST_UTIL.getConfiguration();
71      VisibilityTestUtil.enableVisiblityLabels(conf);
72      String classes = DefinedSetFilterScanLabelGenerator.class.getCanonicalName() + " , "
73          + EnforcingScanLabelGenerator.class.getCanonicalName();
74      conf.setStrings(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, classes);
75      conf.set("hbase.superuser", "admin");
76      TEST_UTIL.startMiniCluster(1);
77      SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
78      TESTUSER = User.createUserForTesting(conf, "test", new String[] { });
79  
80      // Wait for the labels table to become available
81      TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
82  
83      // Set up for the test
84      SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
85        public Void run() throws Exception {
86          try {
87            VisibilityClient.addLabels(conf, new String[] { SECRET, CONFIDENTIAL });
88            VisibilityClient.setAuths(conf, new String[] { CONFIDENTIAL, }, TESTUSER.getShortName());
89          } catch (Throwable t) {
90            throw new IOException(t);
91          }
92          return null;
93        }
94      });
95    }
96  
97    @Test
98    public void testEnforcingScanLabelGenerator() throws Exception {
99      final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
100 
101     SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
102       public Void run() throws Exception {
103         try (Connection connection = ConnectionFactory.createConnection(conf);
104              Table table = TEST_UTIL.createTable(tableName, CF)) {
105           Put put = new Put(ROW_1);
106           put.add(CF, Q1, HConstants.LATEST_TIMESTAMP, value);
107           put.setCellVisibility(new CellVisibility(SECRET));
108           table.put(put);
109           put = new Put(ROW_1);
110           put.add(CF, Q2, HConstants.LATEST_TIMESTAMP, value);
111           put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
112           table.put(put);
113           put = new Put(ROW_1);
114           put.add(CF, Q3, HConstants.LATEST_TIMESTAMP, value);
115           table.put(put);
116           return null;
117         }
118       }
119     });
120 
121     // Test that super user can see all the cells.
122     SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
123       public Void run() throws Exception {
124         try (Connection connection = ConnectionFactory.createConnection(conf);
125              Table table = connection.getTable(tableName)) {
126           // Test that super user can see all the cells.
127           Get get = new Get(ROW_1);
128           Result result = table.get(get);
129           assertTrue("Missing authorization", result.containsColumn(CF, Q1));
130           assertTrue("Missing authorization", result.containsColumn(CF, Q2));
131           assertTrue("Missing authorization", result.containsColumn(CF, Q3));
132           return null;
133         }
134       }
135     });
136 
137     TESTUSER.runAs(new PrivilegedExceptionAction<Void>() {
138       public Void run() throws Exception {
139         try (Connection connection = ConnectionFactory.createConnection(conf);
140              Table table = connection.getTable(tableName)) {
141           // Test that we enforce the defined set
142           Get get = new Get(ROW_1);
143           get.setAuthorizations(new Authorizations(new String[] { SECRET, CONFIDENTIAL }));
144           Result result = table.get(get);
145           assertFalse("Inappropriate authorization", result.containsColumn(CF, Q1));
146           assertTrue("Missing authorization", result.containsColumn(CF, Q2));
147           assertTrue("Inappropriate filtering", result.containsColumn(CF, Q3));
148           // Test that we also enforce the defined set for the user if no auths are provided
149           get = new Get(ROW_1);
150           result = table.get(get);
151           assertFalse("Inappropriate authorization", result.containsColumn(CF, Q1));
152           assertTrue("Missing authorization", result.containsColumn(CF, Q2));
153           assertTrue("Inappropriate filtering", result.containsColumn(CF, Q3));
154           return null;
155         }
156       }
157     });
158 
159   }
160 
161   @AfterClass
162   public static void tearDownAfterClass() throws Exception {
163     TEST_UTIL.shutdownMiniCluster();
164   }
165 }