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