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