001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.security.visibility;
019
020import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
021import static org.junit.Assert.assertNotNull;
022import static org.junit.Assert.assertNull;
023
024import java.io.IOException;
025import java.security.PrivilegedExceptionAction;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.hadoop.hbase.HBaseClassTestRule;
028import org.apache.hadoop.hbase.HBaseTestingUtility;
029import org.apache.hadoop.hbase.HConstants;
030import org.apache.hadoop.hbase.TableName;
031import org.apache.hadoop.hbase.client.Connection;
032import org.apache.hadoop.hbase.client.ConnectionFactory;
033import org.apache.hadoop.hbase.client.Put;
034import org.apache.hadoop.hbase.client.Result;
035import org.apache.hadoop.hbase.client.ResultScanner;
036import org.apache.hadoop.hbase.client.Scan;
037import org.apache.hadoop.hbase.client.Table;
038import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
039import org.apache.hadoop.hbase.security.User;
040import org.apache.hadoop.hbase.testclassification.MediumTests;
041import org.apache.hadoop.hbase.testclassification.SecurityTests;
042import org.apache.hadoop.hbase.util.Bytes;
043import org.junit.AfterClass;
044import org.junit.BeforeClass;
045import org.junit.ClassRule;
046import org.junit.Rule;
047import org.junit.Test;
048import org.junit.experimental.categories.Category;
049import org.junit.rules.TestName;
050
051@Category({ SecurityTests.class, MediumTests.class })
052public class TestVisibilityLabelsWithSLGStack {
053
054  @ClassRule
055  public static final HBaseClassTestRule CLASS_RULE =
056    HBaseClassTestRule.forClass(TestVisibilityLabelsWithSLGStack.class);
057
058  public static final String CONFIDENTIAL = "confidential";
059  private static final String SECRET = "secret";
060  public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
061  private static final byte[] ROW_1 = Bytes.toBytes("row1");
062  private final static byte[] CF = Bytes.toBytes("f");
063  private final static byte[] Q1 = Bytes.toBytes("q1");
064  private final static byte[] Q2 = Bytes.toBytes("q2");
065  private final static byte[] value = Bytes.toBytes("value");
066  public static Configuration conf;
067
068  @Rule
069  public final TestName TEST_NAME = new TestName();
070  public static User SUPERUSER;
071
072  @BeforeClass
073  public static void setupBeforeClass() throws Exception {
074    // setup configuration
075    conf = TEST_UTIL.getConfiguration();
076    VisibilityTestUtil.enableVisiblityLabels(conf);
077    String classes = SimpleScanLabelGenerator.class.getCanonicalName() + " , "
078      + LabelFilteringScanLabelGenerator.class.getCanonicalName();
079    conf.setStrings(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, classes);
080    conf.set("hbase.superuser", "admin");
081    TEST_UTIL.startMiniCluster(1);
082    SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
083
084    // Wait for the labels table to become available
085    TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
086    addLabels();
087  }
088
089  @Test
090  public void testWithSAGStack() throws Exception {
091    TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
092    try (Table table = TEST_UTIL.createTable(tableName, CF)) {
093      Put put = new Put(ROW_1);
094      put.addColumn(CF, Q1, HConstants.LATEST_TIMESTAMP, value);
095      put.setCellVisibility(new CellVisibility(SECRET));
096      table.put(put);
097      put = new Put(ROW_1);
098      put.addColumn(CF, Q2, HConstants.LATEST_TIMESTAMP, value);
099      put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
100      table.put(put);
101
102      LabelFilteringScanLabelGenerator.labelToFilter = CONFIDENTIAL;
103      Scan s = new Scan();
104      s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
105      ResultScanner scanner = table.getScanner(s);
106      Result next = scanner.next();
107      assertNotNull(next.getColumnLatestCell(CF, Q1));
108      assertNull(next.getColumnLatestCell(CF, Q2));
109    }
110  }
111
112  private static void addLabels() throws Exception {
113    PrivilegedExceptionAction<VisibilityLabelsResponse> action =
114      new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
115        @Override
116        public VisibilityLabelsResponse run() throws Exception {
117          String[] labels = { SECRET, CONFIDENTIAL };
118          try (Connection conn = ConnectionFactory.createConnection(conf)) {
119            VisibilityClient.addLabels(conn, labels);
120          } catch (Throwable t) {
121            throw new IOException(t);
122          }
123          return null;
124        }
125      };
126    SUPERUSER.runAs(action);
127  }
128
129  @AfterClass
130  public static void tearDownAfterClass() throws Exception {
131    TEST_UTIL.shutdownMiniCluster();
132  }
133}