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_FAMILY;
21 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
22 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABEL_QUALIFIER;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.io.IOException;
30 import java.security.PrivilegedExceptionAction;
31 import java.util.ArrayList;
32 import java.util.List;
33
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.hbase.Cell;
36 import org.apache.hadoop.hbase.CellScanner;
37 import org.apache.hadoop.hbase.HBaseTestingUtility;
38 import org.apache.hadoop.hbase.HColumnDescriptor;
39 import org.apache.hadoop.hbase.HConstants;
40 import org.apache.hadoop.hbase.HTableDescriptor;
41 import org.apache.hadoop.hbase.MediumTests;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.client.Append;
44 import org.apache.hadoop.hbase.client.Get;
45 import org.apache.hadoop.hbase.client.HBaseAdmin;
46 import org.apache.hadoop.hbase.client.HTable;
47 import org.apache.hadoop.hbase.client.Increment;
48 import org.apache.hadoop.hbase.client.Put;
49 import org.apache.hadoop.hbase.client.Result;
50 import org.apache.hadoop.hbase.client.ResultScanner;
51 import org.apache.hadoop.hbase.client.Scan;
52 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
53 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
54 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
55 import org.apache.hadoop.hbase.regionserver.BloomType;
56 import org.apache.hadoop.hbase.regionserver.HRegion;
57 import org.apache.hadoop.hbase.regionserver.HRegionServer;
58 import org.apache.hadoop.hbase.security.User;
59 import org.apache.hadoop.hbase.util.Bytes;
60 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
61 import org.junit.After;
62 import org.junit.AfterClass;
63 import org.junit.Assert;
64 import org.junit.BeforeClass;
65 import org.junit.Rule;
66 import org.junit.Test;
67 import org.junit.experimental.categories.Category;
68 import org.junit.rules.TestName;
69
70 import com.google.protobuf.ByteString;
71
72
73
74
75 @Category(MediumTests.class)
76 public class TestVisibilityLabels {
77
78 private static final String TOPSECRET = "topsecret";
79 private static final String PUBLIC = "public";
80 private static final String PRIVATE = "private";
81 private static final String CONFIDENTIAL = "confidential";
82 private static final String SECRET = "secret";
83 public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
84 private static final byte[] row1 = Bytes.toBytes("row1");
85 private static final byte[] row2 = Bytes.toBytes("row2");
86 private static final byte[] row3 = Bytes.toBytes("row3");
87 private static final byte[] row4 = Bytes.toBytes("row4");
88 private final static byte[] fam = Bytes.toBytes("info");
89 private final static byte[] qual = Bytes.toBytes("qual");
90 private final static byte[] value = Bytes.toBytes("value");
91 public static Configuration conf;
92
93 private volatile boolean killedRS = false;
94 @Rule
95 public final TestName TEST_NAME = new TestName();
96 public static User SUPERUSER;
97
98 @BeforeClass
99 public static void setupBeforeClass() throws Exception {
100
101 conf = TEST_UTIL.getConfiguration();
102 conf.setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
103 conf.setBoolean("hbase.online.schema.update.enable", true);
104 conf.setInt("hfile.format.version", 3);
105 conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
106 conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
107 conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
108 ScanLabelGenerator.class);
109 conf.set("hbase.superuser", "admin");
110 TEST_UTIL.startMiniCluster(2);
111 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
112
113
114 TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
115 addLabels();
116 }
117
118 @AfterClass
119 public static void tearDownAfterClass() throws Exception {
120 TEST_UTIL.shutdownMiniCluster();
121 }
122
123 @After
124 public void tearDown() throws Exception {
125 killedRS = false;
126 }
127
128 @Test
129 public void testSimpleVisibilityLabels() throws Exception {
130 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
131 HTable table = createTableAndWriteDataWithLabels(tableName, SECRET + "|" + CONFIDENTIAL,
132 PRIVATE + "|" + CONFIDENTIAL);
133 try {
134 Scan s = new Scan();
135 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE));
136 ResultScanner scanner = table.getScanner(s);
137 Result[] next = scanner.next(3);
138
139 assertTrue(next.length == 2);
140 CellScanner cellScanner = next[0].cellScanner();
141 cellScanner.advance();
142 Cell current = cellScanner.current();
143 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
144 current.getRowLength(), row1, 0, row1.length));
145 cellScanner = next[1].cellScanner();
146 cellScanner.advance();
147 current = cellScanner.current();
148 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
149 current.getRowLength(), row2, 0, row2.length));
150 } finally {
151 if (table != null) {
152 table.close();
153 }
154 }
155 }
156
157 @Test
158 public void testVisibilityLabelsWithComplexLabels() throws Exception {
159 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
160 HTable table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
161 + ")" + "&" + "!" + TOPSECRET, "(" + PRIVATE + "&" + CONFIDENTIAL + "&" + SECRET + ")", "("
162 + PRIVATE + "&" + CONFIDENTIAL + "&" + SECRET + ")", "(" + PRIVATE + "&" + CONFIDENTIAL
163 + "&" + SECRET + ")");
164 try {
165 Scan s = new Scan();
166 s.setAuthorizations(new Authorizations(TOPSECRET, CONFIDENTIAL, PRIVATE, PUBLIC, SECRET));
167 ResultScanner scanner = table.getScanner(s);
168 Result[] next = scanner.next(4);
169 assertEquals(3, next.length);
170 CellScanner cellScanner = next[0].cellScanner();
171 cellScanner.advance();
172 Cell current = cellScanner.current();
173 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
174 current.getRowLength(), row2, 0, row2.length));
175 cellScanner = next[1].cellScanner();
176 cellScanner.advance();
177 current = cellScanner.current();
178 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
179 current.getRowLength(), row3, 0, row3.length));
180 cellScanner = next[2].cellScanner();
181 cellScanner.advance();
182 current = cellScanner.current();
183 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
184 current.getRowLength(), row4, 0, row4.length));
185 } finally {
186 if (table != null) {
187 table.close();
188 }
189 }
190 }
191
192 @Test
193 public void testVisibilityLabelsThatDoesNotPassTheCriteria() throws Exception {
194 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
195 HTable table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
196 + ")", PRIVATE);
197 try {
198 Scan s = new Scan();
199 s.setAuthorizations(new Authorizations(PUBLIC));
200 ResultScanner scanner = table.getScanner(s);
201 Result[] next = scanner.next(3);
202 assertTrue(next.length == 0);
203 } finally {
204 if (table != null) {
205 table.close();
206 }
207 }
208 }
209
210 @Test
211 public void testVisibilityLabelsInPutsThatDoesNotMatchAnyDefinedLabels() throws Exception {
212 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
213 try {
214 createTableAndWriteDataWithLabels(tableName, "SAMPLE_LABEL", "TEST");
215 fail("Should have failed with failed sanity check exception");
216 } catch (Exception e) {
217 }
218 }
219
220 @Test
221 public void testVisibilityLabelsInScanThatDoesNotMatchAnyDefinedLabels() throws Exception {
222 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
223 HTable table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
224 + ")", PRIVATE);
225 try {
226 Scan s = new Scan();
227 s.setAuthorizations(new Authorizations("SAMPLE"));
228 ResultScanner scanner = table.getScanner(s);
229 Result[] next = scanner.next(3);
230 assertTrue(next.length == 0);
231 } finally {
232 if (table != null) {
233 table.close();
234 }
235 }
236 }
237
238 @Test
239 public void testVisibilityLabelsWithGet() throws Exception {
240 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
241 HTable table = createTableAndWriteDataWithLabels(tableName, SECRET + "&" + CONFIDENTIAL + "&!"
242 + PRIVATE, SECRET + "&" + CONFIDENTIAL + "&" + PRIVATE);
243 try {
244 Get get = new Get(row1);
245 get.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
246 Result result = table.get(get);
247 assertTrue(!result.isEmpty());
248 Cell cell = result.getColumnLatestCell(fam, qual);
249 assertTrue(Bytes.equals(value, 0, value.length, cell.getValueArray(), cell.getValueOffset(),
250 cell.getValueLength()));
251 } finally {
252 if (table != null) {
253 table.close();
254 }
255 }
256 }
257
258 @Test
259 public void testVisibilityLabelsOnKillingOfRSContainingLabelsTable() throws Exception {
260 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
261 .getRegionServerThreads();
262 int liveRS = 0;
263 for (RegionServerThread rsThreads : regionServerThreads) {
264 if (!rsThreads.getRegionServer().isAborted()) {
265 liveRS++;
266 }
267 }
268 if (liveRS == 1) {
269 TEST_UTIL.getHBaseCluster().startRegionServer();
270 }
271 Thread t1 = new Thread() {
272 public void run() {
273 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
274 .getRegionServerThreads();
275 for (RegionServerThread rsThread : regionServerThreads) {
276 List<HRegion> onlineRegions = rsThread.getRegionServer().getOnlineRegions(
277 LABELS_TABLE_NAME);
278 if (onlineRegions.size() > 0) {
279 rsThread.getRegionServer().abort("Aborting ");
280 killedRS = true;
281 break;
282 }
283 }
284 }
285
286 };
287 t1.start();
288 final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
289 Thread t = new Thread() {
290 public void run() {
291 try {
292 while (!killedRS) {
293 Thread.sleep(1);
294 }
295 createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL + ")",
296 PRIVATE);
297 } catch (Exception e) {
298 }
299 }
300 };
301 t.start();
302 regionServerThreads = TEST_UTIL.getHBaseCluster().getRegionServerThreads();
303 while (!killedRS) {
304 Thread.sleep(10);
305 }
306 regionServerThreads = TEST_UTIL.getHBaseCluster().getRegionServerThreads();
307 for (RegionServerThread rsThread : regionServerThreads) {
308 while (true) {
309 if (!rsThread.getRegionServer().isAborted()) {
310 List<HRegion> onlineRegions = rsThread.getRegionServer().getOnlineRegions(
311 LABELS_TABLE_NAME);
312 if (onlineRegions.size() > 0) {
313 break;
314 } else {
315 Thread.sleep(10);
316 }
317 } else {
318 break;
319 }
320 }
321 }
322 TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
323 t.join();
324 HTable table = null;
325 try {
326 table = new HTable(TEST_UTIL.getConfiguration(), tableName);
327 Scan s = new Scan();
328 s.setAuthorizations(new Authorizations(SECRET));
329 ResultScanner scanner = table.getScanner(s);
330 Result[] next = scanner.next(3);
331 assertTrue(next.length == 1);
332 } finally {
333 if (table != null) {
334 table.close();
335 }
336 }
337 }
338
339 @Test(timeout = 60 * 1000)
340 public void testVisibilityLabelsOnRSRestart() throws Exception {
341 final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
342 HTable table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
343 + ")", PRIVATE);
344 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
345 .getRegionServerThreads();
346 for (RegionServerThread rsThread : regionServerThreads) {
347 rsThread.getRegionServer().abort("Aborting ");
348 }
349
350 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
351 waitForLabelsRegionAvailability(rs.getRegionServer());
352 try {
353 Scan s = new Scan();
354 s.setAuthorizations(new Authorizations(SECRET));
355 ResultScanner scanner = table.getScanner(s);
356 Result[] next = scanner.next(3);
357 assertTrue(next.length == 1);
358 } finally {
359 if (table != null) {
360 table.close();
361 }
362 }
363 }
364
365 @Test(timeout = 60 * 1000)
366 public void testAddVisibilityLabelsOnRSRestart() throws Exception {
367 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
368 .getRegionServerThreads();
369 for (RegionServerThread rsThread : regionServerThreads) {
370 rsThread.getRegionServer().abort("Aborting ");
371 }
372
373 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
374 waitForLabelsRegionAvailability(rs.getRegionServer());
375 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
376 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
377 public VisibilityLabelsResponse run() throws Exception {
378 String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, "ABC", "XYZ" };
379 try {
380 VisibilityClient.addLabels(conf, labels);
381 } catch (Throwable t) {
382 throw new IOException(t);
383 }
384 return null;
385 }
386 };
387 SUPERUSER.runAs(action);
388
389 Scan s = new Scan();
390 s.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
391 HTable ht = new HTable(conf, LABELS_TABLE_NAME.getName());
392 int i = 0;
393 try {
394 ResultScanner scanner = ht.getScanner(s);
395 while (true) {
396 Result next = scanner.next();
397 if (next == null) {
398 break;
399 }
400 i++;
401 }
402 } finally {
403 if (ht != null) {
404 ht.close();
405 }
406 }
407
408 Assert.assertEquals("The count should be 8", 8, i);
409 }
410
411 private void waitForLabelsRegionAvailability(HRegionServer regionServer) {
412 while (!regionServer.isOnline()) {
413 try {
414 Thread.sleep(10);
415 } catch (InterruptedException e) {
416 }
417 }
418 while (regionServer.getOnlineRegions(LABELS_TABLE_NAME).isEmpty()) {
419 try {
420 Thread.sleep(10);
421 } catch (InterruptedException e) {
422 }
423 }
424 HRegion labelsTableRegion = regionServer.getOnlineRegions(LABELS_TABLE_NAME).get(0);
425 while (labelsTableRegion.isRecovering()) {
426 try {
427 Thread.sleep(10);
428 } catch (InterruptedException e) {
429 }
430 }
431 }
432
433 @Test
434 public void testVisibilityLabelsInGetThatDoesNotMatchAnyDefinedLabels() throws Exception {
435 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
436 HTable table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
437 + ")", PRIVATE);
438 try {
439 Get get = new Get(row1);
440 get.setAuthorizations(new Authorizations("SAMPLE"));
441 Result result = table.get(get);
442 assertTrue(result.isEmpty());
443 } finally {
444 if (table != null) {
445 table.close();
446 }
447 }
448 }
449
450 @Test
451 public void testAddLabels() throws Throwable {
452 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
453 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
454 public VisibilityLabelsResponse run() throws Exception {
455 String[] labels = { "L1", SECRET, "L2", "invalid~", "L3" };
456 VisibilityLabelsResponse response = null;
457 try {
458 response = VisibilityClient.addLabels(conf, labels);
459 } catch (Throwable e) {
460 fail("Should not have thrown exception");
461 }
462 List<RegionActionResult> resultList = response.getResultList();
463 assertEquals(5, resultList.size());
464 assertTrue(resultList.get(0).getException().getValue().isEmpty());
465 assertEquals("org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException",
466 resultList.get(1).getException().getName());
467 assertTrue(resultList.get(2).getException().getValue().isEmpty());
468 assertEquals("org.apache.hadoop.hbase.security.visibility.InvalidLabelException",
469 resultList.get(3).getException().getName());
470 assertTrue(resultList.get(4).getException().getValue().isEmpty());
471 return null;
472 }
473 };
474 SUPERUSER.runAs(action);
475 }
476
477 @Test
478 public void testSetAndGetUserAuths() throws Throwable {
479 final String user = "user1";
480 PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
481 public Void run() throws Exception {
482 String[] auths = { SECRET, CONFIDENTIAL };
483 try {
484 VisibilityClient.setAuths(conf, auths, user);
485 } catch (Throwable e) {
486 }
487 return null;
488 }
489 };
490 SUPERUSER.runAs(action);
491 HTable ht = null;
492 try {
493 ht = new HTable(conf, LABELS_TABLE_NAME);
494 Scan scan = new Scan();
495 scan.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
496 ResultScanner scanner = ht.getScanner(scan);
497 Result result = null;
498 while ((result = scanner.next()) != null) {
499 Cell label = result.getColumnLatestCell(LABELS_TABLE_FAMILY, LABEL_QUALIFIER);
500 Cell userAuth = result.getColumnLatestCell(LABELS_TABLE_FAMILY, user.getBytes());
501 if (Bytes.equals(SECRET.getBytes(), 0, SECRET.getBytes().length, label.getValueArray(),
502 label.getValueOffset(), label.getValueLength())
503 || Bytes.equals(CONFIDENTIAL.getBytes(), 0, CONFIDENTIAL.getBytes().length,
504 label.getValueArray(), label.getValueOffset(), label.getValueLength())) {
505 assertNotNull(userAuth);
506 } else {
507 assertNull(userAuth);
508 }
509 }
510 } finally {
511 if (ht != null) {
512 ht.close();
513 }
514 }
515
516 action = new PrivilegedExceptionAction<Void>() {
517 public Void run() throws Exception {
518 GetAuthsResponse authsResponse = null;
519 try {
520 authsResponse = VisibilityClient.getAuths(conf, user);
521 } catch (Throwable e) {
522 fail("Should not have failed");
523 }
524 List<String> authsList = new ArrayList<String>();
525 for (ByteString authBS : authsResponse.getAuthList()) {
526 authsList.add(Bytes.toString(authBS.toByteArray()));
527 }
528 assertEquals(2, authsList.size());
529 assertTrue(authsList.contains(SECRET));
530 assertTrue(authsList.contains(CONFIDENTIAL));
531 return null;
532 }
533 };
534 SUPERUSER.runAs(action);
535
536
537 action = new PrivilegedExceptionAction<Void>() {
538 public Void run() throws Exception {
539 String[] auths1 = { SECRET, CONFIDENTIAL };
540 GetAuthsResponse authsResponse = null;
541 try {
542 VisibilityClient.setAuths(conf, auths1, user);
543 try {
544 authsResponse = VisibilityClient.getAuths(conf, user);
545 } catch (Throwable e) {
546 fail("Should not have failed");
547 }
548 } catch (Throwable e) {
549 }
550 List<String> authsList = new ArrayList<String>();
551 for (ByteString authBS : authsResponse.getAuthList()) {
552 authsList.add(Bytes.toString(authBS.toByteArray()));
553 }
554 assertEquals(2, authsList.size());
555 assertTrue(authsList.contains(SECRET));
556 assertTrue(authsList.contains(CONFIDENTIAL));
557 return null;
558 }
559 };
560 SUPERUSER.runAs(action);
561 }
562
563 @Test
564 public void testClearUserAuths() throws Throwable {
565 PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
566 public Void run() throws Exception {
567 String[] auths = { SECRET, CONFIDENTIAL, PRIVATE };
568 String user = "testUser";
569 try {
570 VisibilityClient.setAuths(conf, auths, user);
571 } catch (Throwable e) {
572 fail("Should not have failed");
573 }
574
575
576 auths = new String[] { SECRET, PUBLIC, CONFIDENTIAL };
577 VisibilityLabelsResponse response = null;
578 try {
579 response = VisibilityClient.clearAuths(conf, auths, user);
580 } catch (Throwable e) {
581 fail("Should not have failed");
582 }
583 List<RegionActionResult> resultList = response.getResultList();
584 assertEquals(3, resultList.size());
585 assertTrue(resultList.get(0).getException().getValue().isEmpty());
586 assertEquals("org.apache.hadoop.hbase.security.visibility.InvalidLabelException",
587 resultList.get(1).getException().getName());
588 assertTrue(resultList.get(2).getException().getValue().isEmpty());
589 HTable ht = null;
590 try {
591 ht = new HTable(conf, LABELS_TABLE_NAME);
592 ResultScanner scanner = ht.getScanner(new Scan());
593 Result result = null;
594 while ((result = scanner.next()) != null) {
595 Cell label = result.getColumnLatestCell(LABELS_TABLE_FAMILY, LABEL_QUALIFIER);
596 Cell userAuth = result.getColumnLatestCell(LABELS_TABLE_FAMILY, user.getBytes());
597 if (Bytes.equals(PRIVATE.getBytes(), 0, PRIVATE.getBytes().length,
598 label.getValueArray(), label.getValueOffset(), label.getValueLength())) {
599 assertNotNull(userAuth);
600 } else {
601 assertNull(userAuth);
602 }
603 }
604 } finally {
605 if (ht != null) {
606 ht.close();
607 }
608 }
609
610 GetAuthsResponse authsResponse = null;
611 try {
612 authsResponse = VisibilityClient.getAuths(conf, user);
613 } catch (Throwable e) {
614 fail("Should not have failed");
615 }
616 List<String> authsList = new ArrayList<String>();
617 for (ByteString authBS : authsResponse.getAuthList()) {
618 authsList.add(Bytes.toString(authBS.toByteArray()));
619 }
620 assertEquals(1, authsList.size());
621 assertTrue(authsList.contains(PRIVATE));
622 return null;
623 }
624 };
625 SUPERUSER.runAs(action);
626 }
627
628 @Test
629 public void testLabelsWithCheckAndPut() throws Throwable {
630 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
631 HTable table = null;
632 try {
633 table = TEST_UTIL.createTable(tableName, fam);
634 byte[] row1 = Bytes.toBytes("row1");
635 Put put = new Put(row1);
636 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
637 put.setCellVisibility(new CellVisibility(SECRET + " & " + CONFIDENTIAL));
638 table.checkAndPut(row1, fam, qual, null, put);
639 byte[] row2 = Bytes.toBytes("row2");
640 put = new Put(row2);
641 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
642 put.setCellVisibility(new CellVisibility(SECRET));
643 table.checkAndPut(row2, fam, qual, null, put);
644
645 Scan scan = new Scan();
646 scan.setAuthorizations(new Authorizations(SECRET));
647 ResultScanner scanner = table.getScanner(scan);
648 Result result = scanner.next();
649 assertTrue(!result.isEmpty());
650 assertTrue(Bytes.equals(row2, result.getRow()));
651 result = scanner.next();
652 assertNull(result);
653 } finally {
654 if (table != null) {
655 table.close();
656 }
657 }
658 }
659
660 @Test
661 public void testLabelsWithIncrement() throws Throwable {
662 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
663 HTable table = null;
664 try {
665 table = TEST_UTIL.createTable(tableName, fam);
666 byte[] row1 = Bytes.toBytes("row1");
667 byte[] val = Bytes.toBytes(1L);
668 Put put = new Put(row1);
669 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, val);
670 put.setCellVisibility(new CellVisibility(SECRET + " & " + CONFIDENTIAL));
671 table.put(put);
672 Get get = new Get(row1);
673 get.setAuthorizations(new Authorizations(SECRET));
674 Result result = table.get(get);
675 assertTrue(result.isEmpty());
676 table.incrementColumnValue(row1, fam, qual, 2L);
677 result = table.get(get);
678 assertTrue(result.isEmpty());
679 Increment increment = new Increment(row1);
680 increment.addColumn(fam, qual, 2L);
681 increment.setCellVisibility(new CellVisibility(SECRET));
682 table.increment(increment);
683 result = table.get(get);
684 assertTrue(!result.isEmpty());
685 } finally {
686 if (table != null) {
687 table.close();
688 }
689 }
690 }
691
692 @Test
693 public void testLabelsWithAppend() throws Throwable {
694 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
695 HTable table = null;
696 try {
697 table = TEST_UTIL.createTable(tableName, fam);
698 byte[] row1 = Bytes.toBytes("row1");
699 byte[] val = Bytes.toBytes("a");
700 Put put = new Put(row1);
701 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, val);
702 put.setCellVisibility(new CellVisibility(SECRET + " & " + CONFIDENTIAL));
703 table.put(put);
704 Get get = new Get(row1);
705 get.setAuthorizations(new Authorizations(SECRET));
706 Result result = table.get(get);
707 assertTrue(result.isEmpty());
708 Append append = new Append(row1);
709 append.add(fam, qual, Bytes.toBytes("b"));
710 table.append(append);
711 result = table.get(get);
712 assertTrue(result.isEmpty());
713 append = new Append(row1);
714 append.add(fam, qual, Bytes.toBytes("c"));
715 append.setCellVisibility(new CellVisibility(SECRET));
716 table.append(append);
717 result = table.get(get);
718 assertTrue(!result.isEmpty());
719 } finally {
720 if (table != null) {
721 table.close();
722 }
723 }
724 }
725
726 @Test
727 public void testUserShouldNotDoDDLOpOnLabelsTable() throws Exception {
728 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
729 try {
730 admin.disableTable(LABELS_TABLE_NAME);
731 fail("Lables table should not get disabled by user.");
732 } catch (Exception e) {
733 }
734 try {
735 admin.deleteTable(LABELS_TABLE_NAME);
736 fail("Lables table should not get disabled by user.");
737 } catch (Exception e) {
738 }
739 try {
740 HColumnDescriptor hcd = new HColumnDescriptor("testFamily");
741 admin.addColumn(LABELS_TABLE_NAME, hcd);
742 fail("Lables table should not get altered by user.");
743 } catch (Exception e) {
744 }
745 try {
746 admin.deleteColumn(LABELS_TABLE_NAME, VisibilityConstants.LABELS_TABLE_FAMILY);
747 fail("Lables table should not get altered by user.");
748 } catch (Exception e) {
749 }
750 try {
751 HColumnDescriptor hcd = new HColumnDescriptor(VisibilityConstants.LABELS_TABLE_FAMILY);
752 hcd.setBloomFilterType(BloomType.ROWCOL);
753 admin.modifyColumn(LABELS_TABLE_NAME, hcd);
754 fail("Lables table should not get altered by user.");
755 } catch (Exception e) {
756 }
757 try {
758 HTableDescriptor htd = new HTableDescriptor(LABELS_TABLE_NAME);
759 htd.addFamily(new HColumnDescriptor("f1"));
760 htd.addFamily(new HColumnDescriptor("f2"));
761 admin.modifyTable(LABELS_TABLE_NAME, htd);
762 fail("Lables table should not get altered by user.");
763 } catch (Exception e) {
764 }
765 }
766
767 private static HTable createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
768 throws Exception {
769 HTable table = null;
770 try {
771 table = TEST_UTIL.createTable(tableName, fam);
772 int i = 1;
773 List<Put> puts = new ArrayList<Put>();
774 for (String labelExp : labelExps) {
775 Put put = new Put(Bytes.toBytes("row" + i));
776 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
777 put.setCellVisibility(new CellVisibility(labelExp));
778 puts.add(put);
779 i++;
780 }
781 table.put(puts);
782 } finally {
783 if (table != null) {
784 table.close();
785 }
786 }
787 return table;
788 }
789
790 public static void addLabels() throws Exception {
791 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
792 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
793 public VisibilityLabelsResponse run() throws Exception {
794 String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE };
795 try {
796 VisibilityClient.addLabels(conf, labels);
797 } catch (Throwable t) {
798 throw new IOException(t);
799 }
800 return null;
801 }
802 };
803 SUPERUSER.runAs(action);
804 }
805 }