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