1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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.apache.hadoop.hbase.security.visibility.VisibilityUtils.SYSTEM_LABEL;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.fail;
26
27 import java.io.IOException;
28 import java.security.PrivilegedExceptionAction;
29 import java.util.List;
30 import java.util.concurrent.atomic.AtomicBoolean;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.testclassification.MediumTests;
37 import org.apache.hadoop.hbase.client.Result;
38 import org.apache.hadoop.hbase.client.ResultScanner;
39 import org.apache.hadoop.hbase.client.Scan;
40 import org.apache.hadoop.hbase.client.Table;
41 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
42 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
43 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameBytesPair;
44 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.ListLabelsResponse;
45 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
46 import org.apache.hadoop.hbase.security.User;
47 import org.apache.hadoop.hbase.util.Bytes;
48 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
49 import org.apache.hadoop.hbase.util.Threads;
50 import org.junit.Assert;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.junit.experimental.categories.Category;
54 import com.google.protobuf.ByteString;
55
56 @Category(MediumTests.class)
57 public class TestVisibilityLabelsWithDefaultVisLabelService extends TestVisibilityLabels {
58 final Log LOG = LogFactory.getLog(getClass());
59
60 @BeforeClass
61 public static void setupBeforeClass() throws Exception {
62
63 conf = TEST_UTIL.getConfiguration();
64 conf.setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
65 conf.setBoolean("hbase.online.schema.update.enable", true);
66 VisibilityTestUtil.enableVisiblityLabels(conf);
67 conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
68 ScanLabelGenerator.class);
69 conf.set("hbase.superuser", "admin");
70 TEST_UTIL.startMiniCluster(2);
71 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
72 USER1 = User.createUserForTesting(conf, "user1", new String[] {});
73
74
75 TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
76 addLabels();
77 }
78
79 @Test
80 public void testAddLabels() throws Throwable {
81 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
82 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
83 public VisibilityLabelsResponse run() throws Exception {
84 String[] labels = { "L1", SECRET, "L2", "invalid~", "L3" };
85 VisibilityLabelsResponse response = null;
86 try {
87 response = VisibilityClient.addLabels(conf, labels);
88 } catch (Throwable e) {
89 fail("Should not have thrown exception");
90 }
91 List<RegionActionResult> resultList = response.getResultList();
92 assertEquals(5, resultList.size());
93 assertTrue(resultList.get(0).getException().getValue().isEmpty());
94 assertEquals("org.apache.hadoop.hbase.DoNotRetryIOException", resultList.get(1)
95 .getException().getName());
96 assertTrue(Bytes.toString(resultList.get(1).getException().getValue().toByteArray())
97 .contains(
98 "org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException: "
99 + "Label 'secret' already exists"));
100 assertTrue(resultList.get(2).getException().getValue().isEmpty());
101 assertTrue(resultList.get(3).getException().getValue().isEmpty());
102 assertTrue(resultList.get(4).getException().getValue().isEmpty());
103 return null;
104 }
105 };
106 SUPERUSER.runAs(action);
107 }
108
109 @Test(timeout = 60 * 1000)
110 public void testAddVisibilityLabelsOnRSRestart() throws Exception {
111 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
112 .getRegionServerThreads();
113 for (RegionServerThread rsThread : regionServerThreads) {
114 rsThread.getRegionServer().abort("Aborting ");
115 }
116
117 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
118 waitForLabelsRegionAvailability(rs.getRegionServer());
119 final AtomicBoolean vcInitialized = new AtomicBoolean(true);
120 do {
121 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
122 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
123 public VisibilityLabelsResponse run() throws Exception {
124 String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, "ABC", "XYZ" };
125 try {
126 VisibilityLabelsResponse resp = VisibilityClient.addLabels(conf, labels);
127 List<RegionActionResult> results = resp.getResultList();
128 if (results.get(0).hasException()) {
129 NameBytesPair pair = results.get(0).getException();
130 Throwable t = ProtobufUtil.toException(pair);
131 LOG.debug("Got exception writing labels", t);
132 if (t instanceof VisibilityControllerNotReadyException) {
133 vcInitialized.set(false);
134 LOG.warn("VisibilityController was not yet initialized");
135 Threads.sleep(10);
136 } else {
137 vcInitialized.set(true);
138 }
139 } else LOG.debug("new labels added: " + resp);
140 } catch (Throwable t) {
141 throw new IOException(t);
142 }
143 return null;
144 }
145 };
146 SUPERUSER.runAs(action);
147 } while (!vcInitialized.get());
148
149 Scan s = new Scan();
150 s.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
151
152 int i = 0;
153 try (Table ht = TEST_UTIL.getConnection().getTable(LABELS_TABLE_NAME);
154 ResultScanner scanner = ht.getScanner(s)) {
155 while (true) {
156 Result next = scanner.next();
157 if (next == null) {
158 break;
159 }
160 i++;
161 }
162 }
163
164 Assert.assertEquals("The count should be 13", 13, i);
165 }
166
167 @Test
168 public void testListLabels() throws Throwable {
169 PrivilegedExceptionAction<ListLabelsResponse> action =
170 new PrivilegedExceptionAction<ListLabelsResponse>() {
171 public ListLabelsResponse run() throws Exception {
172 ListLabelsResponse response = null;
173 try {
174 response = VisibilityClient.listLabels(conf, null);
175 } catch (Throwable e) {
176 fail("Should not have thrown exception");
177 }
178
179
180
181
182
183 List<ByteString> labels = response.getLabelList();
184 assertEquals(12, labels.size());
185 assertTrue(labels.contains(ByteString.copyFrom(SECRET.getBytes())));
186 assertTrue(labels.contains(ByteString.copyFrom(TOPSECRET.getBytes())));
187 assertTrue(labels.contains(ByteString.copyFrom(CONFIDENTIAL.getBytes())));
188 assertTrue(labels.contains(ByteString.copyFrom("ABC".getBytes())));
189 assertTrue(labels.contains(ByteString.copyFrom("XYZ".getBytes())));
190 assertFalse(labels.contains(ByteString.copyFrom(SYSTEM_LABEL.getBytes())));
191 return null;
192 }
193 };
194 SUPERUSER.runAs(action);
195 }
196
197 @Test
198 public void testListLabelsWithRegEx() throws Throwable {
199 PrivilegedExceptionAction<ListLabelsResponse> action =
200 new PrivilegedExceptionAction<ListLabelsResponse>() {
201 public ListLabelsResponse run() throws Exception {
202 ListLabelsResponse response = null;
203 try {
204 response = VisibilityClient.listLabels(conf, ".*secret");
205 } catch (Throwable e) {
206 fail("Should not have thrown exception");
207 }
208
209 List<ByteString> labels = response.getLabelList();
210 assertEquals(2, labels.size());
211 assertTrue(labels.contains(ByteString.copyFrom(SECRET.getBytes())));
212 assertTrue(labels.contains(ByteString.copyFrom(TOPSECRET.getBytes())));
213 return null;
214 }
215 };
216 SUPERUSER.runAs(action);
217 }
218
219 @Test(timeout = 60 * 1000)
220 public void testVisibilityLabelsOnWALReplay() throws Exception {
221 final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
222 try (Table table = createTableAndWriteDataWithLabels(tableName,
223 "(" + SECRET + "|" + CONFIDENTIAL + ")", PRIVATE);) {
224 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
225 .getRegionServerThreads();
226 for (RegionServerThread rsThread : regionServerThreads) {
227 rsThread.getRegionServer().abort("Aborting ");
228 }
229
230 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
231 waitForLabelsRegionAvailability(rs.getRegionServer());
232 Scan s = new Scan();
233 s.setAuthorizations(new Authorizations(SECRET));
234 ResultScanner scanner = table.getScanner(s);
235 Result[] next = scanner.next(3);
236 assertTrue(next.length == 1);
237 }
238 }
239 }