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.security.PrivilegedExceptionAction;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.hbase.HBaseTestingUtility;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.TableName;
31  import org.apache.hadoop.hbase.client.Put;
32  import org.apache.hadoop.hbase.client.Result;
33  import org.apache.hadoop.hbase.client.ResultScanner;
34  import org.apache.hadoop.hbase.client.Scan;
35  import org.apache.hadoop.hbase.client.Table;
36  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
37  import org.apache.hadoop.hbase.security.User;
38  import org.apache.hadoop.hbase.security.access.SecureTestUtil;
39  import org.apache.hadoop.hbase.testclassification.LargeTests;
40  import org.apache.hadoop.hbase.util.Bytes;
41  import org.junit.AfterClass;
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  import com.google.protobuf.ByteString;
49  
50  @Category(LargeTests.class)
51  public class TestWithDisabledAuthorization {
52  
53    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
54    
55    private static final String CONFIDENTIAL = "confidential";
56    private static final String SECRET = "secret";
57    private static final String PRIVATE = "private";
58    private static final byte[] TEST_FAMILY = Bytes.toBytes("test");
59    private static final byte[] TEST_QUALIFIER = Bytes.toBytes("q");
60    private static final byte[] ZERO = Bytes.toBytes(0L);
61  
62  
63    @Rule 
64    public final TestName TEST_NAME = new TestName();
65  
66    private static User SUPERUSER;
67    private static User USER_RW;
68  
69    @BeforeClass
70    public static void setUpBeforeClass() throws Exception {
71      Configuration conf = TEST_UTIL.getConfiguration();
72  
73      // Set up superuser
74      SecureTestUtil.configureSuperuser(conf);
75  
76      // Install the VisibilityController as a system processor
77      VisibilityTestUtil.enableVisiblityLabels(conf);
78  
79      // Now, DISABLE active authorization
80      conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false);
81  
82      TEST_UTIL.startMiniCluster();
83  
84      // Wait for the labels table to become available
85      TEST_UTIL.waitUntilAllRegionsAssigned(LABELS_TABLE_NAME);
86  
87      // create a set of test users
88      SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
89      USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
90  
91      // Define test labels
92      SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
93        public Void run() throws Exception {
94          try {
95            VisibilityClient.addLabels(TEST_UTIL.getConfiguration(),
96              new String[] { SECRET, CONFIDENTIAL, PRIVATE });
97            VisibilityClient.setAuths(TEST_UTIL.getConfiguration(),
98              new String[] { SECRET, CONFIDENTIAL },
99              USER_RW.getShortName());
100         } catch (Throwable t) {
101           fail("Should not have failed");          
102         }
103         return null;
104       }
105     });
106   }
107 
108   @AfterClass
109   public static void tearDownAfterClass() throws Exception {
110     TEST_UTIL.shutdownMiniCluster();
111   }
112 
113   @Test
114   public void testManageUserAuths() throws Throwable {
115     // Even though authorization is disabled, we should be able to manage user auths
116 
117     SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
118       public Void run() throws Exception {
119         try {
120           VisibilityClient.setAuths(TEST_UTIL.getConfiguration(),
121             new String[] { SECRET, CONFIDENTIAL },
122             USER_RW.getShortName());
123         } catch (Throwable t) {
124           fail("Should not have failed");          
125         }
126         return null;
127       }
128     });
129 
130     PrivilegedExceptionAction<List<String>> getAuths =
131       new PrivilegedExceptionAction<List<String>>() {
132         public List<String> run() throws Exception {
133           GetAuthsResponse authsResponse = null;
134           try {
135             authsResponse = VisibilityClient.getAuths(TEST_UTIL.getConfiguration(),
136               USER_RW.getShortName());
137           } catch (Throwable t) {
138             fail("Should not have failed");
139           }
140           List<String> authsList = new ArrayList<String>();
141           for (ByteString authBS : authsResponse.getAuthList()) {
142             authsList.add(Bytes.toString(authBS.toByteArray()));
143           }
144           return authsList;
145         }
146       };
147 
148     List<String> authsList = SUPERUSER.runAs(getAuths);
149     assertEquals(2, authsList.size());
150     assertTrue(authsList.contains(SECRET));
151     assertTrue(authsList.contains(CONFIDENTIAL));
152 
153     SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
154       public Void run() throws Exception {
155         try {
156           VisibilityClient.clearAuths(TEST_UTIL.getConfiguration(),
157             new String[] { SECRET },
158             USER_RW.getShortName());
159         } catch (Throwable t) {
160           fail("Should not have failed");          
161         }
162         return null;
163       }
164     });
165 
166     authsList = SUPERUSER.runAs(getAuths);
167     assertEquals(1, authsList.size());
168     assertTrue(authsList.contains(CONFIDENTIAL));
169 
170     SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
171       public Void run() throws Exception {
172         try {
173           VisibilityClient.clearAuths(TEST_UTIL.getConfiguration(),
174             new String[] { CONFIDENTIAL },
175             USER_RW.getShortName());
176         } catch (Throwable t) {
177           fail("Should not have failed");          
178         }
179         return null;
180       }
181     });
182 
183     authsList = SUPERUSER.runAs(getAuths);
184     assertEquals(0, authsList.size());
185   }
186 
187   @Test
188   public void testPassiveVisibility() throws Exception {
189     // No values should be filtered regardless of authorization if we are passive
190     try (Table t = createTableAndWriteDataWithLabels(
191       TableName.valueOf(TEST_NAME.getMethodName()),
192         SECRET,
193         PRIVATE,
194         SECRET + "|" + CONFIDENTIAL,
195         PRIVATE + "|" + CONFIDENTIAL)) {
196       Scan s = new Scan();
197       s.setAuthorizations(new Authorizations());
198       try (ResultScanner scanner = t.getScanner(s)) {
199         Result[] next = scanner.next(10);
200         assertEquals(next.length, 4);
201       }
202       s = new Scan();
203       s.setAuthorizations(new Authorizations(SECRET));
204       try (ResultScanner scanner = t.getScanner(s)) {
205         Result[] next = scanner.next(10);
206         assertEquals(next.length, 4);
207       }
208       s = new Scan();
209       s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
210       try (ResultScanner scanner = t.getScanner(s)) {
211         Result[] next = scanner.next(10);
212         assertEquals(next.length, 4);
213       }
214       s = new Scan();
215       s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE));
216       try (ResultScanner scanner = t.getScanner(s)) {
217         Result[] next = scanner.next(10);
218         assertEquals(next.length, 4);
219       }
220     }
221   }
222 
223   static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
224       throws Exception {
225     List<Put> puts = new ArrayList<Put>();
226     for (int i = 0; i < labelExps.length; i++) {
227       Put put = new Put(Bytes.toBytes("row" + (i+1)));
228       put.addColumn(TEST_FAMILY, TEST_QUALIFIER, HConstants.LATEST_TIMESTAMP, ZERO);
229       put.setCellVisibility(new CellVisibility(labelExps[i]));
230       puts.add(put);
231     }
232     Table table = TEST_UTIL.createTable(tableName, TEST_FAMILY);
233     table.put(puts);
234     return table;
235   }
236 }