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.assertTrue;
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.HColumnDescriptor;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.HTableDescriptor;
31  import org.apache.hadoop.hbase.testclassification.MediumTests;
32  import org.apache.hadoop.hbase.TableName;
33  import org.apache.hadoop.hbase.client.Admin;
34  import org.apache.hadoop.hbase.client.Append;
35  import org.apache.hadoop.hbase.client.HTable;
36  import org.apache.hadoop.hbase.client.Put;
37  import org.apache.hadoop.hbase.client.Table;
38  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
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.Assert;
43  import org.junit.BeforeClass;
44  import org.junit.Rule;
45  import org.junit.Test;
46  import org.junit.experimental.categories.Category;
47  import org.junit.rules.TestName;
48  
49  @Category(MediumTests.class)
50  /**
51   * Test visibility by setting 'hbase.security.visibility.mutations.checkauths' to true
52   */
53  public class TestVisibilityWithCheckAuths {
54    private static final String TOPSECRET = "TOPSECRET";
55    private static final String PUBLIC = "PUBLIC";
56    public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
57    private static final byte[] row1 = Bytes.toBytes("row1");
58    private final static byte[] fam = Bytes.toBytes("info");
59    private final static byte[] qual = Bytes.toBytes("qual");
60    private final static byte[] value = Bytes.toBytes("value");
61    public static Configuration conf;
62  
63    @Rule
64    public final TestName TEST_NAME = new TestName();
65    public static User SUPERUSER;
66    public static User USER;
67    @BeforeClass
68    public static void setupBeforeClass() throws Exception {
69      // setup configuration
70      conf = TEST_UTIL.getConfiguration();
71      conf.setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
72      VisibilityTestUtil.enableVisiblityLabels(conf);
73      conf.setBoolean(VisibilityConstants.CHECK_AUTHS_FOR_MUTATION, true);
74      conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
75          ScanLabelGenerator.class);
76      conf.set("hbase.superuser", "admin");
77      TEST_UTIL.startMiniCluster(2);
78      SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
79      USER = User.createUserForTesting(conf, "user", new String[]{});
80      // Wait for the labels table to become available
81      TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
82      addLabels();
83    }
84  
85    @AfterClass
86    public static void tearDownAfterClass() throws Exception {
87      TEST_UTIL.shutdownMiniCluster();
88    }
89  
90    public static void addLabels() throws Exception {
91      PrivilegedExceptionAction<VisibilityLabelsResponse> action =
92          new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
93        @Override
94        public VisibilityLabelsResponse run() throws Exception {
95          String[] labels = { TOPSECRET };
96          try {
97            VisibilityClient.addLabels(conf, labels);
98          } catch (Throwable t) {
99            throw new IOException(t);
100         }
101         return null;
102       }
103     };
104     SUPERUSER.runAs(action);
105   }
106 
107   @Test
108   public void testVerifyAccessDeniedForInvalidUserAuths() throws Exception {
109     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
110         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
111       @Override
112       public VisibilityLabelsResponse run() throws Exception {
113         try {
114           return VisibilityClient.setAuths(conf, new String[] { TOPSECRET },
115               USER.getShortName());
116         } catch (Throwable e) {
117         }
118         return null;
119       }
120     };
121     SUPERUSER.runAs(action);
122     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
123     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
124     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
125     colDesc.setMaxVersions(5);
126     HTableDescriptor desc = new HTableDescriptor(tableName);
127     desc.addFamily(colDesc);
128     hBaseAdmin.createTable(desc);
129     Table table = null;
130     try {
131       TEST_UTIL.getHBaseAdmin().flush(tableName);
132       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
133         @Override
134         public Void run() throws Exception {
135           Table table = null;
136           try {
137             table = new HTable(conf, tableName);
138             Put p = new Put(row1);
139             p.setCellVisibility(new CellVisibility(PUBLIC + "&" + TOPSECRET));
140             p.add(fam, qual, 125l, value);
141             table.put(p);
142             Assert.fail("Testcase should fail with AccesDeniedException");
143           } catch (Throwable t) {
144             assertTrue(t.getMessage().contains("AccessDeniedException"));
145           } finally {
146             table.close();
147           }
148           return null;
149         }
150       };
151       USER.runAs(actiona);
152     } catch (Exception e) {
153       throw new IOException(e);
154     }
155   }
156 
157   @Test
158   public void testLabelsWithAppend() throws Throwable {
159     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
160         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
161       @Override
162       public VisibilityLabelsResponse run() throws Exception {
163         try {
164           return VisibilityClient.setAuths(conf, new String[] { TOPSECRET },
165               USER.getShortName());
166         } catch (Throwable e) {
167         }
168         return null;
169       }
170     };
171     SUPERUSER.runAs(action);
172     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
173     Table table = null;
174     try {
175       table = TEST_UTIL.createTable(tableName, fam);
176       final byte[] row1 = Bytes.toBytes("row1");
177       final byte[] val = Bytes.toBytes("a");
178       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
179         @Override
180         public Void run() throws Exception {
181           Table table = null;
182           try {
183             table = new HTable(conf, tableName);
184             Put put = new Put(row1);
185             put.add(fam, qual, HConstants.LATEST_TIMESTAMP, val);
186             put.setCellVisibility(new CellVisibility(TOPSECRET));
187             table.put(put);
188           } finally {
189             table.close();
190           }
191           return null;
192         }
193       };
194       USER.runAs(actiona);
195       actiona = new PrivilegedExceptionAction<Void>() {
196         @Override
197         public Void run() throws Exception {
198           Table table = null;
199           try {
200             table = new HTable(conf, tableName);
201             Append append = new Append(row1);
202             append.add(fam, qual, Bytes.toBytes("b"));
203             table.append(append);
204           } finally {
205             table.close();
206           }
207           return null;
208         }
209       };
210       USER.runAs(actiona);
211       actiona = new PrivilegedExceptionAction<Void>() {
212         @Override
213         public Void run() throws Exception {
214           Table table = null;
215           try {
216             table = new HTable(conf, tableName);
217             Append append = new Append(row1);
218             append.add(fam, qual, Bytes.toBytes("c"));
219             append.setCellVisibility(new CellVisibility(PUBLIC));
220             table.append(append);
221             Assert.fail("Testcase should fail with AccesDeniedException");
222           } catch (Throwable t) {
223             assertTrue(t.getMessage().contains("AccessDeniedException"));
224           } finally {
225             table.close();
226           }
227           return null;
228         }
229       };
230       USER.runAs(actiona);
231     } finally {
232       if (table != null) {
233         table.close();
234       }
235     }
236   }
237 }