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