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