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 @Test
768 public void testMultipleVersions() throws Exception {
769 final byte[] r1 = Bytes.toBytes("row1");
770 final byte[] r2 = Bytes.toBytes("row2");
771 final byte[] v1 = Bytes.toBytes("100");
772 final byte[] v2 = Bytes.toBytes("101");
773 final byte[] fam2 = Bytes.toBytes("info2");
774 final byte[] qual2 = Bytes.toBytes("qual2");
775 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
776 HTableDescriptor desc = new HTableDescriptor(tableName);
777 HColumnDescriptor col = new HColumnDescriptor(fam);
778 desc.addFamily(col);
779 col = new HColumnDescriptor(fam2);
780 col.setMaxVersions(5);
781 desc.addFamily(col);
782 TEST_UTIL.getHBaseAdmin().createTable(desc);
783 HTable table = null;
784 try {
785 table = new HTable(TEST_UTIL.getConfiguration(), tableName);
786 Put put = new Put(r1);
787 put.add(fam, qual, 3l, v1);
788 put.add(fam, qual2, 3l, v1);
789 put.add(fam2, qual, 3l, v1);
790 put.add(fam2, qual2, 3l, v1);
791 put.setCellVisibility(new CellVisibility(SECRET));
792 table.put(put);
793 put = new Put(r1);
794 put.add(fam, qual, 4l, v2);
795 put.add(fam, qual2, 4l, v2);
796 put.add(fam2, qual, 4l, v2);
797 put.add(fam2, qual2, 4l, v2);
798 put.setCellVisibility(new CellVisibility(PRIVATE));
799 table.put(put);
800
801 put = new Put(r2);
802 put.add(fam, qual, 3l, v1);
803 put.add(fam, qual2, 3l, v1);
804 put.add(fam2, qual, 3l, v1);
805 put.add(fam2, qual2, 3l, v1);
806 put.setCellVisibility(new CellVisibility(SECRET));
807 table.put(put);
808 put = new Put(r2);
809 put.add(fam, qual, 4l, v2);
810 put.add(fam, qual2, 4l, v2);
811 put.add(fam2, qual, 4l, v2);
812 put.add(fam2, qual2, 4l, v2);
813 put.setCellVisibility(new CellVisibility(SECRET));
814 table.put(put);
815
816
817 Scan s = new Scan();
818 s.setMaxVersions(1);
819 s.setAuthorizations(new Authorizations(SECRET));
820 ResultScanner scanner = table.getScanner(s);
821 Result result = scanner.next();
822 assertTrue(Bytes.equals(r1, result.getRow()));
823
824
825
826 assertNull(result.getColumnLatestCell(fam, qual));
827 assertNull(result.getColumnLatestCell(fam, qual2));
828
829
830
831
832 Cell cell = result.getColumnLatestCell(fam2, qual);
833 assertNotNull(cell);
834 assertTrue(Bytes.equals(v1, 0, v1.length, cell.getValueArray(), cell.getValueOffset(),
835 cell.getValueLength()));
836 cell = result.getColumnLatestCell(fam2, qual2);
837 assertNotNull(cell);
838 assertTrue(Bytes.equals(v1, 0, v1.length, cell.getValueArray(), cell.getValueOffset(),
839 cell.getValueLength()));
840
841 result = scanner.next();
842 assertTrue(Bytes.equals(r2, result.getRow()));
843 cell = result.getColumnLatestCell(fam, qual);
844 assertNotNull(cell);
845 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
846 cell.getValueLength()));
847 cell = result.getColumnLatestCell(fam, qual2);
848 assertNotNull(cell);
849 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
850 cell.getValueLength()));
851 cell = result.getColumnLatestCell(fam2, qual);
852 assertNotNull(cell);
853 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
854 cell.getValueLength()));
855 cell = result.getColumnLatestCell(fam2, qual2);
856 assertNotNull(cell);
857 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
858 cell.getValueLength()));
859 } finally {
860 if (table != null) {
861 table.close();
862 }
863 }
864 }
865
866 private static HTable createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
867 throws Exception {
868 HTable table = null;
869 try {
870 table = TEST_UTIL.createTable(tableName, fam);
871 int i = 1;
872 List<Put> puts = new ArrayList<Put>();
873 for (String labelExp : labelExps) {
874 Put put = new Put(Bytes.toBytes("row" + i));
875 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
876 put.setCellVisibility(new CellVisibility(labelExp));
877 puts.add(put);
878 i++;
879 }
880 table.put(puts);
881 } finally {
882 if (table != null) {
883 table.close();
884 }
885 }
886 return table;
887 }
888
889 public static void addLabels() throws Exception {
890 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
891 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
892 public VisibilityLabelsResponse run() throws Exception {
893 String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE };
894 try {
895 VisibilityClient.addLabels(conf, labels);
896 } catch (Throwable t) {
897 throw new IOException(t);
898 }
899 return null;
900 }
901 };
902 SUPERUSER.runAs(action);
903 }
904 }