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