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