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