1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security.access;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.fail;
23
24 import java.io.IOException;
25 import java.lang.reflect.UndeclaredThrowableException;
26 import java.security.PrivilegedActionException;
27 import java.security.PrivilegedExceptionAction;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.concurrent.Callable;
31 import java.util.concurrent.CountDownLatch;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.hbase.Coprocessor;
37 import org.apache.hadoop.hbase.HBaseTestingUtility;
38 import org.apache.hadoop.hbase.HConstants;
39 import org.apache.hadoop.hbase.HColumnDescriptor;
40 import org.apache.hadoop.hbase.HTableDescriptor;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.MiniHBaseCluster;
43 import org.apache.hadoop.hbase.NamespaceDescriptor;
44 import org.apache.hadoop.hbase.TableName;
45 import org.apache.hadoop.hbase.TableNotEnabledException;
46 import org.apache.hadoop.hbase.Waiter.Predicate;
47 import org.apache.hadoop.hbase.client.Connection;
48 import org.apache.hadoop.hbase.client.ConnectionFactory;
49 import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
50 import org.apache.hadoop.hbase.client.Admin;
51 import org.apache.hadoop.hbase.client.Table;
52 import org.apache.hadoop.hbase.coprocessor.BaseMasterObserver;
53 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
54 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
55 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
56 import org.apache.hadoop.hbase.io.hfile.HFile;
57 import org.apache.hadoop.hbase.master.HMaster;
58 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
59 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
60 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
61 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.CheckPermissionsRequest;
62 import org.apache.hadoop.hbase.regionserver.Region;
63 import org.apache.hadoop.hbase.security.AccessDeniedException;
64 import org.apache.hadoop.hbase.security.User;
65 import org.apache.hadoop.hbase.security.access.Permission.Action;
66 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
67
68 import com.google.common.collect.Lists;
69 import com.google.common.collect.Maps;
70 import com.google.protobuf.BlockingRpcChannel;
71 import com.google.protobuf.ServiceException;
72
73
74
75
76 public class SecureTestUtil {
77
78 private static final Log LOG = LogFactory.getLog(SecureTestUtil.class);
79 private static final int WAIT_TIME = 10000;
80
81 public static void configureSuperuser(Configuration conf) throws IOException {
82
83
84
85
86 String currentUser = User.getCurrent().getName();
87 StringBuffer sb = new StringBuffer();
88 sb.append("admin,");
89 sb.append(currentUser);
90
91 for (int i = 0; i < 5; i++) {
92 sb.append(',');
93 sb.append(currentUser); sb.append(".hfs."); sb.append(i);
94 }
95 conf.set("hbase.superuser", sb.toString());
96 }
97
98 public static void enableSecurity(Configuration conf) throws IOException {
99 conf.set("hadoop.security.authorization", "false");
100 conf.set("hadoop.security.authentication", "simple");
101 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, AccessController.class.getName() +
102 "," + MasterSyncObserver.class.getName());
103 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, AccessController.class.getName() +
104 "," + SecureBulkLoadEndpoint.class.getName());
105 conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, AccessController.class.getName());
106
107 conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
108 configureSuperuser(conf);
109 }
110
111 public static void verifyConfiguration(Configuration conf) {
112 String coprocs = conf.get(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);
113 boolean accessControllerLoaded = false;
114 for (String coproc : coprocs.split(",")) {
115 try {
116 accessControllerLoaded = AccessController.class.isAssignableFrom(Class.forName(coproc));
117 if (accessControllerLoaded) break;
118 } catch (ClassNotFoundException cnfe) {
119 }
120 }
121 if (!(conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY).contains(
122 AccessController.class.getName())
123 && accessControllerLoaded && conf.get(
124 CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY).contains(
125 AccessController.class.getName()))) {
126 throw new RuntimeException("AccessController is missing from a system coprocessor list");
127 }
128 if (conf.getInt(HFile.FORMAT_VERSION_KEY, 2) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) {
129 throw new RuntimeException("Post 0.96 security features require HFile version >= 3");
130 }
131 }
132
133 public static void checkTablePerms(Configuration conf, TableName table, byte[] family, byte[] column,
134 Permission.Action... actions) throws IOException {
135 Permission[] perms = new Permission[actions.length];
136 for (int i = 0; i < actions.length; i++) {
137 perms[i] = new TablePermission(table, family, column, actions[i]);
138 }
139
140 checkTablePerms(conf, table, perms);
141 }
142
143 public static void checkTablePerms(Configuration conf, TableName table, Permission... perms)
144 throws IOException {
145 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
146 for (Permission p : perms) {
147 request.addPermission(ProtobufUtil.toPermission(p));
148 }
149 try (Connection connection = ConnectionFactory.createConnection(conf)) {
150 try (Table acl = connection.getTable(table)) {
151 AccessControlService.BlockingInterface protocol =
152 AccessControlService.newBlockingStub(acl.coprocessorService(new byte[0]));
153 try {
154 protocol.checkPermissions(null, request.build());
155 } catch (ServiceException se) {
156 ProtobufUtil.toIOException(se);
157 }
158 }
159 }
160 }
161
162
163
164
165
166
167
168
169
170
171
172 public static interface AccessTestAction extends PrivilegedExceptionAction<Object> { }
173
174
175 public static void verifyAllowed(User user, AccessTestAction... actions) throws Exception {
176 for (AccessTestAction action : actions) {
177 try {
178 Object obj = user.runAs(action);
179 if (obj != null && obj instanceof List<?>) {
180 List<?> results = (List<?>) obj;
181 if (results != null && results.isEmpty()) {
182 fail("Empty non null results from action for user '" + user.getShortName() + "'");
183 }
184 }
185 } catch (AccessDeniedException ade) {
186 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
187 }
188 }
189 }
190
191
192 public static void verifyAllowed(AccessTestAction action, User... users) throws Exception {
193 for (User user : users) {
194 verifyAllowed(user, action);
195 }
196 }
197
198 public static void verifyAllowed(User user, AccessTestAction action, int count) throws Exception {
199 try {
200 Object obj = user.runAs(action);
201 if (obj != null && obj instanceof List<?>) {
202 List<?> results = (List<?>) obj;
203 if (results != null && results.isEmpty()) {
204 fail("Empty non null results from action for user '" + user.getShortName() + "'");
205 }
206 assertEquals(count, results.size());
207 }
208 } catch (AccessDeniedException ade) {
209 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
210 }
211 }
212
213
214 public static void verifyDenied(AccessTestAction action, User... users) throws Exception {
215 for (User user : users) {
216 verifyDenied(user, action);
217 }
218 }
219
220
221 public static void verifyIfEmptyList(AccessTestAction action, User... users) throws Exception {
222 for (User user : users) {
223 try {
224 Object obj = user.runAs(action);
225 if (obj != null && obj instanceof List<?>) {
226 List<?> results = (List<?>) obj;
227 if (results != null && !results.isEmpty()) {
228 fail("Unexpected action results: " + results + " for user '"
229 + user.getShortName() + "'");
230 }
231 } else {
232 fail("Unexpected results for user '" + user.getShortName() + "'");
233 }
234 } catch (AccessDeniedException ade) {
235 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
236 }
237 }
238 }
239
240
241 public static void verifyIfNull(AccessTestAction action, User... users) throws Exception {
242 for (User user : users) {
243 try {
244 Object obj = user.runAs(action);
245 if (obj != null) {
246 fail("Non null results from action for user '" + user.getShortName() + "' : " + obj);
247 }
248 } catch (AccessDeniedException ade) {
249 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
250 }
251 }
252 }
253
254
255 public static void verifyDenied(User user, AccessTestAction... actions) throws Exception {
256 for (AccessTestAction action : actions) {
257 try {
258 user.runAs(action);
259 fail("Expected exception was not thrown for user '" + user.getShortName() + "'");
260 } catch (IOException e) {
261 boolean isAccessDeniedException = false;
262 if(e instanceof RetriesExhaustedWithDetailsException) {
263
264
265
266 for(Throwable ex : ((RetriesExhaustedWithDetailsException) e).getCauses()) {
267 if (ex instanceof AccessDeniedException) {
268 isAccessDeniedException = true;
269 break;
270 }
271 }
272 }
273 else {
274
275
276 Throwable ex = e;
277 do {
278 if (ex instanceof AccessDeniedException) {
279 isAccessDeniedException = true;
280 break;
281 }
282 } while((ex = ex.getCause()) != null);
283 }
284 if (!isAccessDeniedException) {
285 fail("Expected exception was not thrown for user '" + user.getShortName() + "'");
286 }
287 } catch (UndeclaredThrowableException ute) {
288
289 Throwable ex = ute.getUndeclaredThrowable();
290 if (ex instanceof PrivilegedActionException) {
291 ex = ((PrivilegedActionException) ex).getException();
292 }
293 if (ex instanceof ServiceException) {
294 ServiceException se = (ServiceException)ex;
295 if (se.getCause() != null && se.getCause() instanceof AccessDeniedException) {
296
297 return;
298 }
299 }
300 fail("Expected exception was not thrown for user '" + user.getShortName() + "'");
301 }
302 }
303 }
304
305 private static List<AccessController> getAccessControllers(MiniHBaseCluster cluster) {
306 List<AccessController> result = Lists.newArrayList();
307 for (RegionServerThread t: cluster.getLiveRegionServerThreads()) {
308 for (Region region: t.getRegionServer().getOnlineRegionsLocalContext()) {
309 Coprocessor cp = region.getCoprocessorHost()
310 .findCoprocessor(AccessController.class.getName());
311 if (cp != null) {
312 result.add((AccessController)cp);
313 }
314 }
315 }
316 return result;
317 }
318
319 private static Map<AccessController,Long> getAuthManagerMTimes(MiniHBaseCluster cluster) {
320 Map<AccessController,Long> result = Maps.newHashMap();
321 for (AccessController ac: getAccessControllers(cluster)) {
322 result.put(ac, ac.getAuthManager().getMTime());
323 }
324 return result;
325 }
326
327 @SuppressWarnings("rawtypes")
328 private static void updateACLs(final HBaseTestingUtility util, Callable c) throws Exception {
329
330 final Map<AccessController,Long> oldMTimes = getAuthManagerMTimes(util.getHBaseCluster());
331
332
333 c.call();
334
335
336 util.waitFor(WAIT_TIME, 100, new Predicate<IOException>() {
337 @Override
338 public boolean evaluate() throws IOException {
339 Map<AccessController,Long> mtimes = getAuthManagerMTimes(util.getHBaseCluster());
340 for (Map.Entry<AccessController,Long> e: mtimes.entrySet()) {
341 if (!oldMTimes.containsKey(e.getKey())) {
342 LOG.error("Snapshot of AccessController state does not include instance on region " +
343 e.getKey().getRegion().getRegionInfo().getRegionNameAsString());
344
345 return false;
346 }
347 long old = oldMTimes.get(e.getKey());
348 long now = e.getValue();
349 if (now <= old) {
350 LOG.info("AccessController on region " +
351 e.getKey().getRegion().getRegionInfo().getRegionNameAsString() +
352 " has not updated: mtime=" + now);
353 return false;
354 }
355 }
356 return true;
357 }
358 });
359 }
360
361
362
363
364
365
366 public static void grantGlobal(final HBaseTestingUtility util, final String user,
367 final Permission.Action... actions) throws Exception {
368 SecureTestUtil.updateACLs(util, new Callable<Void>() {
369 @Override
370 public Void call() throws Exception {
371 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
372 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
373 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
374 AccessControlService.BlockingInterface protocol =
375 AccessControlService.newBlockingStub(service);
376 ProtobufUtil.grant(null, protocol, user, actions);
377 }
378 }
379 return null;
380 }
381 });
382 }
383
384
385
386
387
388
389 public static void revokeGlobal(final HBaseTestingUtility util, final String user,
390 final Permission.Action... actions) throws Exception {
391 SecureTestUtil.updateACLs(util, new Callable<Void>() {
392 @Override
393 public Void call() throws Exception {
394 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
395 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
396 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
397 AccessControlService.BlockingInterface protocol =
398 AccessControlService.newBlockingStub(service);
399 ProtobufUtil.revoke(null, protocol, user, actions);
400 }
401 }
402 return null;
403 }
404 });
405 }
406
407
408
409
410
411
412 public static void grantOnNamespace(final HBaseTestingUtility util, final String user,
413 final String namespace, final Permission.Action... actions) throws Exception {
414 SecureTestUtil.updateACLs(util, new Callable<Void>() {
415 @Override
416 public Void call() throws Exception {
417 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
418 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
419 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
420 AccessControlService.BlockingInterface protocol =
421 AccessControlService.newBlockingStub(service);
422 ProtobufUtil.grant(null, protocol, user, namespace, actions);
423 }
424 }
425 return null;
426 }
427 });
428 }
429
430
431
432
433
434
435 public static void grantOnNamespaceUsingAccessControlClient(final HBaseTestingUtility util,
436 final Connection connection, final String user, final String namespace,
437 final Permission.Action... actions) throws Exception {
438 SecureTestUtil.updateACLs(util, new Callable<Void>() {
439 @Override
440 public Void call() throws Exception {
441 try {
442 AccessControlClient.grant(connection, namespace, user, actions);
443 } catch (Throwable t) {
444 LOG.error("grant failed: ", t);
445 }
446 return null;
447 }
448 });
449 }
450
451
452
453
454
455
456 public static void revokeFromNamespaceUsingAccessControlClient(final HBaseTestingUtility util,
457 final Connection connection, final String user, final String namespace,
458 final Permission.Action... actions) throws Exception {
459 SecureTestUtil.updateACLs(util, new Callable<Void>() {
460 @Override
461 public Void call() throws Exception {
462 try {
463 AccessControlClient.revoke(connection, namespace, user, actions);
464 } catch (Throwable t) {
465 LOG.error("revoke failed: ", t);
466 }
467 return null;
468 }
469 });
470 }
471
472
473
474
475
476
477 public static void revokeFromNamespace(final HBaseTestingUtility util, final String user,
478 final String namespace, final Permission.Action... actions) throws Exception {
479 SecureTestUtil.updateACLs(util, new Callable<Void>() {
480 @Override
481 public Void call() throws Exception {
482 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
483 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
484 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
485 AccessControlService.BlockingInterface protocol =
486 AccessControlService.newBlockingStub(service);
487 ProtobufUtil.revoke(null, protocol, user, namespace, actions);
488 }
489 }
490 return null;
491 }
492 });
493 }
494
495
496
497
498
499
500 public static void grantOnTable(final HBaseTestingUtility util, final String user,
501 final TableName table, final byte[] family, final byte[] qualifier,
502 final Permission.Action... actions) throws Exception {
503 SecureTestUtil.updateACLs(util, new Callable<Void>() {
504 @Override
505 public Void call() throws Exception {
506 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
507 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
508 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
509 AccessControlService.BlockingInterface protocol =
510 AccessControlService.newBlockingStub(service);
511 ProtobufUtil.grant(null, protocol, user, table, family, qualifier, actions);
512 }
513 }
514 return null;
515 }
516 });
517 }
518
519
520
521
522
523
524 public static void grantOnTableUsingAccessControlClient(final HBaseTestingUtility util,
525 final Connection connection, final String user, final TableName table, final byte[] family,
526 final byte[] qualifier, final Permission.Action... actions) throws Exception {
527 SecureTestUtil.updateACLs(util, new Callable<Void>() {
528 @Override
529 public Void call() throws Exception {
530 try {
531 AccessControlClient.grant(connection, table, user, family, qualifier, actions);
532 } catch (Throwable t) {
533 LOG.error("grant failed: ", t);
534 }
535 return null;
536 }
537 });
538 }
539
540
541
542
543
544
545 public static void grantGlobalUsingAccessControlClient(final HBaseTestingUtility util,
546 final Connection connection, final String user, final Permission.Action... actions)
547 throws Exception {
548 SecureTestUtil.updateACLs(util, new Callable<Void>() {
549 @Override
550 public Void call() throws Exception {
551 try {
552 AccessControlClient.grant(connection, user, actions);
553 } catch (Throwable t) {
554 LOG.error("grant failed: ", t);
555 }
556 return null;
557 }
558 });
559 }
560
561
562
563
564
565
566 public static void revokeFromTable(final HBaseTestingUtility util, final String user,
567 final TableName table, final byte[] family, final byte[] qualifier,
568 final Permission.Action... actions) throws Exception {
569 SecureTestUtil.updateACLs(util, new Callable<Void>() {
570 @Override
571 public Void call() throws Exception {
572 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
573 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
574 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
575 AccessControlService.BlockingInterface protocol =
576 AccessControlService.newBlockingStub(service);
577 ProtobufUtil.revoke(null, protocol, user, table, family, qualifier, actions);
578 }
579 }
580 return null;
581 }
582 });
583 }
584
585
586
587
588
589
590 public static void revokeFromTableUsingAccessControlClient(final HBaseTestingUtility util,
591 final Connection connection, final String user, final TableName table, final byte[] family,
592 final byte[] qualifier, final Permission.Action... actions) throws Exception {
593 SecureTestUtil.updateACLs(util, new Callable<Void>() {
594 @Override
595 public Void call() throws Exception {
596 try {
597 AccessControlClient.revoke(connection, table, user, family, qualifier, actions);
598 } catch (Throwable t) {
599 LOG.error("revoke failed: ", t);
600 }
601 return null;
602 }
603 });
604 }
605
606
607
608
609
610
611 public static void revokeGlobalUsingAccessControlClient(final HBaseTestingUtility util,
612 final Connection connection, final String user,final Permission.Action... actions)
613 throws Exception {
614 SecureTestUtil.updateACLs(util, new Callable<Void>() {
615 @Override
616 public Void call() throws Exception {
617 try {
618 AccessControlClient.revoke(connection, user, actions);
619 } catch (Throwable t) {
620 LOG.error("revoke failed: ", t);
621 }
622 return null;
623 }
624 });
625 }
626
627 public static class MasterSyncObserver extends BaseMasterObserver {
628 volatile CountDownLatch tableCreationLatch = null;
629 volatile CountDownLatch tableDeletionLatch = null;
630
631 @Override
632 public void postCreateTableHandler(
633 final ObserverContext<MasterCoprocessorEnvironment> ctx,
634 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
635
636 if (tableCreationLatch != null) {
637 tableCreationLatch.countDown();
638 }
639 }
640
641 @Override
642 public void postDeleteTableHandler(
643 final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
644 throws IOException {
645
646 if (tableDeletionLatch != null) {
647 tableDeletionLatch.countDown();
648 }
649 }
650 }
651
652 public static Table createTable(HBaseTestingUtility testUtil, TableName tableName,
653 byte[][] families) throws Exception {
654 HTableDescriptor htd = new HTableDescriptor(tableName);
655 for (byte[] family : families) {
656 HColumnDescriptor hcd = new HColumnDescriptor(family);
657 htd.addFamily(hcd);
658 }
659 createTable(testUtil, testUtil.getHBaseAdmin(), htd);
660 return testUtil.getConnection().getTable(htd.getTableName());
661 }
662
663 public static void createTable(HBaseTestingUtility testUtil, HTableDescriptor htd)
664 throws Exception {
665 createTable(testUtil, testUtil.getHBaseAdmin(), htd);
666 }
667
668 public static void createTable(HBaseTestingUtility testUtil, HTableDescriptor htd,
669 byte[][] splitKeys) throws Exception {
670 createTable(testUtil, testUtil.getHBaseAdmin(), htd, splitKeys);
671 }
672
673 public static void createTable(HBaseTestingUtility testUtil, Admin admin, HTableDescriptor htd)
674 throws Exception {
675 createTable(testUtil, admin, htd, null);
676 }
677
678 public static void createTable(HBaseTestingUtility testUtil, Admin admin, HTableDescriptor htd,
679 byte[][] splitKeys) throws Exception {
680
681
682 MasterSyncObserver observer = (MasterSyncObserver)testUtil.getHBaseCluster().getMaster()
683 .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
684 observer.tableCreationLatch = new CountDownLatch(1);
685 if (splitKeys != null) {
686 admin.createTable(htd, splitKeys);
687 } else {
688 admin.createTable(htd);
689 }
690 observer.tableCreationLatch.await();
691 observer.tableCreationLatch = null;
692 testUtil.waitUntilAllRegionsAssigned(htd.getTableName());
693 }
694
695 public static void deleteTable(HBaseTestingUtility testUtil, TableName tableName)
696 throws Exception {
697 deleteTable(testUtil, testUtil.getHBaseAdmin(), tableName);
698 }
699
700 public static void createNamespace(HBaseTestingUtility testUtil, NamespaceDescriptor nsDesc)
701 throws Exception {
702 testUtil.getHBaseAdmin().createNamespace(nsDesc);
703 }
704
705 public static void deleteNamespace(HBaseTestingUtility testUtil, String namespace)
706 throws Exception {
707 testUtil.getHBaseAdmin().deleteNamespace(namespace);
708 }
709
710 public static void deleteTable(HBaseTestingUtility testUtil, Admin admin, TableName tableName)
711 throws Exception {
712
713
714 MasterSyncObserver observer = null;
715 HMaster master = testUtil.getHBaseCluster().getMaster();
716 if (master != null) {
717 observer = (MasterSyncObserver)master.getMasterCoprocessorHost()
718 .findCoprocessor(MasterSyncObserver.class.getName());
719 if (observer != null) {
720 observer.tableDeletionLatch = new CountDownLatch(1);
721 }
722 }
723 try {
724 admin.disableTable(tableName);
725 } catch (TableNotEnabledException e) {
726 LOG.debug("Table: " + tableName + " already disabled, so just deleting it.");
727 }
728 admin.deleteTable(tableName);
729 if (observer != null) {
730 observer.tableDeletionLatch.await();
731 observer.tableDeletionLatch = null;
732 }
733 }
734
735 public static String convertToNamespace(String namespace) {
736 return AccessControlLists.NAMESPACE_PREFIX + namespace;
737 }
738
739 public static void checkGlobalPerms(HBaseTestingUtility testUtil, Permission.Action... actions)
740 throws IOException {
741 Permission[] perms = new Permission[actions.length];
742 for (int i = 0; i < actions.length; i++) {
743 perms[i] = new Permission(actions[i]);
744 }
745 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
746 for (Action a : actions) {
747 request.addPermission(AccessControlProtos.Permission.newBuilder()
748 .setType(AccessControlProtos.Permission.Type.Global)
749 .setGlobalPermission(
750 AccessControlProtos.GlobalPermission.newBuilder()
751 .addAction(ProtobufUtil.toPermissionAction(a)).build()));
752 }
753 try(Connection conn = ConnectionFactory.createConnection(testUtil.getConfiguration());
754 Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
755 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
756 AccessControlService.BlockingInterface protocol =
757 AccessControlService.newBlockingStub(channel);
758 try {
759 protocol.checkPermissions(null, request.build());
760 } catch (ServiceException se) {
761 ProtobufUtil.toIOException(se);
762 }
763 }
764 }
765
766 public static void checkTablePerms(HBaseTestingUtility testUtil, TableName table, byte[] family,
767 byte[] column, Permission.Action... actions) throws IOException {
768 Permission[] perms = new Permission[actions.length];
769 for (int i = 0; i < actions.length; i++) {
770 perms[i] = new TablePermission(table, family, column, actions[i]);
771 }
772 checkTablePerms(testUtil, table, perms);
773 }
774
775 public static void checkTablePerms(HBaseTestingUtility testUtil, TableName table,
776 Permission... perms) throws IOException {
777 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
778 for (Permission p : perms) {
779 request.addPermission(ProtobufUtil.toPermission(p));
780 }
781
782 try(Connection conn = ConnectionFactory.createConnection(testUtil.getConfiguration());
783 Table acl = conn.getTable(table)) {
784 AccessControlService.BlockingInterface protocol =
785 AccessControlService.newBlockingStub(acl.coprocessorService(new byte[0]));
786 try {
787 protocol.checkPermissions(null, request.build());
788 } catch (ServiceException se) {
789 ProtobufUtil.toIOException(se);
790 }
791 }
792 }
793
794 }