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.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.IOException;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.NavigableMap;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.fs.FileStatus;
35 import org.apache.hadoop.fs.FileSystem;
36 import org.apache.hadoop.fs.Path;
37 import org.apache.hadoop.fs.permission.FsPermission;
38 import org.apache.hadoop.hbase.Coprocessor;
39 import org.apache.hadoop.hbase.CoprocessorEnvironment;
40 import org.apache.hadoop.hbase.HBaseTestingUtility;
41 import org.apache.hadoop.hbase.HColumnDescriptor;
42 import org.apache.hadoop.hbase.HConstants;
43 import org.apache.hadoop.hbase.HRegionInfo;
44 import org.apache.hadoop.hbase.HTableDescriptor;
45 import org.apache.hadoop.hbase.KeyValue;
46 import org.apache.hadoop.hbase.LargeTests;
47 import org.apache.hadoop.hbase.MiniHBaseCluster;
48 import org.apache.hadoop.hbase.ServerName;
49 import org.apache.hadoop.hbase.TableName;
50 import org.apache.hadoop.hbase.TableNotFoundException;
51 import org.apache.hadoop.hbase.client.Append;
52 import org.apache.hadoop.hbase.client.Delete;
53 import org.apache.hadoop.hbase.client.Get;
54 import org.apache.hadoop.hbase.client.HBaseAdmin;
55 import org.apache.hadoop.hbase.client.HTable;
56 import org.apache.hadoop.hbase.client.Increment;
57 import org.apache.hadoop.hbase.client.Put;
58 import org.apache.hadoop.hbase.client.Result;
59 import org.apache.hadoop.hbase.client.ResultScanner;
60 import org.apache.hadoop.hbase.client.Scan;
61 import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
62 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
63 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
64 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
65 import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
66 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.CountRequest;
67 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.CountResponse;
68 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.HelloRequest;
69 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.HelloResponse;
70 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.IncrementCountRequest;
71 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.IncrementCountResponse;
72 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.NoopRequest;
73 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.NoopResponse;
74 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingRequest;
75 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingResponse;
76 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingService;
77 import org.apache.hadoop.hbase.io.hfile.CacheConfig;
78 import org.apache.hadoop.hbase.io.hfile.HFile;
79 import org.apache.hadoop.hbase.io.hfile.HFileContext;
80 import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder;
81 import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
82 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
83 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
84 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
85 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
86 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.CheckPermissionsRequest;
87 import org.apache.hadoop.hbase.regionserver.HRegion;
88 import org.apache.hadoop.hbase.regionserver.HRegionServer;
89 import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost;
90 import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
91 import org.apache.hadoop.hbase.regionserver.ScanType;
92 import org.apache.hadoop.hbase.security.User;
93 import org.apache.hadoop.hbase.security.access.Permission.Action;
94 import org.apache.hadoop.hbase.util.Bytes;
95 import org.apache.hadoop.hbase.util.JVMClusterUtil;
96 import org.apache.hadoop.hbase.util.TestTableName;
97
98 import org.apache.log4j.Level;
99 import org.apache.log4j.Logger;
100
101 import org.junit.After;
102 import org.junit.AfterClass;
103 import org.junit.Before;
104 import org.junit.BeforeClass;
105 import org.junit.Rule;
106 import org.junit.Test;
107 import org.junit.experimental.categories.Category;
108
109 import com.google.protobuf.BlockingRpcChannel;
110 import com.google.protobuf.RpcCallback;
111 import com.google.protobuf.RpcController;
112 import com.google.protobuf.Service;
113 import com.google.protobuf.ServiceException;
114
115
116
117
118
119 @Category(LargeTests.class)
120 public class TestAccessController extends SecureTestUtil {
121 private static final Log LOG = LogFactory.getLog(TestAccessController.class);
122
123 static {
124 Logger.getLogger(AccessController.class).setLevel(Level.TRACE);
125 Logger.getLogger(AccessControlFilter.class).setLevel(Level.TRACE);
126 Logger.getLogger(TableAuthManager.class).setLevel(Level.TRACE);
127 }
128
129 @Rule public TestTableName TEST_TABLE = new TestTableName();
130 private static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
131 private static Configuration conf;
132
133
134 private static User SUPERUSER;
135
136 private static User USER_ADMIN;
137
138 private static User USER_RW;
139
140 private static User USER_RO;
141
142 private static User USER_OWNER;
143
144 private static User USER_CREATE;
145
146 private static User USER_NONE;
147
148 private static TableName TEST_TABLE2 = TableName.valueOf("testtable2");
149 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
150 private static byte[] TEST_QUALIFIER = Bytes.toBytes("q1");
151 private static byte[] TEST_ROW = Bytes.toBytes("r1");
152
153 private static MasterCoprocessorEnvironment CP_ENV;
154 private static AccessController ACCESS_CONTROLLER;
155 private static RegionServerCoprocessorEnvironment RSCP_ENV;
156 private RegionCoprocessorEnvironment RCP_ENV;
157
158 @BeforeClass
159 public static void setupBeforeClass() throws Exception {
160
161 conf = TEST_UTIL.getConfiguration();
162 conf.set("hbase.master.hfilecleaner.plugins",
163 "org.apache.hadoop.hbase.master.cleaner.HFileLinkCleaner," +
164 "org.apache.hadoop.hbase.master.snapshot.SnapshotHFileCleaner");
165 conf.set("hbase.master.logcleaner.plugins",
166 "org.apache.hadoop.hbase.master.snapshot.SnapshotLogCleaner");
167
168 enableSecurity(conf);
169
170 verifyConfiguration(conf);
171
172
173 conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true);
174
175 TEST_UTIL.startMiniCluster();
176 MasterCoprocessorHost cpHost = TEST_UTIL.getMiniHBaseCluster().getMaster().getCoprocessorHost();
177 cpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf);
178 ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(AccessController.class.getName());
179 CP_ENV = cpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
180 Coprocessor.PRIORITY_HIGHEST, 1, conf);
181 RegionServerCoprocessorHost rsHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
182 .getCoprocessorHost();
183 RSCP_ENV = rsHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
184 Coprocessor.PRIORITY_HIGHEST, 1, conf);
185
186
187 TEST_UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME.getName());
188
189
190 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
191 USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]);
192 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
193 USER_RO = User.createUserForTesting(conf, "rouser", new String[0]);
194 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]);
195 USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]);
196 USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]);
197 }
198
199 @AfterClass
200 public static void tearDownAfterClass() throws Exception {
201 TEST_UTIL.shutdownMiniCluster();
202 }
203
204 @Before
205 public void setUp() throws Exception {
206
207 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
208 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
209 HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY);
210 hcd.setMaxVersions(100);
211 htd.addFamily(hcd);
212 htd.setOwner(USER_OWNER);
213 admin.createTable(htd, new byte[][] { Bytes.toBytes("s") });
214 TEST_UTIL.waitTableEnabled(TEST_TABLE.getTableName().getName());
215
216 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(TEST_TABLE.getTableName()).get(0);
217 RegionCoprocessorHost rcpHost = region.getCoprocessorHost();
218 RCP_ENV = rcpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
219 Coprocessor.PRIORITY_HIGHEST, 1, conf);
220
221
222
223 grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(),
224 Permission.Action.ADMIN,
225 Permission.Action.CREATE,
226 Permission.Action.READ,
227 Permission.Action.WRITE);
228
229 grantOnTable(TEST_UTIL, USER_RW.getShortName(),
230 TEST_TABLE.getTableName(), TEST_FAMILY, null,
231 Permission.Action.READ,
232 Permission.Action.WRITE);
233
234
235 grantOnTable(TEST_UTIL, USER_CREATE.getShortName(),
236 TEST_TABLE.getTableName(), null, null,
237 Permission.Action.CREATE,
238 Permission.Action.READ,
239 Permission.Action.WRITE);
240
241 grantOnTable(TEST_UTIL, USER_RO.getShortName(),
242 TEST_TABLE.getTableName(), TEST_FAMILY, null,
243 Permission.Action.READ);
244
245 assertEquals(4, AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()).size());
246 }
247
248 @After
249 public void tearDown() throws Exception {
250
251 try {
252 TEST_UTIL.deleteTable(TEST_TABLE.getTableName());
253 } catch (TableNotFoundException ex) {
254
255 LOG.info("Test deleted table " + TEST_TABLE.getTableName());
256 }
257 assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()).size());
258 }
259
260 @Test
261 public void testTableCreate() throws Exception {
262 AccessTestAction createTable = new AccessTestAction() {
263 @Override
264 public Object run() throws Exception {
265 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testnewtable"));
266 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
267 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
268 return null;
269 }
270 };
271
272
273 verifyAllowed(createTable, SUPERUSER, USER_ADMIN);
274
275
276 verifyDenied(createTable, USER_CREATE, USER_RW, USER_RO, USER_NONE);
277 }
278
279 @Test
280 public void testTableModify() throws Exception {
281 AccessTestAction modifyTable = new AccessTestAction() {
282 @Override
283 public Object run() throws Exception {
284 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
285 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
286 htd.addFamily(new HColumnDescriptor("fam_" + User.getCurrent().getShortName()));
287 ACCESS_CONTROLLER.preModifyTable(ObserverContext.createAndPrepare(CP_ENV, null),
288 TEST_TABLE.getTableName(), htd);
289 return null;
290 }
291 };
292
293 verifyAllowed(modifyTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
294 verifyDenied(modifyTable, USER_RW, USER_RO, USER_NONE);
295 }
296
297 @Test
298 public void testTableDelete() throws Exception {
299 AccessTestAction deleteTable = new AccessTestAction() {
300 @Override
301 public Object run() throws Exception {
302 ACCESS_CONTROLLER
303 .preDeleteTable(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE.getTableName());
304 return null;
305 }
306 };
307
308 verifyAllowed(deleteTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
309 verifyDenied(deleteTable, USER_RW, USER_RO, USER_NONE);
310 }
311
312 @Test
313 public void testAddColumn() throws Exception {
314 final HColumnDescriptor hcd = new HColumnDescriptor("fam_new");
315 AccessTestAction action = new AccessTestAction() {
316 @Override
317 public Object run() throws Exception {
318 ACCESS_CONTROLLER.preAddColumn(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE.getTableName(),
319 hcd);
320 return null;
321 }
322 };
323
324 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
325 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
326 }
327
328 @Test
329 public void testModifyColumn() throws Exception {
330 final HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY);
331 hcd.setMaxVersions(10);
332 AccessTestAction action = new AccessTestAction() {
333 @Override
334 public Object run() throws Exception {
335 ACCESS_CONTROLLER.preModifyColumn(ObserverContext.createAndPrepare(CP_ENV, null),
336 TEST_TABLE.getTableName(), hcd);
337 return null;
338 }
339 };
340
341 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
342 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
343 }
344
345 @Test
346 public void testDeleteColumn() throws Exception {
347 AccessTestAction action = new AccessTestAction() {
348 @Override
349 public Object run() throws Exception {
350 ACCESS_CONTROLLER.preDeleteColumn(ObserverContext.createAndPrepare(CP_ENV, null),
351 TEST_TABLE.getTableName(), TEST_FAMILY);
352 return null;
353 }
354 };
355
356 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
357 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
358 }
359
360 @Test
361 public void testTableDisable() throws Exception {
362 AccessTestAction disableTable = new AccessTestAction() {
363 @Override
364 public Object run() throws Exception {
365 ACCESS_CONTROLLER.preDisableTable(ObserverContext.createAndPrepare(CP_ENV, null),
366 TEST_TABLE.getTableName());
367 return null;
368 }
369 };
370
371 AccessTestAction disableAclTable = new AccessTestAction() {
372 @Override
373 public Object run() throws Exception {
374 ACCESS_CONTROLLER.preDisableTable(ObserverContext.createAndPrepare(CP_ENV, null),
375 AccessControlLists.ACL_TABLE_NAME);
376 return null;
377 }
378 };
379
380 verifyAllowed(disableTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
381 verifyDenied(disableTable, USER_RW, USER_RO, USER_NONE);
382
383
384 verifyDenied(disableAclTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_RW, USER_RO);
385 }
386
387 @Test
388 public void testTableEnable() throws Exception {
389 AccessTestAction enableTable = new AccessTestAction() {
390 @Override
391 public Object run() throws Exception {
392 ACCESS_CONTROLLER
393 .preEnableTable(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE.getTableName());
394 return null;
395 }
396 };
397
398 verifyAllowed(enableTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
399 verifyDenied(enableTable, USER_RW, USER_RO, USER_NONE);
400 }
401
402 @Test
403 public void testMove() throws Exception {
404 Map<HRegionInfo, ServerName> regions;
405 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
406 try {
407 regions = table.getRegionLocations();
408 } finally {
409 table.close();
410 }
411 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
412 final ServerName server = TEST_UTIL.getHBaseCluster().getRegionServer(0).getServerName();
413 AccessTestAction action = new AccessTestAction() {
414 @Override
415 public Object run() throws Exception {
416 ACCESS_CONTROLLER.preMove(ObserverContext.createAndPrepare(CP_ENV, null),
417 firstRegion.getKey(), server, server);
418 return null;
419 }
420 };
421
422 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
423 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
424 }
425
426 @Test
427 public void testAssign() throws Exception {
428 Map<HRegionInfo, ServerName> regions;
429 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
430 try {
431 regions = table.getRegionLocations();
432 } finally {
433 table.close();
434 }
435 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
436
437 AccessTestAction action = new AccessTestAction() {
438 @Override
439 public Object run() throws Exception {
440 ACCESS_CONTROLLER.preAssign(ObserverContext.createAndPrepare(CP_ENV, null),
441 firstRegion.getKey());
442 return null;
443 }
444 };
445
446 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
447 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
448 }
449
450 @Test
451 public void testUnassign() throws Exception {
452 Map<HRegionInfo, ServerName> regions;
453 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
454 try {
455 regions = table.getRegionLocations();
456 } finally {
457 table.close();
458 }
459 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
460
461 AccessTestAction action = new AccessTestAction() {
462 @Override
463 public Object run() throws Exception {
464 ACCESS_CONTROLLER.preUnassign(ObserverContext.createAndPrepare(CP_ENV, null),
465 firstRegion.getKey(), false);
466 return null;
467 }
468 };
469
470 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
471 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
472 }
473
474 @Test
475 public void testRegionOffline() throws Exception {
476 Map<HRegionInfo, ServerName> regions;
477 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
478 try {
479 regions = table.getRegionLocations();
480 } finally {
481 table.close();
482 }
483 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
484
485 AccessTestAction action = new AccessTestAction() {
486 @Override
487 public Object run() throws Exception {
488 ACCESS_CONTROLLER.preRegionOffline(ObserverContext.createAndPrepare(CP_ENV, null),
489 firstRegion.getKey());
490 return null;
491 }
492 };
493
494 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
495 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
496 }
497
498 @Test
499 public void testBalance() throws Exception {
500 AccessTestAction action = new AccessTestAction() {
501 @Override
502 public Object run() throws Exception {
503 ACCESS_CONTROLLER.preBalance(ObserverContext.createAndPrepare(CP_ENV, null));
504 return null;
505 }
506 };
507
508 verifyAllowed(action, SUPERUSER, USER_ADMIN);
509 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
510 }
511
512 @Test
513 public void testBalanceSwitch() throws Exception {
514 AccessTestAction action = new AccessTestAction() {
515 @Override
516 public Object run() throws Exception {
517 ACCESS_CONTROLLER.preBalanceSwitch(ObserverContext.createAndPrepare(CP_ENV, null), true);
518 return null;
519 }
520 };
521
522 verifyAllowed(action, SUPERUSER, USER_ADMIN);
523 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
524 }
525
526 @Test
527 public void testShutdown() throws Exception {
528 AccessTestAction action = new AccessTestAction() {
529 @Override
530 public Object run() throws Exception {
531 ACCESS_CONTROLLER.preShutdown(ObserverContext.createAndPrepare(CP_ENV, null));
532 return null;
533 }
534 };
535
536 verifyAllowed(action, SUPERUSER, USER_ADMIN);
537 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
538 }
539
540 @Test
541 public void testStopMaster() throws Exception {
542 AccessTestAction action = new AccessTestAction() {
543 @Override
544 public Object run() throws Exception {
545 ACCESS_CONTROLLER.preStopMaster(ObserverContext.createAndPrepare(CP_ENV, null));
546 return null;
547 }
548 };
549
550 verifyAllowed(action, SUPERUSER, USER_ADMIN);
551 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
552 }
553
554 private void verifyWrite(AccessTestAction action) throws Exception {
555 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW);
556 verifyDenied(action, USER_NONE, USER_RO);
557 }
558
559 @Test
560 public void testSplit() throws Exception {
561 AccessTestAction action = new AccessTestAction() {
562 @Override
563 public Object run() throws Exception {
564 ACCESS_CONTROLLER.preSplit(ObserverContext.createAndPrepare(RCP_ENV, null));
565 return null;
566 }
567 };
568
569 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
570 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
571 }
572
573 @Test
574 public void testSplitWithSplitRow() throws Exception {
575 AccessTestAction action = new AccessTestAction() {
576 @Override
577 public Object run() throws Exception {
578 ACCESS_CONTROLLER.preSplit(
579 ObserverContext.createAndPrepare(RCP_ENV, null),
580 TEST_ROW);
581 return null;
582 }
583 };
584
585 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
586 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
587 }
588
589 @Test
590 public void testMergeRegions() throws Exception {
591
592 final List<HRegion> regions = TEST_UTIL.getHBaseCluster().findRegionsForTable(TEST_TABLE.getTableName());
593
594 AccessTestAction action = new AccessTestAction() {
595 @Override
596 public Object run() throws Exception {
597 ACCESS_CONTROLLER.preMerge(
598 ObserverContext.createAndPrepare(RSCP_ENV, null),
599 regions.get(0),regions.get(1));
600 return null;
601 }
602 };
603
604 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
605 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
606 }
607
608 @Test
609 public void testFlush() throws Exception {
610 AccessTestAction action = new AccessTestAction() {
611 @Override
612 public Object run() throws Exception {
613 ACCESS_CONTROLLER.preFlush(ObserverContext.createAndPrepare(RCP_ENV, null));
614 return null;
615 }
616 };
617
618 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
619 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
620 }
621
622 @Test
623 public void testCompact() throws Exception {
624 AccessTestAction action = new AccessTestAction() {
625 @Override
626 public Object run() throws Exception {
627 ACCESS_CONTROLLER.preCompact(ObserverContext.createAndPrepare(RCP_ENV, null), null, null,
628 ScanType.COMPACT_RETAIN_DELETES);
629 return null;
630 }
631 };
632
633 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
634 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
635 }
636
637 @Test
638 public void testPreCompactSelection() throws Exception {
639 AccessTestAction action = new AccessTestAction() {
640 @Override
641 public Object run() throws Exception {
642 ACCESS_CONTROLLER.preCompactSelection(ObserverContext.createAndPrepare(RCP_ENV, null), null, null);
643 return null;
644 }
645 };
646
647 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
648 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
649 }
650
651 private void verifyRead(AccessTestAction action) throws Exception {
652 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO);
653 verifyDenied(action, USER_NONE);
654 }
655
656 private void verifyReadWrite(AccessTestAction action) throws Exception {
657 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW);
658 verifyDenied(action, USER_NONE, USER_RO);
659 }
660
661 @Test
662 public void testRead() throws Exception {
663
664 AccessTestAction getAction = new AccessTestAction() {
665 @Override
666 public Object run() throws Exception {
667 Get g = new Get(TEST_ROW);
668 g.addFamily(TEST_FAMILY);
669 HTable t = new HTable(conf, TEST_TABLE.getTableName());
670 try {
671 t.get(g);
672 } finally {
673 t.close();
674 }
675 return null;
676 }
677 };
678 verifyRead(getAction);
679
680
681 AccessTestAction scanAction = new AccessTestAction() {
682 @Override
683 public Object run() throws Exception {
684 Scan s = new Scan();
685 s.addFamily(TEST_FAMILY);
686
687 HTable table = new HTable(conf, TEST_TABLE.getTableName());
688 try {
689 ResultScanner scanner = table.getScanner(s);
690 try {
691 for (Result r = scanner.next(); r != null; r = scanner.next()) {
692
693 }
694 } catch (IOException e) {
695 } finally {
696 scanner.close();
697 }
698 } finally {
699 table.close();
700 }
701 return null;
702 }
703 };
704 verifyRead(scanAction);
705 }
706
707 @Test
708
709 public void testWrite() throws Exception {
710
711 AccessTestAction putAction = new AccessTestAction() {
712 @Override
713 public Object run() throws Exception {
714 Put p = new Put(TEST_ROW);
715 p.add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(1));
716 HTable t = new HTable(conf, TEST_TABLE.getTableName());
717 try {
718 t.put(p);
719 } finally {
720 t.close();
721 }
722 return null;
723 }
724 };
725 verifyWrite(putAction);
726
727
728 AccessTestAction deleteAction = new AccessTestAction() {
729 @Override
730 public Object run() throws Exception {
731 Delete d = new Delete(TEST_ROW);
732 d.deleteFamily(TEST_FAMILY);
733 HTable t = new HTable(conf, TEST_TABLE.getTableName());
734 try {
735 t.delete(d);
736 } finally {
737 t.close();
738 }
739 return null;
740 }
741 };
742 verifyWrite(deleteAction);
743
744
745 AccessTestAction incrementAction = new AccessTestAction() {
746 @Override
747 public Object run() throws Exception {
748 Increment inc = new Increment(TEST_ROW);
749 inc.addColumn(TEST_FAMILY, TEST_QUALIFIER, 1);
750 HTable t = new HTable(conf, TEST_TABLE.getTableName());
751 try {
752 t.increment(inc);
753 } finally {
754 t.close();
755 }
756 return null;
757 }
758 };
759 verifyWrite(incrementAction);
760 }
761
762 @Test
763 public void testReadWrite() throws Exception {
764
765 AccessTestAction checkAndDeleteAction = new AccessTestAction() {
766 @Override
767 public Object run() throws Exception {
768 Delete d = new Delete(TEST_ROW);
769 d.deleteFamily(TEST_FAMILY);
770 HTable t = new HTable(conf, TEST_TABLE.getTableName());
771 try {
772 t.checkAndDelete(TEST_ROW, TEST_FAMILY, TEST_QUALIFIER,
773 Bytes.toBytes("test_value"), d);
774 } finally {
775 t.close();
776 }
777 return null;
778 }
779 };
780 verifyReadWrite(checkAndDeleteAction);
781
782
783 AccessTestAction checkAndPut = new AccessTestAction() {
784 @Override
785 public Object run() throws Exception {
786 Put p = new Put(TEST_ROW);
787 p.add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(1));
788 HTable t = new HTable(conf, TEST_TABLE.getTableName());
789 try {
790 t.checkAndPut(TEST_ROW, TEST_FAMILY, TEST_QUALIFIER,
791 Bytes.toBytes("test_value"), p);
792 } finally {
793 t.close();
794 }
795 return null;
796 }
797 };
798 verifyReadWrite(checkAndPut);
799 }
800
801 @Test
802 public void testBulkLoad() throws Exception {
803 FileSystem fs = TEST_UTIL.getTestFileSystem();
804 final Path dir = TEST_UTIL.getDataTestDirOnTestFS("testBulkLoad");
805 fs.mkdirs(dir);
806
807
808 fs.setPermission(dir, FsPermission.valueOf("-rwxrwxrwx"));
809
810 AccessTestAction bulkLoadAction = new AccessTestAction() {
811 @Override
812 public Object run() throws Exception {
813 int numRows = 3;
814
815
816 byte[][][] hfileRanges = {{{(byte)0}, {(byte)9}}};
817
818 Path bulkLoadBasePath = new Path(dir, new Path(User.getCurrent().getName()));
819 new BulkLoadHelper(bulkLoadBasePath)
820 .bulkLoadHFile(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_QUALIFIER, hfileRanges, numRows);
821
822 return null;
823 }
824 };
825
826
827
828 verifyAllowed(bulkLoadAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
829 verifyDenied(bulkLoadAction, USER_RW, USER_NONE, USER_RO);
830
831
832 TEST_UTIL.getHBaseAdmin().disableTable(TEST_TABLE.getTableName());
833 TEST_UTIL.getHBaseAdmin().enableTable(TEST_TABLE.getTableName());
834 }
835
836 public class BulkLoadHelper {
837 private final FileSystem fs;
838 private final Path loadPath;
839 private final Configuration conf;
840
841 public BulkLoadHelper(Path loadPath) throws IOException {
842 fs = TEST_UTIL.getTestFileSystem();
843 conf = TEST_UTIL.getConfiguration();
844 loadPath = loadPath.makeQualified(fs);
845 this.loadPath = loadPath;
846 }
847
848 private void createHFile(Path path,
849 byte[] family, byte[] qualifier,
850 byte[] startKey, byte[] endKey, int numRows) throws IOException {
851
852 HFile.Writer writer = null;
853 long now = System.currentTimeMillis();
854 try {
855 HFileContext context = new HFileContextBuilder().build();
856 writer = HFile.getWriterFactory(conf, new CacheConfig(conf))
857 .withPath(fs, path)
858 .withFileContext(context)
859 .create();
860
861 for (byte[] key : Bytes.iterateOnSplits(startKey, endKey, true, numRows-2)) {
862 KeyValue kv = new KeyValue(key, family, qualifier, now, key);
863 writer.append(kv);
864 }
865 } finally {
866 if(writer != null)
867 writer.close();
868 }
869 }
870
871 private void bulkLoadHFile(
872 TableName tableName,
873 byte[] family,
874 byte[] qualifier,
875 byte[][][] hfileRanges,
876 int numRowsPerRange) throws Exception {
877
878 Path familyDir = new Path(loadPath, Bytes.toString(family));
879 fs.mkdirs(familyDir);
880 int hfileIdx = 0;
881 for (byte[][] range : hfileRanges) {
882 byte[] from = range[0];
883 byte[] to = range[1];
884 createHFile(new Path(familyDir, "hfile_"+(hfileIdx++)),
885 family, qualifier, from, to, numRowsPerRange);
886 }
887
888 setPermission(loadPath, FsPermission.valueOf("-rwxrwxrwx"));
889
890 HTable table = new HTable(conf, tableName);
891 try {
892 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
893 TEST_UTIL.waitTableEnabled(admin, tableName.getName());
894 LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf);
895 loader.doBulkLoad(loadPath, table);
896 } finally {
897 table.close();
898 }
899 }
900
901 public void setPermission(Path dir, FsPermission perm) throws IOException {
902 if(!fs.getFileStatus(dir).isDir()) {
903 fs.setPermission(dir,perm);
904 }
905 else {
906 for(FileStatus el : fs.listStatus(dir)) {
907 fs.setPermission(el.getPath(), perm);
908 setPermission(el.getPath() , perm);
909 }
910 }
911 }
912 }
913
914 @Test
915 public void testAppend() throws Exception {
916
917 AccessTestAction appendAction = new AccessTestAction() {
918 @Override
919 public Object run() throws Exception {
920 byte[] row = TEST_ROW;
921 byte[] qualifier = TEST_QUALIFIER;
922 Put put = new Put(row);
923 put.add(TEST_FAMILY, qualifier, Bytes.toBytes(1));
924 Append append = new Append(row);
925 append.add(TEST_FAMILY, qualifier, Bytes.toBytes(2));
926 HTable t = new HTable(conf, TEST_TABLE.getTableName());
927 try {
928 t.put(put);
929 t.append(append);
930 } finally {
931 t.close();
932 }
933 return null;
934 }
935 };
936
937 verifyAllowed(appendAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW);
938 verifyDenied(appendAction, USER_RO, USER_NONE);
939 }
940
941 @Test
942 public void testGrantRevoke() throws Exception {
943 AccessTestAction grantAction = new AccessTestAction() {
944 @Override
945 public Object run() throws Exception {
946 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
947 try {
948 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
949 AccessControlService.BlockingInterface protocol =
950 AccessControlService.newBlockingStub(service);
951 ProtobufUtil.grant(protocol, USER_RO.getShortName(), TEST_TABLE.getTableName(),
952 TEST_FAMILY, null, Action.READ);
953 } finally {
954 acl.close();
955 }
956 return null;
957 }
958 };
959
960 AccessTestAction revokeAction = new AccessTestAction() {
961 @Override
962 public Object run() throws Exception {
963 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
964 try {
965 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
966 AccessControlService.BlockingInterface protocol =
967 AccessControlService.newBlockingStub(service);
968 ProtobufUtil.revoke(protocol, USER_RO.getShortName(), TEST_TABLE.getTableName(),
969 TEST_FAMILY, null, Action.READ);
970 } finally {
971 acl.close();
972 }
973 return null;
974 }
975 };
976
977 AccessTestAction getPermissionsAction = new AccessTestAction() {
978 @Override
979 public Object run() throws Exception {
980 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
981 try {
982 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
983 AccessControlService.BlockingInterface protocol =
984 AccessControlService.newBlockingStub(service);
985 ProtobufUtil.getUserPermissions(protocol, TEST_TABLE.getTableName());
986 } finally {
987 acl.close();
988 }
989 return null;
990 }
991 };
992
993 verifyAllowed(grantAction, SUPERUSER, USER_ADMIN, USER_OWNER);
994 verifyDenied(grantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE);
995
996 verifyAllowed(revokeAction, SUPERUSER, USER_ADMIN, USER_OWNER);
997 verifyDenied(revokeAction, USER_CREATE, USER_RW, USER_RO, USER_NONE);
998
999 verifyAllowed(getPermissionsAction, SUPERUSER, USER_ADMIN, USER_OWNER);
1000 verifyDenied(getPermissionsAction, USER_CREATE, USER_RW, USER_RO, USER_NONE);
1001 }
1002
1003 @Test
1004 public void testPostGrantRevoke() throws Exception {
1005 final TableName tableName =
1006 TableName.valueOf("TempTable");
1007 final byte[] family1 = Bytes.toBytes("f1");
1008 final byte[] family2 = Bytes.toBytes("f2");
1009 final byte[] qualifier = Bytes.toBytes("q");
1010
1011
1012 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1013 if (admin.tableExists(tableName)) {
1014 admin.disableTable(tableName);
1015 admin.deleteTable(tableName);
1016 }
1017 HTableDescriptor htd = new HTableDescriptor(tableName);
1018 htd.addFamily(new HColumnDescriptor(family1));
1019 htd.addFamily(new HColumnDescriptor(family2));
1020 admin.createTable(htd);
1021
1022
1023 User tblUser = User
1024 .createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser", new String[0]);
1025 User gblUser = User
1026 .createUserForTesting(TEST_UTIL.getConfiguration(), "gbluser", new String[0]);
1027
1028
1029 AccessTestAction putActionAll = new AccessTestAction() {
1030 @Override
1031 public Object run() throws Exception {
1032 Put p = new Put(Bytes.toBytes("a"));
1033 p.add(family1, qualifier, Bytes.toBytes("v1"));
1034 p.add(family2, qualifier, Bytes.toBytes("v2"));
1035 HTable t = new HTable(conf, tableName);
1036 try {
1037 t.put(p);
1038 } finally {
1039 t.close();
1040 }
1041 return null;
1042 }
1043 };
1044
1045 AccessTestAction putAction1 = new AccessTestAction() {
1046 @Override
1047 public Object run() throws Exception {
1048 Put p = new Put(Bytes.toBytes("a"));
1049 p.add(family1, qualifier, Bytes.toBytes("v1"));
1050 HTable t = new HTable(conf, tableName);
1051 try {
1052 t.put(p);
1053 } finally {
1054 t.close();
1055 }
1056 return null;
1057 }
1058 };
1059
1060 AccessTestAction putAction2 = new AccessTestAction() {
1061 @Override
1062 public Object run() throws Exception {
1063 Put p = new Put(Bytes.toBytes("a"));
1064 p.add(family2, qualifier, Bytes.toBytes("v2"));
1065 HTable t = new HTable(conf, tableName);
1066 try {
1067 t.put(p);
1068 } finally {
1069 t.close();
1070 }
1071 return null;
1072 }
1073 };
1074
1075 AccessTestAction getActionAll = new AccessTestAction() {
1076 @Override
1077 public Object run() throws Exception {
1078 Get g = new Get(TEST_ROW);
1079 g.addFamily(family1);
1080 g.addFamily(family2);
1081 HTable t = new HTable(conf, tableName);
1082 try {
1083 t.get(g);
1084 } finally {
1085 t.close();
1086 }
1087 return null;
1088 }
1089 };
1090
1091 AccessTestAction getAction1 = new AccessTestAction() {
1092 @Override
1093 public Object run() throws Exception {
1094 Get g = new Get(TEST_ROW);
1095 g.addFamily(family1);
1096 HTable t = new HTable(conf, tableName);
1097 try {
1098 t.get(g);
1099 } finally {
1100 t.close();
1101 }
1102 return null;
1103 }
1104 };
1105
1106 AccessTestAction getAction2 = new AccessTestAction() {
1107 @Override
1108 public Object run() throws Exception {
1109 Get g = new Get(TEST_ROW);
1110 g.addFamily(family2);
1111 HTable t = new HTable(conf, tableName);
1112 try {
1113 t.get(g);
1114 } finally {
1115 t.close();
1116 }
1117 return null;
1118 }
1119 };
1120
1121 AccessTestAction deleteActionAll = new AccessTestAction() {
1122 @Override
1123 public Object run() throws Exception {
1124 Delete d = new Delete(TEST_ROW);
1125 d.deleteFamily(family1);
1126 d.deleteFamily(family2);
1127 HTable t = new HTable(conf, tableName);
1128 try {
1129 t.delete(d);
1130 } finally {
1131 t.close();
1132 }
1133 return null;
1134 }
1135 };
1136
1137 AccessTestAction deleteAction1 = new AccessTestAction() {
1138 @Override
1139 public Object run() throws Exception {
1140 Delete d = new Delete(TEST_ROW);
1141 d.deleteFamily(family1);
1142 HTable t = new HTable(conf, tableName);
1143 try {
1144 t.delete(d);
1145 } finally {
1146 t.close();
1147 }
1148 return null;
1149 }
1150 };
1151
1152 AccessTestAction deleteAction2 = new AccessTestAction() {
1153 @Override
1154 public Object run() throws Exception {
1155 Delete d = new Delete(TEST_ROW);
1156 d.deleteFamily(family2);
1157 HTable t = new HTable(conf, tableName);
1158 try {
1159 t.delete(d);
1160 } finally {
1161 t.close();
1162 }
1163 return null;
1164 }
1165 };
1166
1167
1168 verifyDenied(tblUser, getActionAll, getAction1, getAction2);
1169 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1170 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1171
1172 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1173 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1174 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1175
1176
1177 grantGlobal(TEST_UTIL, gblUser.getShortName(),
1178 Permission.Action.READ);
1179 grantOnTable(TEST_UTIL, tblUser.getShortName(),
1180 tableName, null, null,
1181 Permission.Action.READ);
1182
1183
1184 verifyAllowed(tblUser, getActionAll, getAction1, getAction2);
1185 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1186 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1187
1188 verifyAllowed(gblUser, getActionAll, getAction1, getAction2);
1189 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1190 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1191
1192
1193 grantGlobal(TEST_UTIL, gblUser.getShortName(),
1194 Permission.Action.WRITE);
1195 grantOnTable(TEST_UTIL, tblUser.getShortName(),
1196 tableName, null, null,
1197 Permission.Action.WRITE);
1198
1199 verifyDenied(tblUser, getActionAll, getAction1, getAction2);
1200 verifyAllowed(tblUser, putActionAll, putAction1, putAction2);
1201 verifyAllowed(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1202
1203 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1204 verifyAllowed(gblUser, putActionAll, putAction1, putAction2);
1205 verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1206
1207
1208 revokeGlobal(TEST_UTIL, gblUser.getShortName());
1209 revokeFromTable(TEST_UTIL, tblUser.getShortName(),
1210 tableName, null, null);
1211
1212 verifyDenied(tblUser, getActionAll, getAction1, getAction2);
1213 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1214 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1215
1216 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1217 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1218 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1219
1220
1221 grantGlobal(TEST_UTIL, gblUser.getShortName(),
1222 Permission.Action.READ);
1223 grantOnTable(TEST_UTIL, tblUser.getShortName(),
1224 tableName, family1, null, Permission.Action.READ);
1225
1226
1227 verifyAllowed(tblUser, getActionAll, getAction1);
1228 verifyDenied(tblUser, getAction2);
1229 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1230 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1231
1232 verifyAllowed(gblUser, getActionAll, getAction1, getAction2);
1233 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1234 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1235
1236
1237 grantGlobal(TEST_UTIL, gblUser.getShortName(),
1238 Permission.Action.WRITE);
1239 grantOnTable(TEST_UTIL, tblUser.getShortName(),
1240 tableName, family2, null, Permission.Action.WRITE);
1241
1242
1243 verifyAllowed(tblUser, getActionAll, getAction1);
1244 verifyAllowed(tblUser, putAction2, deleteAction2);
1245 verifyDenied(tblUser, getAction2);
1246 verifyDenied(tblUser, putActionAll, putAction1);
1247 verifyDenied(tblUser, deleteActionAll, deleteAction1);
1248
1249 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1250 verifyAllowed(gblUser, putActionAll, putAction1, putAction2);
1251 verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1252
1253
1254 revokeGlobal(TEST_UTIL, gblUser.getShortName());
1255 revokeFromTable(TEST_UTIL, tblUser.getShortName(), tableName, family2, null);
1256
1257
1258 verifyAllowed(tblUser, getActionAll, getAction1);
1259 verifyDenied(tblUser, getAction2);
1260 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1261 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1262
1263
1264 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1265 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1266 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1267
1268
1269 admin.disableTable(tableName);
1270 admin.deleteTable(tableName);
1271 }
1272
1273 private boolean hasFoundUserPermission(UserPermission userPermission, List<UserPermission> perms) {
1274 return perms.contains(userPermission);
1275 }
1276
1277 @Test
1278 public void testPostGrantRevokeAtQualifierLevel() throws Exception {
1279 final TableName tableName =
1280 TableName.valueOf("testGrantRevokeAtQualifierLevel");
1281 final byte[] family1 = Bytes.toBytes("f1");
1282 final byte[] family2 = Bytes.toBytes("f2");
1283 final byte[] qualifier = Bytes.toBytes("q");
1284
1285
1286 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1287 if (admin.tableExists(tableName)) {
1288 admin.disableTable(tableName);
1289 admin.deleteTable(tableName);
1290 }
1291 HTableDescriptor htd = new HTableDescriptor(tableName);
1292 htd.addFamily(new HColumnDescriptor(family1));
1293 htd.addFamily(new HColumnDescriptor(family2));
1294 admin.createTable(htd);
1295
1296
1297 User user = User.createUserForTesting(TEST_UTIL.getConfiguration(), "user", new String[0]);
1298
1299 AccessTestAction getQualifierAction = new AccessTestAction() {
1300 @Override
1301 public Object run() throws Exception {
1302 Get g = new Get(TEST_ROW);
1303 g.addColumn(family1, qualifier);
1304 HTable t = new HTable(conf, tableName);
1305 try {
1306 t.get(g);
1307 } finally {
1308 t.close();
1309 }
1310 return null;
1311 }
1312 };
1313
1314 AccessTestAction putQualifierAction = new AccessTestAction() {
1315 @Override
1316 public Object run() throws Exception {
1317 Put p = new Put(TEST_ROW);
1318 p.add(family1, qualifier, Bytes.toBytes("v1"));
1319 HTable t = new HTable(conf, tableName);
1320 try {
1321 t.put(p);
1322 } finally {
1323 t.close();
1324 }
1325 return null;
1326 }
1327 };
1328
1329 AccessTestAction deleteQualifierAction = new AccessTestAction() {
1330 @Override
1331 public Object run() throws Exception {
1332 Delete d = new Delete(TEST_ROW);
1333 d.deleteColumn(family1, qualifier);
1334
1335 HTable t = new HTable(conf, tableName);
1336 try {
1337 t.delete(d);
1338 } finally {
1339 t.close();
1340 }
1341 return null;
1342 }
1343 };
1344
1345 revokeFromTable(TEST_UTIL, user.getShortName(), tableName, family1, null);
1346
1347 verifyDenied(user, getQualifierAction);
1348 verifyDenied(user, putQualifierAction);
1349 verifyDenied(user, deleteQualifierAction);
1350
1351 grantOnTable(TEST_UTIL, user.getShortName(),
1352 tableName, family1, qualifier,
1353 Permission.Action.READ);
1354
1355 verifyAllowed(user, getQualifierAction);
1356 verifyDenied(user, putQualifierAction);
1357 verifyDenied(user, deleteQualifierAction);
1358
1359
1360
1361 grantOnTable(TEST_UTIL, user.getShortName(),
1362 tableName, family1, qualifier,
1363 Permission.Action.WRITE);
1364
1365 verifyDenied(user, getQualifierAction);
1366 verifyAllowed(user, putQualifierAction);
1367 verifyAllowed(user, deleteQualifierAction);
1368
1369
1370 grantOnTable(TEST_UTIL, user.getShortName(),
1371 tableName, family1, qualifier,
1372 Permission.Action.READ, Permission.Action.WRITE);
1373
1374 verifyAllowed(user, getQualifierAction);
1375 verifyAllowed(user, putQualifierAction);
1376 verifyAllowed(user, deleteQualifierAction);
1377
1378
1379 revokeFromTable(TEST_UTIL, user.getShortName(),
1380 tableName, family1, qualifier);
1381
1382 verifyDenied(user, getQualifierAction);
1383 verifyDenied(user, putQualifierAction);
1384 verifyDenied(user, deleteQualifierAction);
1385
1386
1387 admin.disableTable(tableName);
1388 admin.deleteTable(tableName);
1389 }
1390
1391 @Test
1392 public void testPermissionList() throws Exception {
1393 final TableName tableName =
1394 TableName.valueOf("testPermissionList");
1395 final byte[] family1 = Bytes.toBytes("f1");
1396 final byte[] family2 = Bytes.toBytes("f2");
1397 final byte[] qualifier = Bytes.toBytes("q");
1398
1399
1400 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1401 if (admin.tableExists(tableName)) {
1402 admin.disableTable(tableName);
1403 admin.deleteTable(tableName);
1404 }
1405 HTableDescriptor htd = new HTableDescriptor(tableName);
1406 htd.addFamily(new HColumnDescriptor(family1));
1407 htd.addFamily(new HColumnDescriptor(family2));
1408 htd.setOwner(USER_OWNER);
1409 admin.createTable(htd);
1410
1411 List<UserPermission> perms;
1412
1413 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1414 try {
1415 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1416 AccessControlService.BlockingInterface protocol =
1417 AccessControlService.newBlockingStub(service);
1418 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1419 } finally {
1420 acl.close();
1421 }
1422
1423 UserPermission ownerperm = new UserPermission(
1424 Bytes.toBytes(USER_OWNER.getName()), tableName, null, Action.values());
1425 assertTrue("Owner should have all permissions on table",
1426 hasFoundUserPermission(ownerperm, perms));
1427
1428 User user = User.createUserForTesting(TEST_UTIL.getConfiguration(), "user", new String[0]);
1429 byte[] userName = Bytes.toBytes(user.getShortName());
1430
1431 UserPermission up = new UserPermission(userName,
1432 tableName, family1, qualifier, Permission.Action.READ);
1433 assertFalse("User should not be granted permission: " + up.toString(),
1434 hasFoundUserPermission(up, perms));
1435
1436
1437 grantOnTable(TEST_UTIL, user.getShortName(),
1438 tableName, family1, qualifier, Permission.Action.READ);
1439
1440 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1441 try {
1442 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1443 AccessControlService.BlockingInterface protocol =
1444 AccessControlService.newBlockingStub(service);
1445 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1446 } finally {
1447 acl.close();
1448 }
1449
1450 UserPermission upToVerify = new UserPermission(
1451 userName, tableName, family1, qualifier, Permission.Action.READ);
1452 assertTrue("User should be granted permission: " + upToVerify.toString(),
1453 hasFoundUserPermission(upToVerify, perms));
1454
1455 upToVerify = new UserPermission(
1456 userName, tableName, family1, qualifier, Permission.Action.WRITE);
1457 assertFalse("User should not be granted permission: " + upToVerify.toString(),
1458 hasFoundUserPermission(upToVerify, perms));
1459
1460
1461 grantOnTable(TEST_UTIL, user.getShortName(),
1462 tableName, family1, qualifier,
1463 Permission.Action.WRITE, Permission.Action.READ);
1464
1465 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1466 try {
1467 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1468 AccessControlService.BlockingInterface protocol =
1469 AccessControlService.newBlockingStub(service);
1470 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1471 } finally {
1472 acl.close();
1473 }
1474
1475 upToVerify = new UserPermission(userName, tableName, family1,
1476 qualifier, Permission.Action.WRITE, Permission.Action.READ);
1477 assertTrue("User should be granted permission: " + upToVerify.toString(),
1478 hasFoundUserPermission(upToVerify, perms));
1479
1480
1481 revokeFromTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier,
1482 Permission.Action.WRITE, Permission.Action.READ);
1483
1484 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1485 try {
1486 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1487 AccessControlService.BlockingInterface protocol =
1488 AccessControlService.newBlockingStub(service);
1489 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1490 } finally {
1491 acl.close();
1492 }
1493
1494 assertFalse("User should not be granted permission: " + upToVerify.toString(),
1495 hasFoundUserPermission(upToVerify, perms));
1496
1497
1498 admin.disableTable(tableName);
1499
1500 User newOwner = User.createUserForTesting(conf, "new_owner", new String[] {});
1501 htd.setOwner(newOwner);
1502 admin.modifyTable(tableName, htd);
1503
1504 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1505 try {
1506 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1507 AccessControlService.BlockingInterface protocol =
1508 AccessControlService.newBlockingStub(service);
1509 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1510 } finally {
1511 acl.close();
1512 }
1513
1514 UserPermission newOwnerperm = new UserPermission(
1515 Bytes.toBytes(newOwner.getName()), tableName, null, Action.values());
1516 assertTrue("New owner should have all permissions on table",
1517 hasFoundUserPermission(newOwnerperm, perms));
1518
1519
1520 admin.deleteTable(tableName);
1521 }
1522
1523 @Test
1524 public void testGlobalPermissionList() throws Exception {
1525 List<UserPermission> perms;
1526 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1527 try {
1528 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
1529 AccessControlService.BlockingInterface protocol =
1530 AccessControlService.newBlockingStub(service);
1531 perms = ProtobufUtil.getUserPermissions(protocol);
1532 } finally {
1533 acl.close();
1534 }
1535 UserPermission adminPerm = new UserPermission(Bytes.toBytes(USER_ADMIN.getShortName()),
1536 AccessControlLists.ACL_TABLE_NAME, null, null, Bytes.toBytes("ACRW"));
1537 assertTrue("Only user admin has permission on table _acl_ per setup",
1538 perms.size() == 1 && hasFoundUserPermission(adminPerm, perms));
1539 }
1540
1541
1542 private void verifyGlobal(AccessTestAction action) throws Exception {
1543 verifyAllowed(action, SUPERUSER);
1544
1545 verifyDenied(action, USER_CREATE, USER_RW, USER_NONE, USER_RO);
1546 }
1547
1548 public void checkGlobalPerms(Permission.Action... actions) throws IOException {
1549 Permission[] perms = new Permission[actions.length];
1550 for (int i = 0; i < actions.length; i++) {
1551 perms[i] = new Permission(actions[i]);
1552 }
1553 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
1554 for (Action a : actions) {
1555 request.addPermission(AccessControlProtos.Permission.newBuilder()
1556 .setType(AccessControlProtos.Permission.Type.Global)
1557 .setGlobalPermission(
1558 AccessControlProtos.GlobalPermission.newBuilder()
1559 .addAction(ProtobufUtil.toPermissionAction(a)).build()));
1560 }
1561 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1562 try {
1563 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
1564 AccessControlService.BlockingInterface protocol =
1565 AccessControlService.newBlockingStub(channel);
1566 try {
1567 protocol.checkPermissions(null, request.build());
1568 } catch (ServiceException se) {
1569 ProtobufUtil.toIOException(se);
1570 }
1571 } finally {
1572 acl.close();
1573 }
1574 }
1575
1576 public void checkTablePerms(TableName table, byte[] family, byte[] column,
1577 Permission.Action... actions) throws IOException {
1578 Permission[] perms = new Permission[actions.length];
1579 for (int i = 0; i < actions.length; i++) {
1580 perms[i] = new TablePermission(table, family, column, actions[i]);
1581 }
1582
1583 checkTablePerms(table, perms);
1584 }
1585
1586 public void checkTablePerms(TableName table, Permission... perms) throws IOException {
1587 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
1588 for (Permission p : perms) {
1589 request.addPermission(ProtobufUtil.toPermission(p));
1590 }
1591 HTable acl = new HTable(conf, table);
1592 try {
1593 AccessControlService.BlockingInterface protocol =
1594 AccessControlService.newBlockingStub(acl.coprocessorService(new byte[0]));
1595 try {
1596 protocol.checkPermissions(null, request.build());
1597 } catch (ServiceException se) {
1598 ProtobufUtil.toIOException(se);
1599 }
1600 } finally {
1601 acl.close();
1602 }
1603 }
1604
1605 @Test
1606 public void testCheckPermissions() throws Exception {
1607
1608
1609 AccessTestAction globalAdmin = new AccessTestAction() {
1610 @Override
1611 public Void run() throws Exception {
1612 checkGlobalPerms(Permission.Action.ADMIN);
1613 return null;
1614 }
1615 };
1616
1617 verifyGlobal(globalAdmin);
1618
1619
1620
1621 AccessTestAction globalReadWrite = new AccessTestAction() {
1622 @Override
1623 public Void run() throws Exception {
1624 checkGlobalPerms(Permission.Action.READ, Permission.Action.WRITE);
1625 return null;
1626 }
1627 };
1628
1629 verifyGlobal(globalReadWrite);
1630
1631
1632
1633 final byte[] TEST_Q1 = Bytes.toBytes("q1");
1634 final byte[] TEST_Q2 = Bytes.toBytes("q2");
1635
1636 User userTable = User.createUserForTesting(conf, "user_check_perms_table", new String[0]);
1637 User userColumn = User.createUserForTesting(conf, "user_check_perms_family", new String[0]);
1638 User userQualifier = User.createUserForTesting(conf, "user_check_perms_q", new String[0]);
1639
1640 grantOnTable(TEST_UTIL, userTable.getShortName(),
1641 TEST_TABLE.getTableName(), null, null,
1642 Permission.Action.READ);
1643 grantOnTable(TEST_UTIL, userColumn.getShortName(),
1644 TEST_TABLE.getTableName(), TEST_FAMILY, null,
1645 Permission.Action.READ);
1646 grantOnTable(TEST_UTIL, userQualifier.getShortName(),
1647 TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1,
1648 Permission.Action.READ);
1649
1650 AccessTestAction tableRead = new AccessTestAction() {
1651 @Override
1652 public Void run() throws Exception {
1653 checkTablePerms(TEST_TABLE.getTableName(), null, null, Permission.Action.READ);
1654 return null;
1655 }
1656 };
1657
1658 AccessTestAction columnRead = new AccessTestAction() {
1659 @Override
1660 public Void run() throws Exception {
1661 checkTablePerms(TEST_TABLE.getTableName(), TEST_FAMILY, null, Permission.Action.READ);
1662 return null;
1663 }
1664 };
1665
1666 AccessTestAction qualifierRead = new AccessTestAction() {
1667 @Override
1668 public Void run() throws Exception {
1669 checkTablePerms(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1, Permission.Action.READ);
1670 return null;
1671 }
1672 };
1673
1674 AccessTestAction multiQualifierRead = new AccessTestAction() {
1675 @Override
1676 public Void run() throws Exception {
1677 checkTablePerms(TEST_TABLE.getTableName(), new Permission[] {
1678 new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1, Permission.Action.READ),
1679 new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q2, Permission.Action.READ), });
1680 return null;
1681 }
1682 };
1683
1684 AccessTestAction globalAndTableRead = new AccessTestAction() {
1685 @Override
1686 public Void run() throws Exception {
1687 checkTablePerms(TEST_TABLE.getTableName(), new Permission[] { new Permission(Permission.Action.READ),
1688 new TablePermission(TEST_TABLE.getTableName(), null, (byte[]) null, Permission.Action.READ), });
1689 return null;
1690 }
1691 };
1692
1693 AccessTestAction noCheck = new AccessTestAction() {
1694 @Override
1695 public Void run() throws Exception {
1696 checkTablePerms(TEST_TABLE.getTableName(), new Permission[0]);
1697 return null;
1698 }
1699 };
1700
1701 verifyAllowed(tableRead, SUPERUSER, userTable);
1702 verifyDenied(tableRead, userColumn, userQualifier);
1703
1704 verifyAllowed(columnRead, SUPERUSER, userTable, userColumn);
1705 verifyDenied(columnRead, userQualifier);
1706
1707 verifyAllowed(qualifierRead, SUPERUSER, userTable, userColumn, userQualifier);
1708
1709 verifyAllowed(multiQualifierRead, SUPERUSER, userTable, userColumn);
1710 verifyDenied(multiQualifierRead, userQualifier);
1711
1712 verifyAllowed(globalAndTableRead, SUPERUSER);
1713 verifyDenied(globalAndTableRead, userTable, userColumn, userQualifier);
1714
1715 verifyAllowed(noCheck, SUPERUSER, userTable, userColumn, userQualifier);
1716
1717
1718
1719 AccessTestAction familyReadWrite = new AccessTestAction() {
1720 @Override
1721 public Void run() throws Exception {
1722 checkTablePerms(TEST_TABLE.getTableName(), TEST_FAMILY, null, Permission.Action.READ,
1723 Permission.Action.WRITE);
1724 return null;
1725 }
1726 };
1727
1728 verifyAllowed(familyReadWrite, SUPERUSER, USER_OWNER, USER_CREATE, USER_RW);
1729 verifyDenied(familyReadWrite, USER_NONE, USER_RO);
1730
1731
1732
1733 CheckPermissionsRequest checkRequest = CheckPermissionsRequest.newBuilder()
1734 .addPermission(AccessControlProtos.Permission.newBuilder()
1735 .setType(AccessControlProtos.Permission.Type.Table)
1736 .setTablePermission(
1737 AccessControlProtos.TablePermission.newBuilder()
1738 .setTableName(ProtobufUtil.toProtoTableName(TEST_TABLE.getTableName()))
1739 .addAction(AccessControlProtos.Permission.Action.CREATE))
1740 ).build();
1741 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1742 try {
1743 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
1744 AccessControlService.BlockingInterface protocol =
1745 AccessControlService.newBlockingStub(channel);
1746 try {
1747
1748 protocol.checkPermissions(null, checkRequest);
1749 fail("this should have thrown CoprocessorException");
1750 } catch (ServiceException ex) {
1751
1752 }
1753 } finally {
1754 acl.close();
1755 }
1756 }
1757
1758 @Test
1759 public void testStopRegionServer() throws Exception {
1760 AccessTestAction action = new AccessTestAction() {
1761 @Override
1762 public Object run() throws Exception {
1763 ACCESS_CONTROLLER.preStopRegionServer(ObserverContext.createAndPrepare(RSCP_ENV, null));
1764 return null;
1765 }
1766 };
1767
1768 verifyAllowed(action, SUPERUSER, USER_ADMIN);
1769 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
1770 }
1771
1772 @Test
1773 public void testOpenRegion() throws Exception {
1774 AccessTestAction action = new AccessTestAction() {
1775 @Override
1776 public Object run() throws Exception {
1777 ACCESS_CONTROLLER.preOpen(ObserverContext.createAndPrepare(RCP_ENV, null));
1778 return null;
1779 }
1780 };
1781
1782 verifyAllowed(action, SUPERUSER, USER_ADMIN);
1783 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1784 }
1785
1786 @Test
1787 public void testCloseRegion() throws Exception {
1788 AccessTestAction action = new AccessTestAction() {
1789 @Override
1790 public Object run() throws Exception {
1791 ACCESS_CONTROLLER.preClose(ObserverContext.createAndPrepare(RCP_ENV, null), false);
1792 return null;
1793 }
1794 };
1795
1796 verifyAllowed(action, SUPERUSER, USER_ADMIN);
1797 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1798 }
1799
1800 @Test
1801 public void testSnapshot() throws Exception {
1802 AccessTestAction snapshotAction = new AccessTestAction() {
1803 @Override
1804 public Object run() throws Exception {
1805 ACCESS_CONTROLLER.preSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1806 null, null);
1807 return null;
1808 }
1809 };
1810
1811 AccessTestAction deleteAction = new AccessTestAction() {
1812 @Override
1813 public Object run() throws Exception {
1814 ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1815 null);
1816 return null;
1817 }
1818 };
1819
1820 AccessTestAction restoreAction = new AccessTestAction() {
1821 @Override
1822 public Object run() throws Exception {
1823 ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1824 null, null);
1825 return null;
1826 }
1827 };
1828
1829 AccessTestAction cloneAction = new AccessTestAction() {
1830 @Override
1831 public Object run() throws Exception {
1832 ACCESS_CONTROLLER.preCloneSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1833 null, null);
1834 return null;
1835 }
1836 };
1837
1838 verifyAllowed(snapshotAction, SUPERUSER, USER_ADMIN);
1839 verifyDenied(snapshotAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1840
1841 verifyAllowed(cloneAction, SUPERUSER, USER_ADMIN);
1842 verifyDenied(deleteAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1843
1844 verifyAllowed(restoreAction, SUPERUSER, USER_ADMIN);
1845 verifyDenied(restoreAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1846
1847 verifyAllowed(deleteAction, SUPERUSER, USER_ADMIN);
1848 verifyDenied(cloneAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1849 }
1850
1851 @Test
1852 public void testGlobalAuthorizationForNewRegisteredRS() throws Exception {
1853 LOG.debug("Test for global authorization for a new registered RegionServer.");
1854 MiniHBaseCluster hbaseCluster = TEST_UTIL.getHBaseCluster();
1855
1856
1857
1858 String currentUser = User.getCurrent().getShortName();
1859 String activeUserForNewRs = currentUser + ".hfs." +
1860 hbaseCluster.getLiveRegionServerThreads().size();
1861 grantGlobal(TEST_UTIL, activeUserForNewRs,
1862 Permission.Action.ADMIN, Permission.Action.CREATE, Permission.Action.READ,
1863 Permission.Action.WRITE);
1864
1865 final HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1866 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE2);
1867 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
1868 admin.createTable(htd);
1869
1870
1871 JVMClusterUtil.RegionServerThread newRsThread = hbaseCluster
1872 .startRegionServer();
1873 final HRegionServer newRs = newRsThread.getRegionServer();
1874
1875
1876 final HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE2);
1877 try {
1878 NavigableMap<HRegionInfo, ServerName> regions = table
1879 .getRegionLocations();
1880 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet()
1881 .iterator().next();
1882
1883 AccessTestAction moveAction = new AccessTestAction() {
1884 @Override
1885 public Object run() throws Exception {
1886 admin.move(firstRegion.getKey().getEncodedNameAsBytes(),
1887 Bytes.toBytes(newRs.getServerName().getServerName()));
1888 return null;
1889 }
1890 };
1891 SUPERUSER.runAs(moveAction);
1892
1893 final int RETRIES_LIMIT = 10;
1894 int retries = 0;
1895 while (newRs.getOnlineRegions(TEST_TABLE2).size() < 1 && retries < RETRIES_LIMIT) {
1896 LOG.debug("Waiting for region to be opened. Already retried " + retries
1897 + " times.");
1898 try {
1899 Thread.sleep(1000);
1900 } catch (InterruptedException e) {
1901 }
1902 retries++;
1903 if (retries == RETRIES_LIMIT - 1) {
1904 fail("Retry exhaust for waiting region to be opened.");
1905 }
1906 }
1907
1908
1909 AccessTestAction putAction = new AccessTestAction() {
1910 @Override
1911 public Object run() throws Exception {
1912 Put put = new Put(Bytes.toBytes("test"));
1913 put.add(TEST_FAMILY, Bytes.toBytes("qual"), Bytes.toBytes("value"));
1914 table.put(put);
1915 return null;
1916 }
1917 };
1918 USER_ADMIN.runAs(putAction);
1919 } finally {
1920 table.close();
1921 }
1922 }
1923
1924 @Test
1925 public void testTableDescriptorsEnumeration() throws Exception {
1926 User TABLE_ADMIN = User.createUserForTesting(conf, "UserA", new String[0]);
1927
1928
1929 grantOnTable(TEST_UTIL, TABLE_ADMIN.getShortName(),
1930 TEST_TABLE.getTableName(), null, null,
1931 Permission.Action.ADMIN);
1932
1933 AccessTestAction listTablesAction = new AccessTestAction() {
1934 @Override
1935 public Object run() throws Exception {
1936 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1937 try {
1938 admin.listTables();
1939 } finally {
1940 admin.close();
1941 }
1942 return null;
1943 }
1944 };
1945
1946 AccessTestAction getTableDescAction = new AccessTestAction() {
1947 @Override
1948 public Object run() throws Exception {
1949 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1950 try {
1951 admin.getTableDescriptor(TEST_TABLE.getTableName());
1952 } finally {
1953 admin.close();
1954 }
1955 return null;
1956 }
1957 };
1958
1959 verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN);
1960 verifyDenied(listTablesAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, TABLE_ADMIN);
1961
1962 verifyAllowed(getTableDescAction, SUPERUSER, USER_ADMIN, USER_CREATE, TABLE_ADMIN);
1963 verifyDenied(getTableDescAction, USER_RW, USER_RO, USER_NONE);
1964 }
1965
1966 @Test
1967 public void testTableDeletion() throws Exception {
1968 User TABLE_ADMIN = User.createUserForTesting(conf, "TestUser", new String[0]);
1969
1970
1971 grantOnTable(TEST_UTIL, TABLE_ADMIN.getShortName(),
1972 TEST_TABLE.getTableName(), null, null,
1973 Permission.Action.ADMIN);
1974
1975 AccessTestAction deleteTableAction = new AccessTestAction() {
1976 @Override
1977 public Object run() throws Exception {
1978 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1979 try {
1980 admin.disableTable(TEST_TABLE.getTableName());
1981 admin.deleteTable(TEST_TABLE.getTableName());
1982 } finally {
1983 admin.close();
1984 }
1985 return null;
1986 }
1987 };
1988
1989 verifyDenied(deleteTableAction, USER_RW, USER_RO, USER_NONE);
1990 verifyAllowed(deleteTableAction, TABLE_ADMIN);
1991 }
1992
1993 @Test
1994 public void testNamespaceUserGrant() throws Exception {
1995 AccessTestAction getAction = new AccessTestAction() {
1996 @Override
1997 public Object run() throws Exception {
1998 HTable t = new HTable(conf, TEST_TABLE.getTableName());
1999 try {
2000 return t.get(new Get(TEST_ROW));
2001 } finally {
2002 t.close();
2003 }
2004 }
2005 };
2006
2007 verifyDenied(getAction, USER_NONE);
2008
2009
2010 grantOnNamespace(TEST_UTIL, USER_NONE.getShortName(),
2011 TEST_TABLE.getTableName().getNamespaceAsString(),
2012 Permission.Action.READ);
2013
2014
2015 verifyAllowed(getAction, USER_NONE);
2016 }
2017
2018 public static class PingCoprocessor extends PingService implements Coprocessor,
2019 CoprocessorService {
2020
2021 @Override
2022 public void start(CoprocessorEnvironment env) throws IOException { }
2023
2024 @Override
2025 public void stop(CoprocessorEnvironment env) throws IOException { }
2026
2027 @Override
2028 public Service getService() {
2029 return this;
2030 }
2031
2032 @Override
2033 public void ping(RpcController controller, PingRequest request,
2034 RpcCallback<PingResponse> callback) {
2035 callback.run(PingResponse.newBuilder().setPong("Pong!").build());
2036 }
2037
2038 @Override
2039 public void count(RpcController controller, CountRequest request,
2040 RpcCallback<CountResponse> callback) {
2041 callback.run(CountResponse.newBuilder().build());
2042 }
2043
2044 @Override
2045 public void increment(RpcController controller, IncrementCountRequest requet,
2046 RpcCallback<IncrementCountResponse> callback) {
2047 callback.run(IncrementCountResponse.newBuilder().build());
2048 }
2049
2050 @Override
2051 public void hello(RpcController controller, HelloRequest request,
2052 RpcCallback<HelloResponse> callback) {
2053 callback.run(HelloResponse.newBuilder().setResponse("Hello!").build());
2054 }
2055
2056 @Override
2057 public void noop(RpcController controller, NoopRequest request,
2058 RpcCallback<NoopResponse> callback) {
2059 callback.run(NoopResponse.newBuilder().build());
2060 }
2061 }
2062
2063 @Test
2064 public void testCoprocessorExec() throws Exception {
2065
2066 for (JVMClusterUtil.RegionServerThread thread:
2067 TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads()) {
2068 HRegionServer rs = thread.getRegionServer();
2069 for (HRegion region: rs.getOnlineRegions(TEST_TABLE.getTableName())) {
2070 region.getCoprocessorHost().load(PingCoprocessor.class,
2071 Coprocessor.PRIORITY_USER, conf);
2072 }
2073 }
2074
2075
2076
2077 User userA = User.createUserForTesting(conf, "UserA", new String[0]);
2078 User userB = User.createUserForTesting(conf, "UserB", new String[0]);
2079
2080 grantOnTable(TEST_UTIL, userA.getShortName(),
2081 TEST_TABLE.getTableName(), null, null,
2082 Permission.Action.EXEC);
2083
2084
2085 AccessTestAction execEndpointAction = new AccessTestAction() {
2086 @Override
2087 public Object run() throws Exception {
2088 HTable t = new HTable(conf, TEST_TABLE.getTableName());
2089 try {
2090 BlockingRpcChannel service = t.coprocessorService(HConstants.EMPTY_BYTE_ARRAY);
2091 PingCoprocessor.newBlockingStub(service).noop(null, NoopRequest.newBuilder().build());
2092 } finally {
2093 t.close();
2094 }
2095 return null;
2096 }
2097 };
2098
2099
2100 verifyDenied(execEndpointAction, userB);
2101 verifyAllowed(execEndpointAction, userA);
2102
2103
2104 grantOnNamespace(TEST_UTIL, userB.getShortName(),
2105 TEST_TABLE.getTableName().getNamespaceAsString(),
2106 Permission.Action.EXEC);
2107
2108
2109 verifyAllowed(execEndpointAction, userA, userB);
2110 }
2111
2112 }