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