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.assertEquals;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.io.IOException;
25  import java.security.PrivilegedExceptionAction;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.apache.hadoop.conf.Configuration;
30  import org.apache.hadoop.hbase.HBaseTestingUtility;
31  import org.apache.hadoop.hbase.testclassification.MediumTests;
32  import org.apache.hadoop.hbase.client.Connection;
33  import org.apache.hadoop.hbase.client.ConnectionFactory;
34  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
35  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
36  import org.apache.hadoop.hbase.security.User;
37  import org.apache.hadoop.hbase.util.Bytes;
38  import org.junit.AfterClass;
39  import org.junit.BeforeClass;
40  import org.junit.Rule;
41  import org.junit.Test;
42  import org.junit.experimental.categories.Category;
43  import org.junit.rules.TestName;
44  
45  import com.google.protobuf.ByteString;
46  
47  @Category(MediumTests.class)
48  public class TestVisibilityLabelsOpWithDifferentUsersNoACL {
49    private static final String PRIVATE = "private";
50    private static final String CONFIDENTIAL = "confidential";
51    private static final String SECRET = "secret";
52    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
53    private static Configuration conf;
54  
55    @Rule
56    public final TestName TEST_NAME = new TestName();
57    private static User SUPERUSER;
58    private static User NORMAL_USER;
59    private static User NORMAL_USER1;
60  
61    @BeforeClass
62    public static void setupBeforeClass() throws Exception {
63      // setup configuration
64      conf = TEST_UTIL.getConfiguration();
65      VisibilityTestUtil.enableVisiblityLabels(conf);
66      String currentUser = User.getCurrent().getName();
67      conf.set("hbase.superuser", "admin,"+currentUser);
68      TEST_UTIL.startMiniCluster(2);
69  
70      // Wait for the labels table to become available
71      TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
72      SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
73      NORMAL_USER = User.createUserForTesting(conf, "user1", new String[] {});
74      NORMAL_USER1 = User.createUserForTesting(conf, "user2", new String[] {});
75      addLabels();
76    }
77  
78    @AfterClass
79    public static void tearDownAfterClass() throws Exception {
80      TEST_UTIL.shutdownMiniCluster();
81    }
82  
83    @Test
84    public void testLabelsTableOpsWithDifferentUsers() throws Throwable {
85      PrivilegedExceptionAction<VisibilityLabelsResponse> action =
86          new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
87        public VisibilityLabelsResponse run() throws Exception {
88          try (Connection conn = ConnectionFactory.createConnection(conf)) {
89            return VisibilityClient.setAuths(conn, new String[] { CONFIDENTIAL, PRIVATE }, "user1");
90          } catch (Throwable e) {
91          }
92          return null;
93        }
94      };
95      VisibilityLabelsResponse response = SUPERUSER.runAs(action);
96      assertTrue(response.getResult(0).getException().getValue().isEmpty());
97      assertTrue(response.getResult(1).getException().getValue().isEmpty());
98      
99      // Ideally this should not be allowed.  this operation should fail or do nothing.
100     action = new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
101       public VisibilityLabelsResponse run() throws Exception {
102         try (Connection conn = ConnectionFactory.createConnection(conf)) {
103           return VisibilityClient.setAuths(conn, new String[] { CONFIDENTIAL, PRIVATE }, "user3");
104         } catch (Throwable e) {
105         }
106         return null;
107       }
108     };
109     response = NORMAL_USER1.runAs(action);
110     assertEquals("org.apache.hadoop.hbase.security.AccessDeniedException", response
111         .getResult(0).getException().getName());
112     assertEquals("org.apache.hadoop.hbase.security.AccessDeniedException", response
113         .getResult(1).getException().getName());
114 
115     PrivilegedExceptionAction<GetAuthsResponse> action1 =
116         new PrivilegedExceptionAction<GetAuthsResponse>() {
117       public GetAuthsResponse run() throws Exception {
118         try (Connection conn = ConnectionFactory.createConnection(conf)) {
119           return VisibilityClient.getAuths(conn, "user1");
120         } catch (Throwable e) {
121         }
122         return null;
123       }
124     };
125     GetAuthsResponse authsResponse = NORMAL_USER.runAs(action1);
126     assertTrue(authsResponse.getAuthList().isEmpty());
127     authsResponse = NORMAL_USER1.runAs(action1);
128     assertTrue(authsResponse.getAuthList().isEmpty());
129     authsResponse = SUPERUSER.runAs(action1);
130     List<String> authsList = new ArrayList<String>();
131     for (ByteString authBS : authsResponse.getAuthList()) {
132       authsList.add(Bytes.toString(authBS.toByteArray()));
133     }
134     assertEquals(2, authsList.size());
135     assertTrue(authsList.contains(CONFIDENTIAL));
136     assertTrue(authsList.contains(PRIVATE));
137 
138     PrivilegedExceptionAction<VisibilityLabelsResponse> action2 = 
139         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
140       public VisibilityLabelsResponse run() throws Exception {
141         try (Connection conn = ConnectionFactory.createConnection(conf)) {
142           return VisibilityClient.clearAuths(conn, new String[] {
143               CONFIDENTIAL, PRIVATE }, "user1");
144         } catch (Throwable e) {
145         }
146         return null;
147       }
148     };
149     response = NORMAL_USER1.runAs(action2);
150     assertEquals("org.apache.hadoop.hbase.security.AccessDeniedException", response
151         .getResult(0).getException().getName());
152     assertEquals("org.apache.hadoop.hbase.security.AccessDeniedException", response
153         .getResult(1).getException().getName());
154     response = SUPERUSER.runAs(action2);
155     assertTrue(response.getResult(0).getException().getValue().isEmpty());
156     assertTrue(response.getResult(1).getException().getValue().isEmpty());
157     authsResponse = SUPERUSER.runAs(action1);
158     assertTrue(authsResponse.getAuthList().isEmpty());
159   }
160 
161   private static void addLabels() throws Exception {
162     PrivilegedExceptionAction<VisibilityLabelsResponse> action = 
163         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
164       public VisibilityLabelsResponse run() throws Exception {
165         String[] labels = { SECRET, CONFIDENTIAL, PRIVATE };
166         try (Connection conn = ConnectionFactory.createConnection(conf)) {
167           VisibilityClient.addLabels(conn, labels);
168         } catch (Throwable t) {
169           throw new IOException(t);
170         }
171         return null;
172       }
173     };
174     SUPERUSER.runAs(action);
175   }
176 }