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