001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security.access; 019 020import java.util.ArrayList; 021import java.util.Collection; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.hadoop.hbase.TableName; 026import org.apache.yetus.audience.InterfaceAudience; 027import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 028import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos; 029import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService; 030import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GetUserPermissionsResponse; 031import org.apache.hadoop.hbase.util.ByteStringer; 032 033import org.apache.hbase.thirdparty.com.google.common.collect.ArrayListMultimap; 034import org.apache.hbase.thirdparty.com.google.common.collect.ListMultimap; 035import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 036import com.google.protobuf.ByteString; 037import com.google.protobuf.RpcController; 038import com.google.protobuf.ServiceException; 039 040/** 041 * @since 2.0.0 042 */ 043@InterfaceAudience.Private 044public class AccessControlUtil { 045 private AccessControlUtil() {} 046 047 /** 048 * Create a request to grant user permissions. 049 * 050 * @param username the short user name who to grant permissions 051 * @param tableName optional table name the permissions apply 052 * @param family optional column family 053 * @param qualifier optional qualifier 054 * @param actions the permissions to be granted 055 * @return A {@link AccessControlProtos} GrantRequest 056 */ 057 public static AccessControlProtos.GrantRequest buildGrantRequest( 058 String username, TableName tableName, byte[] family, byte[] qualifier, 059 boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) { 060 AccessControlProtos.Permission.Builder ret = 061 AccessControlProtos.Permission.newBuilder(); 062 AccessControlProtos.TablePermission.Builder permissionBuilder = 063 AccessControlProtos.TablePermission.newBuilder(); 064 for (AccessControlProtos.Permission.Action a : actions) { 065 permissionBuilder.addAction(a); 066 } 067 if (tableName == null) { 068 throw new NullPointerException("TableName cannot be null"); 069 } 070 permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName)); 071 072 if (family != null) { 073 permissionBuilder.setFamily(ByteStringer.wrap(family)); 074 } 075 if (qualifier != null) { 076 permissionBuilder.setQualifier(ByteStringer.wrap(qualifier)); 077 } 078 ret.setType(AccessControlProtos.Permission.Type.Table) 079 .setTablePermission(permissionBuilder); 080 return AccessControlProtos.GrantRequest.newBuilder() 081 .setUserPermission( 082 AccessControlProtos.UserPermission.newBuilder() 083 .setUser(ByteString.copyFromUtf8(username)) 084 .setPermission(ret) 085 ).setMergeExistingPermissions(mergeExistingPermissions).build(); 086 } 087 088 /** 089 * Create a request to grant user permissions. 090 * 091 * @param username the short user name who to grant permissions 092 * @param namespace optional table name the permissions apply 093 * @param actions the permissions to be granted 094 * @return A {@link AccessControlProtos} GrantRequest 095 */ 096 public static AccessControlProtos.GrantRequest buildGrantRequest( 097 String username, String namespace, boolean mergeExistingPermissions, 098 AccessControlProtos.Permission.Action... actions) { 099 AccessControlProtos.Permission.Builder ret = 100 AccessControlProtos.Permission.newBuilder(); 101 AccessControlProtos.NamespacePermission.Builder permissionBuilder = 102 AccessControlProtos.NamespacePermission.newBuilder(); 103 for (AccessControlProtos.Permission.Action a : actions) { 104 permissionBuilder.addAction(a); 105 } 106 if (namespace != null) { 107 permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace)); 108 } 109 ret.setType(AccessControlProtos.Permission.Type.Namespace) 110 .setNamespacePermission(permissionBuilder); 111 return AccessControlProtos.GrantRequest.newBuilder() 112 .setUserPermission( 113 AccessControlProtos.UserPermission.newBuilder() 114 .setUser(ByteString.copyFromUtf8(username)) 115 .setPermission(ret) 116 ).setMergeExistingPermissions(mergeExistingPermissions).build(); 117 } 118 119 /** 120 * Create a request to revoke user permissions. 121 * 122 * @param username the short user name whose permissions to be revoked 123 * @param actions the permissions to be revoked 124 * @return A {@link AccessControlProtos} RevokeRequest 125 */ 126 public static AccessControlProtos.RevokeRequest buildRevokeRequest( 127 String username, AccessControlProtos.Permission.Action... actions) { 128 AccessControlProtos.Permission.Builder ret = 129 AccessControlProtos.Permission.newBuilder(); 130 AccessControlProtos.GlobalPermission.Builder permissionBuilder = 131 AccessControlProtos.GlobalPermission.newBuilder(); 132 for (AccessControlProtos.Permission.Action a : actions) { 133 permissionBuilder.addAction(a); 134 } 135 ret.setType(AccessControlProtos.Permission.Type.Global) 136 .setGlobalPermission(permissionBuilder); 137 return AccessControlProtos.RevokeRequest.newBuilder() 138 .setUserPermission( 139 AccessControlProtos.UserPermission.newBuilder() 140 .setUser(ByteString.copyFromUtf8(username)) 141 .setPermission(ret) 142 ).build(); 143 } 144 145 /** 146 * Create a request to revoke user permissions. 147 * 148 * @param username the short user name whose permissions to be revoked 149 * @param namespace optional table name the permissions apply 150 * @param actions the permissions to be revoked 151 * @return A {@link AccessControlProtos} RevokeRequest 152 */ 153 public static AccessControlProtos.RevokeRequest buildRevokeRequest( 154 String username, String namespace, 155 AccessControlProtos.Permission.Action... actions) { 156 AccessControlProtos.Permission.Builder ret = 157 AccessControlProtos.Permission.newBuilder(); 158 AccessControlProtos.NamespacePermission.Builder permissionBuilder = 159 AccessControlProtos.NamespacePermission.newBuilder(); 160 for (AccessControlProtos.Permission.Action a : actions) { 161 permissionBuilder.addAction(a); 162 } 163 if (namespace != null) { 164 permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace)); 165 } 166 ret.setType(AccessControlProtos.Permission.Type.Namespace) 167 .setNamespacePermission(permissionBuilder); 168 return AccessControlProtos.RevokeRequest.newBuilder() 169 .setUserPermission( 170 AccessControlProtos.UserPermission.newBuilder() 171 .setUser(ByteString.copyFromUtf8(username)) 172 .setPermission(ret) 173 ).build(); 174 } 175 176 /** 177 * Create a request to grant user permissions. 178 * 179 * @param username the short user name who to grant permissions 180 * @param actions the permissions to be granted 181 * @return A {@link AccessControlProtos} GrantRequest 182 */ 183 public static AccessControlProtos.GrantRequest buildGrantRequest(String username, 184 boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) { 185 AccessControlProtos.Permission.Builder ret = 186 AccessControlProtos.Permission.newBuilder(); 187 AccessControlProtos.GlobalPermission.Builder permissionBuilder = 188 AccessControlProtos.GlobalPermission.newBuilder(); 189 for (AccessControlProtos.Permission.Action a : actions) { 190 permissionBuilder.addAction(a); 191 } 192 ret.setType(AccessControlProtos.Permission.Type.Global) 193 .setGlobalPermission(permissionBuilder); 194 return AccessControlProtos.GrantRequest.newBuilder() 195 .setUserPermission( 196 AccessControlProtos.UserPermission.newBuilder() 197 .setUser(ByteString.copyFromUtf8(username)) 198 .setPermission(ret) 199 ).setMergeExistingPermissions(mergeExistingPermissions).build(); 200 } 201 202 public static AccessControlProtos.UsersAndPermissions toUsersAndPermissions(String user, 203 Permission perms) { 204 return AccessControlProtos.UsersAndPermissions.newBuilder() 205 .addUserPermissions(AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder() 206 .setUser(ByteString.copyFromUtf8(user)) 207 .addPermissions(toPermission(perms)) 208 .build()) 209 .build(); 210 } 211 212 public static AccessControlProtos.UsersAndPermissions toUsersAndPermissions( 213 ListMultimap<String, Permission> perms) { 214 AccessControlProtos.UsersAndPermissions.Builder builder = 215 AccessControlProtos.UsersAndPermissions.newBuilder(); 216 for (Map.Entry<String, Collection<Permission>> entry : perms.asMap().entrySet()) { 217 AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder = 218 AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder(); 219 userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey())); 220 for (Permission perm: entry.getValue()) { 221 userPermBuilder.addPermissions(toPermission(perm)); 222 } 223 builder.addUserPermissions(userPermBuilder.build()); 224 } 225 return builder.build(); 226 } 227 228 public static ListMultimap<String, Permission> toUsersAndPermissions( 229 AccessControlProtos.UsersAndPermissions proto) { 230 ListMultimap<String, Permission> result = ArrayListMultimap.create(); 231 for (AccessControlProtos.UsersAndPermissions.UserPermissions userPerms: 232 proto.getUserPermissionsList()) { 233 String user = userPerms.getUser().toStringUtf8(); 234 for (AccessControlProtos.Permission perm: userPerms.getPermissionsList()) { 235 result.put(user, toPermission(perm)); 236 } 237 } 238 return result; 239 } 240 241 242 /** 243 * Converts a Permission proto to a client Permission object. 244 * 245 * @param proto the protobuf Permission 246 * @return the converted Permission 247 */ 248 public static Permission toPermission(AccessControlProtos.Permission proto) { 249 if (proto.getType() != AccessControlProtos.Permission.Type.Global) { 250 return toTablePermission(proto); 251 } else { 252 List<Permission.Action> actions = toPermissionActions( 253 proto.getGlobalPermission().getActionList()); 254 return new Permission(actions.toArray(new Permission.Action[actions.size()])); 255 } 256 } 257 258 /** 259 * Converts a Permission proto to a client TablePermission object. 260 * 261 * @param proto the protobuf Permission 262 * @return the converted TablePermission 263 */ 264 public static TablePermission toTablePermission(AccessControlProtos.Permission proto) { 265 if(proto.getType() == AccessControlProtos.Permission.Type.Global) { 266 AccessControlProtos.GlobalPermission perm = proto.getGlobalPermission(); 267 List<Permission.Action> actions = toPermissionActions(perm.getActionList()); 268 269 return new TablePermission(null, null, null, 270 actions.toArray(new Permission.Action[actions.size()])); 271 } 272 if(proto.getType() == AccessControlProtos.Permission.Type.Namespace) { 273 AccessControlProtos.NamespacePermission perm = proto.getNamespacePermission(); 274 List<Permission.Action> actions = toPermissionActions(perm.getActionList()); 275 276 if(!proto.hasNamespacePermission()) { 277 throw new IllegalStateException("Namespace must not be empty in NamespacePermission"); 278 } 279 String namespace = perm.getNamespaceName().toStringUtf8(); 280 return new TablePermission(namespace, actions.toArray(new Permission.Action[actions.size()])); 281 } 282 if(proto.getType() == AccessControlProtos.Permission.Type.Table) { 283 AccessControlProtos.TablePermission perm = proto.getTablePermission(); 284 List<Permission.Action> actions = toPermissionActions(perm.getActionList()); 285 286 byte[] qualifier = null; 287 byte[] family = null; 288 TableName table = null; 289 290 if (!perm.hasTableName()) { 291 throw new IllegalStateException("TableName cannot be empty"); 292 } 293 table = ProtobufUtil.toTableName(perm.getTableName()); 294 295 if (perm.hasFamily()) family = perm.getFamily().toByteArray(); 296 if (perm.hasQualifier()) qualifier = perm.getQualifier().toByteArray(); 297 298 return new TablePermission(table, family, qualifier, 299 actions.toArray(new Permission.Action[actions.size()])); 300 } 301 throw new IllegalStateException("Unrecognize Perm Type: "+proto.getType()); 302 } 303 304 /** 305 * Convert a client Permission to a Permission proto 306 * 307 * @param perm the client Permission 308 * @return the protobuf Permission 309 */ 310 public static AccessControlProtos.Permission toPermission(Permission perm) { 311 AccessControlProtos.Permission.Builder ret = AccessControlProtos.Permission.newBuilder(); 312 if (perm instanceof TablePermission) { 313 TablePermission tablePerm = (TablePermission)perm; 314 if(tablePerm.hasNamespace()) { 315 ret.setType(AccessControlProtos.Permission.Type.Namespace); 316 317 AccessControlProtos.NamespacePermission.Builder builder = 318 AccessControlProtos.NamespacePermission.newBuilder(); 319 builder.setNamespaceName(ByteString.copyFromUtf8(tablePerm.getNamespace())); 320 Permission.Action[] actions = perm.getActions(); 321 if (actions != null) { 322 for (Permission.Action a : actions) { 323 builder.addAction(toPermissionAction(a)); 324 } 325 } 326 ret.setNamespacePermission(builder); 327 return ret.build(); 328 } else if (tablePerm.hasTable()) { 329 ret.setType(AccessControlProtos.Permission.Type.Table); 330 331 AccessControlProtos.TablePermission.Builder builder = 332 AccessControlProtos.TablePermission.newBuilder(); 333 builder.setTableName(ProtobufUtil.toProtoTableName(tablePerm.getTableName())); 334 if (tablePerm.hasFamily()) { 335 builder.setFamily(ByteStringer.wrap(tablePerm.getFamily())); 336 } 337 if (tablePerm.hasQualifier()) { 338 builder.setQualifier(ByteStringer.wrap(tablePerm.getQualifier())); 339 } 340 Permission.Action actions[] = perm.getActions(); 341 if (actions != null) { 342 for (Permission.Action a : actions) { 343 builder.addAction(toPermissionAction(a)); 344 } 345 } 346 ret.setTablePermission(builder); 347 return ret.build(); 348 } 349 } 350 351 ret.setType(AccessControlProtos.Permission.Type.Global); 352 353 AccessControlProtos.GlobalPermission.Builder builder = 354 AccessControlProtos.GlobalPermission.newBuilder(); 355 Permission.Action actions[] = perm.getActions(); 356 if (actions != null) { 357 for (Permission.Action a: actions) { 358 builder.addAction(toPermissionAction(a)); 359 } 360 } 361 ret.setGlobalPermission(builder); 362 return ret.build(); 363 } 364 365 /** 366 * Converts a list of Permission.Action proto to a list of client Permission.Action objects. 367 * 368 * @param protoActions the list of protobuf Actions 369 * @return the converted list of Actions 370 */ 371 public static List<Permission.Action> toPermissionActions( 372 List<AccessControlProtos.Permission.Action> protoActions) { 373 List<Permission.Action> actions = new ArrayList<>(protoActions.size()); 374 for (AccessControlProtos.Permission.Action a : protoActions) { 375 actions.add(toPermissionAction(a)); 376 } 377 return actions; 378 } 379 380 /** 381 * Converts a Permission.Action proto to a client Permission.Action object. 382 * 383 * @param action the protobuf Action 384 * @return the converted Action 385 */ 386 public static Permission.Action toPermissionAction( 387 AccessControlProtos.Permission.Action action) { 388 switch (action) { 389 case READ: 390 return Permission.Action.READ; 391 case WRITE: 392 return Permission.Action.WRITE; 393 case EXEC: 394 return Permission.Action.EXEC; 395 case CREATE: 396 return Permission.Action.CREATE; 397 case ADMIN: 398 return Permission.Action.ADMIN; 399 } 400 throw new IllegalArgumentException("Unknown action value "+action.name()); 401 } 402 403 /** 404 * Convert a client Permission.Action to a Permission.Action proto 405 * 406 * @param action the client Action 407 * @return the protobuf Action 408 */ 409 public static AccessControlProtos.Permission.Action toPermissionAction( 410 Permission.Action action) { 411 switch (action) { 412 case READ: 413 return AccessControlProtos.Permission.Action.READ; 414 case WRITE: 415 return AccessControlProtos.Permission.Action.WRITE; 416 case EXEC: 417 return AccessControlProtos.Permission.Action.EXEC; 418 case CREATE: 419 return AccessControlProtos.Permission.Action.CREATE; 420 case ADMIN: 421 return AccessControlProtos.Permission.Action.ADMIN; 422 } 423 throw new IllegalArgumentException("Unknown action value "+action.name()); 424 } 425 426 /** 427 * Convert a client user permission to a user permission proto 428 * 429 * @param perm the client UserPermission 430 * @return the protobuf UserPermission 431 */ 432 public static AccessControlProtos.UserPermission toUserPermission(UserPermission perm) { 433 return AccessControlProtos.UserPermission.newBuilder() 434 .setUser(ByteStringer.wrap(perm.getUser())) 435 .setPermission(toPermission(perm)) 436 .build(); 437 } 438 439 /** 440 * Converts the permissions list into a protocol buffer GetUserPermissionsResponse 441 */ 442 public static GetUserPermissionsResponse buildGetUserPermissionsResponse( 443 final List<UserPermission> permissions) { 444 GetUserPermissionsResponse.Builder builder = GetUserPermissionsResponse.newBuilder(); 445 for (UserPermission perm : permissions) { 446 builder.addUserPermission(toUserPermission(perm)); 447 } 448 return builder.build(); 449 } 450 451 /** 452 * Converts a user permission proto to a client user permission object. 453 * 454 * @param proto the protobuf UserPermission 455 * @return the converted UserPermission 456 */ 457 public static UserPermission toUserPermission(AccessControlProtos.UserPermission proto) { 458 return new UserPermission(proto.getUser().toByteArray(), 459 toTablePermission(proto.getPermission())); 460 } 461 462 /** 463 * Convert a ListMultimap<String, TablePermission> where key is username 464 * to a protobuf UserPermission 465 * 466 * @param perm the list of user and table permissions 467 * @return the protobuf UserTablePermissions 468 */ 469 public static AccessControlProtos.UsersAndPermissions toUserTablePermissions( 470 ListMultimap<String, TablePermission> perm) { 471 AccessControlProtos.UsersAndPermissions.Builder builder = 472 AccessControlProtos.UsersAndPermissions.newBuilder(); 473 for (Map.Entry<String, Collection<TablePermission>> entry : perm.asMap().entrySet()) { 474 AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder = 475 AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder(); 476 userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey())); 477 for (TablePermission tablePerm: entry.getValue()) { 478 userPermBuilder.addPermissions(toPermission(tablePerm)); 479 } 480 builder.addUserPermissions(userPermBuilder.build()); 481 } 482 return builder.build(); 483 } 484 485 /** 486 * A utility used to grant a user global permissions. 487 * <p> 488 * It's also called by the shell, in case you want to find references. 489 * 490 * @param protocol the AccessControlService protocol proxy 491 * @param userShortName the short name of the user to grant permissions 492 * @param actions the permissions to be granted 493 * @throws ServiceException 494 */ 495 public static void grant(RpcController controller, 496 AccessControlService.BlockingInterface protocol, String userShortName, boolean mergeExistingPermissions, 497 Permission.Action... actions) throws ServiceException { 498 List<AccessControlProtos.Permission.Action> permActions = 499 Lists.newArrayListWithCapacity(actions.length); 500 for (Permission.Action a : actions) { 501 permActions.add(toPermissionAction(a)); 502 } 503 AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, mergeExistingPermissions, 504 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 505 protocol.grant(controller, request); 506 } 507 508 /** 509 * A utility used to grant a user table permissions. The permissions will 510 * be for a table table/column family/qualifier. 511 * <p> 512 * It's also called by the shell, in case you want to find references. 513 * 514 * @param protocol the AccessControlService protocol proxy 515 * @param userShortName the short name of the user to grant permissions 516 * @param tableName optional table name 517 * @param f optional column family 518 * @param q optional qualifier 519 * @param actions the permissions to be granted 520 * @throws ServiceException 521 */ 522 public static void grant(RpcController controller, 523 AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName, 524 byte[] f, byte[] q, boolean mergeExistingPermissions, Permission.Action... actions) 525 throws ServiceException { 526 List<AccessControlProtos.Permission.Action> permActions = 527 Lists.newArrayListWithCapacity(actions.length); 528 for (Permission.Action a : actions) { 529 permActions.add(toPermissionAction(a)); 530 } 531 AccessControlProtos.GrantRequest request = 532 buildGrantRequest(userShortName, tableName, f, q, mergeExistingPermissions, 533 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 534 protocol.grant(controller, request); 535 } 536 537 /** 538 * A utility used to grant a user namespace permissions. 539 * <p> 540 * It's also called by the shell, in case you want to find references. 541 * 542 * @param protocol the AccessControlService protocol proxy 543 * @param namespace the short name of the user to grant permissions 544 * @param actions the permissions to be granted 545 * @throws ServiceException 546 */ 547 public static void grant(RpcController controller, 548 AccessControlService.BlockingInterface protocol, String userShortName, String namespace, 549 boolean mergeExistingPermissions, Permission.Action... actions) throws ServiceException { 550 List<AccessControlProtos.Permission.Action> permActions = 551 Lists.newArrayListWithCapacity(actions.length); 552 for (Permission.Action a : actions) { 553 permActions.add(toPermissionAction(a)); 554 } 555 AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, namespace, mergeExistingPermissions, 556 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 557 protocol.grant(controller, request); 558 } 559 560 /** 561 * A utility used to revoke a user's global permissions. 562 * <p> 563 * It's also called by the shell, in case you want to find references. 564 * 565 * @param protocol the AccessControlService protocol proxy 566 * @param userShortName the short name of the user to revoke permissions 567 * @param actions the permissions to be revoked 568 * @throws ServiceException 569 */ 570 public static void revoke(RpcController controller, 571 AccessControlService.BlockingInterface protocol, String userShortName, 572 Permission.Action... actions) throws ServiceException { 573 List<AccessControlProtos.Permission.Action> permActions = 574 Lists.newArrayListWithCapacity(actions.length); 575 for (Permission.Action a : actions) { 576 permActions.add(toPermissionAction(a)); 577 } 578 AccessControlProtos.RevokeRequest request = buildRevokeRequest(userShortName, 579 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 580 protocol.revoke(controller, request); 581 } 582 583 /** 584 * A utility used to revoke a user's table permissions. The permissions will 585 * be for a table/column family/qualifier. 586 * <p> 587 * It's also called by the shell, in case you want to find references. 588 * 589 * @param protocol the AccessControlService protocol proxy 590 * @param userShortName the short name of the user to revoke permissions 591 * @param tableName optional table name 592 * @param f optional column family 593 * @param q optional qualifier 594 * @param actions the permissions to be revoked 595 * @throws ServiceException 596 */ 597 public static void revoke(RpcController controller, 598 AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName, 599 byte[] f, byte[] q, Permission.Action... actions) throws ServiceException { 600 List<AccessControlProtos.Permission.Action> permActions = 601 Lists.newArrayListWithCapacity(actions.length); 602 for (Permission.Action a : actions) { 603 permActions.add(toPermissionAction(a)); 604 } 605 AccessControlProtos.RevokeRequest request = buildRevokeRequest(userShortName, tableName, f, q, 606 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 607 protocol.revoke(controller, request); 608 } 609 610 /** 611 * A utility used to revoke a user's namespace permissions. 612 * <p> 613 * It's also called by the shell, in case you want to find references. 614 * 615 * @param protocol the AccessControlService protocol proxy 616 * @param userShortName the short name of the user to revoke permissions 617 * @param namespace optional table name 618 * @param actions the permissions to be revoked 619 * @throws ServiceException 620 */ 621 public static void revoke(RpcController controller, 622 AccessControlService.BlockingInterface protocol, String userShortName, String namespace, 623 Permission.Action... actions) throws ServiceException { 624 List<AccessControlProtos.Permission.Action> permActions = 625 Lists.newArrayListWithCapacity(actions.length); 626 for (Permission.Action a : actions) { 627 permActions.add(toPermissionAction(a)); 628 } 629 AccessControlProtos.RevokeRequest request = buildRevokeRequest(userShortName, namespace, 630 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 631 protocol.revoke(controller, request); 632 } 633 634 /** 635 * A utility used to get user's global permissions. 636 * <p> 637 * It's also called by the shell, in case you want to find references. 638 * 639 * @param protocol the AccessControlService protocol proxy 640 * @throws ServiceException 641 */ 642 public static List<UserPermission> getUserPermissions(RpcController controller, 643 AccessControlService.BlockingInterface protocol) throws ServiceException { 644 AccessControlProtos.GetUserPermissionsRequest.Builder builder = 645 AccessControlProtos.GetUserPermissionsRequest.newBuilder(); 646 builder.setType(AccessControlProtos.Permission.Type.Global); 647 AccessControlProtos.GetUserPermissionsRequest request = builder.build(); 648 AccessControlProtos.GetUserPermissionsResponse response = 649 protocol.getUserPermissions(controller, request); 650 List<UserPermission> perms = new ArrayList<>(response.getUserPermissionCount()); 651 for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { 652 perms.add(toUserPermission(perm)); 653 } 654 return perms; 655 } 656 657 /** 658 * A utility used to get user table permissions. 659 * <p> 660 * It's also called by the shell, in case you want to find references. 661 * 662 * @param protocol the AccessControlService protocol proxy 663 * @param t optional table name 664 * @throws ServiceException 665 */ 666 public static List<UserPermission> getUserPermissions(RpcController controller, 667 AccessControlService.BlockingInterface protocol, 668 TableName t) throws ServiceException { 669 AccessControlProtos.GetUserPermissionsRequest.Builder builder = 670 AccessControlProtos.GetUserPermissionsRequest.newBuilder(); 671 if (t != null) { 672 builder.setTableName(ProtobufUtil.toProtoTableName(t)); 673 } 674 builder.setType(AccessControlProtos.Permission.Type.Table); 675 AccessControlProtos.GetUserPermissionsRequest request = builder.build(); 676 AccessControlProtos.GetUserPermissionsResponse response = 677 protocol.getUserPermissions(controller, request); 678 List<UserPermission> perms = new ArrayList<>(response.getUserPermissionCount()); 679 for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { 680 perms.add(toUserPermission(perm)); 681 } 682 return perms; 683 } 684 685 /** 686 * A utility used to get permissions for selected namespace. 687 * <p> 688 * It's also called by the shell, in case you want to find references. 689 * 690 * @param protocol the AccessControlService protocol proxy 691 * @param namespace name of the namespace 692 * @throws ServiceException 693 */ 694 public static List<UserPermission> getUserPermissions(RpcController controller, 695 AccessControlService.BlockingInterface protocol, 696 byte[] namespace) throws ServiceException { 697 AccessControlProtos.GetUserPermissionsRequest.Builder builder = 698 AccessControlProtos.GetUserPermissionsRequest.newBuilder(); 699 if (namespace != null) { 700 builder.setNamespaceName(ByteStringer.wrap(namespace)); 701 } 702 builder.setType(AccessControlProtos.Permission.Type.Namespace); 703 AccessControlProtos.GetUserPermissionsRequest request = builder.build(); 704 AccessControlProtos.GetUserPermissionsResponse response = 705 protocol.getUserPermissions(controller, request); 706 List<UserPermission> perms = new ArrayList<>(response.getUserPermissionCount()); 707 for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { 708 perms.add(toUserPermission(perm)); 709 } 710 return perms; 711 } 712 713 /** 714 * Convert a protobuf UserTablePermissions to a 715 * ListMultimap<String, TablePermission> where key is username. 716 * 717 * @param proto the protobuf UserPermission 718 * @return the converted UserPermission 719 */ 720 public static ListMultimap<String, TablePermission> toUserTablePermissions( 721 AccessControlProtos.UsersAndPermissions proto) { 722 ListMultimap<String, TablePermission> perms = ArrayListMultimap.create(); 723 AccessControlProtos.UsersAndPermissions.UserPermissions userPerm; 724 for (int i = 0; i < proto.getUserPermissionsCount(); i++) { 725 userPerm = proto.getUserPermissions(i); 726 for (int j = 0; j < userPerm.getPermissionsCount(); j++) { 727 TablePermission tablePerm = toTablePermission(userPerm.getPermissions(j)); 728 perms.put(userPerm.getUser().toStringUtf8(), tablePerm); 729 } 730 } 731 return perms; 732 } 733 734 /** 735 * Create a request to revoke user permissions. 736 * 737 * @param username the short user name whose permissions to be revoked 738 * @param tableName optional table name the permissions apply 739 * @param family optional column family 740 * @param qualifier optional qualifier 741 * @param actions the permissions to be revoked 742 * @return A {@link AccessControlProtos} RevokeRequest 743 */ 744 public static AccessControlProtos.RevokeRequest buildRevokeRequest( 745 String username, TableName tableName, byte[] family, byte[] qualifier, 746 AccessControlProtos.Permission.Action... actions) { 747 AccessControlProtos.Permission.Builder ret = 748 AccessControlProtos.Permission.newBuilder(); 749 AccessControlProtos.TablePermission.Builder permissionBuilder = 750 AccessControlProtos.TablePermission.newBuilder(); 751 for (AccessControlProtos.Permission.Action a : actions) { 752 permissionBuilder.addAction(a); 753 } 754 if (tableName != null) { 755 permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName)); 756 } 757 if (family != null) { 758 permissionBuilder.setFamily(ByteStringer.wrap(family)); 759 } 760 if (qualifier != null) { 761 permissionBuilder.setQualifier(ByteStringer.wrap(qualifier)); 762 } 763 ret.setType(AccessControlProtos.Permission.Type.Table) 764 .setTablePermission(permissionBuilder); 765 return AccessControlProtos.RevokeRequest.newBuilder() 766 .setUserPermission( 767 AccessControlProtos.UserPermission.newBuilder() 768 .setUser(ByteString.copyFromUtf8(username)) 769 .setPermission(ret) 770 ).build(); 771 } 772}