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