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.jupiter.api.Assertions.assertNotNull;
022import static org.junit.jupiter.api.Assertions.assertNull;
023
024import java.io.IOException;
025import java.security.PrivilegedExceptionAction;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.hadoop.hbase.HBaseTestingUtil;
028import org.apache.hadoop.hbase.HConstants;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.client.Connection;
031import org.apache.hadoop.hbase.client.ConnectionFactory;
032import org.apache.hadoop.hbase.client.Put;
033import org.apache.hadoop.hbase.client.Result;
034import org.apache.hadoop.hbase.client.ResultScanner;
035import org.apache.hadoop.hbase.client.Scan;
036import org.apache.hadoop.hbase.client.Table;
037import org.apache.hadoop.hbase.security.User;
038import org.apache.hadoop.hbase.testclassification.MediumTests;
039import org.apache.hadoop.hbase.testclassification.SecurityTests;
040import org.apache.hadoop.hbase.util.Bytes;
041import org.junit.jupiter.api.AfterAll;
042import org.junit.jupiter.api.BeforeAll;
043import org.junit.jupiter.api.Tag;
044import org.junit.jupiter.api.Test;
045import org.junit.jupiter.api.TestInfo;
046
047import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
048
049@Tag(SecurityTests.TAG)
050@Tag(MediumTests.TAG)
051public class TestVisibilityLabelsWithSLGStack {
052
053  public static final String CONFIDENTIAL = "confidential";
054  private static final String SECRET = "secret";
055  public static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
056  private static final byte[] ROW_1 = Bytes.toBytes("row1");
057  private final static byte[] CF = Bytes.toBytes("f");
058  private final static byte[] Q1 = Bytes.toBytes("q1");
059  private final static byte[] Q2 = Bytes.toBytes("q2");
060  private final static byte[] value = Bytes.toBytes("value");
061  public static Configuration conf;
062
063  public static User SUPERUSER;
064
065  @BeforeAll
066  public static void setupBeforeClass() throws Exception {
067    // setup configuration
068    conf = TEST_UTIL.getConfiguration();
069    VisibilityTestUtil.enableVisiblityLabels(conf);
070    String classes = SimpleScanLabelGenerator.class.getCanonicalName() + " , "
071      + LabelFilteringScanLabelGenerator.class.getCanonicalName();
072    conf.setStrings(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, classes);
073    conf.set("hbase.superuser", "admin");
074    TEST_UTIL.startMiniCluster(1);
075    SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
076
077    // Wait for the labels table to become available
078    TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
079    addLabels();
080  }
081
082  @Test
083  public void testWithSAGStack(TestInfo testInfo) throws Exception {
084    TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());
085    try (Table table = TEST_UTIL.createTable(tableName, CF)) {
086      Put put = new Put(ROW_1);
087      put.addColumn(CF, Q1, HConstants.LATEST_TIMESTAMP, value);
088      put.setCellVisibility(new CellVisibility(SECRET));
089      table.put(put);
090      put = new Put(ROW_1);
091      put.addColumn(CF, Q2, HConstants.LATEST_TIMESTAMP, value);
092      put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
093      table.put(put);
094
095      LabelFilteringScanLabelGenerator.labelToFilter = CONFIDENTIAL;
096      Scan s = new Scan();
097      s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
098      ResultScanner scanner = table.getScanner(s);
099      Result next = scanner.next();
100      assertNotNull(next.getColumnLatestCell(CF, Q1));
101      assertNull(next.getColumnLatestCell(CF, Q2));
102    }
103  }
104
105  private static void addLabels() throws Exception {
106    PrivilegedExceptionAction<VisibilityLabelsResponse> action =
107      new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
108        @Override
109        public VisibilityLabelsResponse run() throws Exception {
110          String[] labels = { SECRET, CONFIDENTIAL };
111          try (Connection conn = ConnectionFactory.createConnection(conf)) {
112            VisibilityClient.addLabels(conn, labels);
113          } catch (Throwable t) {
114            throw new IOException(t);
115          }
116          return null;
117        }
118      };
119    SUPERUSER.runAs(action);
120  }
121
122  @AfterAll
123  public static void tearDownAfterClass() throws Exception {
124    TEST_UTIL.shutdownMiniCluster();
125  }
126}