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