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.commons.lang3.StringUtils; 026import org.apache.hadoop.hbase.HConstants; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.Admin; 029import org.apache.yetus.audience.InterfaceAudience; 030import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 031import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos; 032import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService; 033import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GetUserPermissionsResponse; 034import org.apache.hadoop.hbase.util.ByteStringer; 035import org.apache.hadoop.hbase.util.Bytes; 036import org.apache.hbase.thirdparty.com.google.common.collect.ArrayListMultimap; 037import org.apache.hbase.thirdparty.com.google.common.collect.ListMultimap; 038import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 039import com.google.protobuf.ByteString; 040import com.google.protobuf.RpcController; 041import com.google.protobuf.ServiceException; 042 043/** 044 * @since 2.0.0 045 */ 046@InterfaceAudience.Private 047public class AccessControlUtil { 048 private AccessControlUtil() {} 049 050 /** 051 * Create a request to grant user table permissions. 052 * 053 * @param username the short user name who to grant permissions 054 * @param tableName optional table name the permissions apply 055 * @param family optional column family 056 * @param qualifier optional qualifier 057 * @param actions the permissions to be granted 058 * @return A {@link AccessControlProtos} GrantRequest 059 */ 060 public static AccessControlProtos.GrantRequest buildGrantRequest( 061 String username, TableName tableName, byte[] family, byte[] qualifier, 062 boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) { 063 AccessControlProtos.Permission.Builder ret = 064 AccessControlProtos.Permission.newBuilder(); 065 AccessControlProtos.TablePermission.Builder permissionBuilder = 066 AccessControlProtos.TablePermission.newBuilder(); 067 for (AccessControlProtos.Permission.Action a : actions) { 068 permissionBuilder.addAction(a); 069 } 070 if (tableName == null) { 071 throw new NullPointerException("TableName cannot be null"); 072 } 073 permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName)); 074 075 if (family != null) { 076 permissionBuilder.setFamily(ByteStringer.wrap(family)); 077 } 078 if (qualifier != null) { 079 permissionBuilder.setQualifier(ByteStringer.wrap(qualifier)); 080 } 081 ret.setType(AccessControlProtos.Permission.Type.Table) 082 .setTablePermission(permissionBuilder); 083 return AccessControlProtos.GrantRequest.newBuilder() 084 .setUserPermission( 085 AccessControlProtos.UserPermission.newBuilder() 086 .setUser(ByteString.copyFromUtf8(username)) 087 .setPermission(ret) 088 ).setMergeExistingPermissions(mergeExistingPermissions).build(); 089 } 090 091 /** 092 * Create a request to grant user namespace permissions. 093 * 094 * @param username the short user name who to grant permissions 095 * @param namespace optional table name the permissions apply 096 * @param actions the permissions to be granted 097 * @return A {@link AccessControlProtos} GrantRequest 098 */ 099 public static AccessControlProtos.GrantRequest buildGrantRequest( 100 String username, String namespace, boolean mergeExistingPermissions, 101 AccessControlProtos.Permission.Action... actions) { 102 AccessControlProtos.Permission.Builder ret = 103 AccessControlProtos.Permission.newBuilder(); 104 AccessControlProtos.NamespacePermission.Builder permissionBuilder = 105 AccessControlProtos.NamespacePermission.newBuilder(); 106 for (AccessControlProtos.Permission.Action a : actions) { 107 permissionBuilder.addAction(a); 108 } 109 if (namespace != null) { 110 permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace)); 111 } 112 ret.setType(AccessControlProtos.Permission.Type.Namespace) 113 .setNamespacePermission(permissionBuilder); 114 return AccessControlProtos.GrantRequest.newBuilder() 115 .setUserPermission( 116 AccessControlProtos.UserPermission.newBuilder() 117 .setUser(ByteString.copyFromUtf8(username)) 118 .setPermission(ret) 119 ).setMergeExistingPermissions(mergeExistingPermissions).build(); 120 } 121 122 /** 123 * Create a request to revoke user global permissions. 124 * 125 * @param username the short user name whose permissions to be revoked 126 * @param actions the permissions to be revoked 127 * @return A {@link AccessControlProtos} RevokeRequest 128 */ 129 public static AccessControlProtos.RevokeRequest buildRevokeRequest( 130 String username, AccessControlProtos.Permission.Action... actions) { 131 AccessControlProtos.Permission.Builder ret = 132 AccessControlProtos.Permission.newBuilder(); 133 AccessControlProtos.GlobalPermission.Builder permissionBuilder = 134 AccessControlProtos.GlobalPermission.newBuilder(); 135 for (AccessControlProtos.Permission.Action a : actions) { 136 permissionBuilder.addAction(a); 137 } 138 ret.setType(AccessControlProtos.Permission.Type.Global) 139 .setGlobalPermission(permissionBuilder); 140 return AccessControlProtos.RevokeRequest.newBuilder() 141 .setUserPermission( 142 AccessControlProtos.UserPermission.newBuilder() 143 .setUser(ByteString.copyFromUtf8(username)) 144 .setPermission(ret) 145 ).build(); 146 } 147 148 /** 149 * Create a request to revoke user namespace permissions. 150 * 151 * @param username the short user name whose permissions to be revoked 152 * @param namespace optional table name the permissions apply 153 * @param actions the permissions to be revoked 154 * @return A {@link AccessControlProtos} RevokeRequest 155 */ 156 public static AccessControlProtos.RevokeRequest buildRevokeRequest( 157 String username, String namespace, 158 AccessControlProtos.Permission.Action... actions) { 159 AccessControlProtos.Permission.Builder ret = 160 AccessControlProtos.Permission.newBuilder(); 161 AccessControlProtos.NamespacePermission.Builder permissionBuilder = 162 AccessControlProtos.NamespacePermission.newBuilder(); 163 for (AccessControlProtos.Permission.Action a : actions) { 164 permissionBuilder.addAction(a); 165 } 166 if (namespace != null) { 167 permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace)); 168 } 169 ret.setType(AccessControlProtos.Permission.Type.Namespace) 170 .setNamespacePermission(permissionBuilder); 171 return AccessControlProtos.RevokeRequest.newBuilder() 172 .setUserPermission( 173 AccessControlProtos.UserPermission.newBuilder() 174 .setUser(ByteString.copyFromUtf8(username)) 175 .setPermission(ret) 176 ).build(); 177 } 178 179 /** 180 * Create a request to grant user global permissions. 181 * 182 * @param username the short user name who to grant permissions 183 * @param actions the permissions to be granted 184 * @return A {@link AccessControlProtos} GrantRequest 185 */ 186 public static AccessControlProtos.GrantRequest buildGrantRequest(String username, 187 boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) { 188 AccessControlProtos.Permission.Builder ret = 189 AccessControlProtos.Permission.newBuilder(); 190 AccessControlProtos.GlobalPermission.Builder permissionBuilder = 191 AccessControlProtos.GlobalPermission.newBuilder(); 192 for (AccessControlProtos.Permission.Action a : actions) { 193 permissionBuilder.addAction(a); 194 } 195 ret.setType(AccessControlProtos.Permission.Type.Global) 196 .setGlobalPermission(permissionBuilder); 197 return AccessControlProtos.GrantRequest.newBuilder() 198 .setUserPermission( 199 AccessControlProtos.UserPermission.newBuilder() 200 .setUser(ByteString.copyFromUtf8(username)) 201 .setPermission(ret) 202 ).setMergeExistingPermissions(mergeExistingPermissions).build(); 203 } 204 205 public static AccessControlProtos.UsersAndPermissions toUsersAndPermissions(String user, 206 Permission perms) { 207 return AccessControlProtos.UsersAndPermissions.newBuilder() 208 .addUserPermissions(AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder() 209 .setUser(ByteString.copyFromUtf8(user)) 210 .addPermissions(toPermission(perms)) 211 .build()) 212 .build(); 213 } 214 215 public static AccessControlProtos.UsersAndPermissions toUsersAndPermissions( 216 ListMultimap<String, Permission> perms) { 217 AccessControlProtos.UsersAndPermissions.Builder builder = 218 AccessControlProtos.UsersAndPermissions.newBuilder(); 219 for (Map.Entry<String, Collection<Permission>> entry : perms.asMap().entrySet()) { 220 AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder = 221 AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder(); 222 userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey())); 223 for (Permission perm: entry.getValue()) { 224 userPermBuilder.addPermissions(toPermission(perm)); 225 } 226 builder.addUserPermissions(userPermBuilder.build()); 227 } 228 return builder.build(); 229 } 230 231 public static ListMultimap<String, Permission> toUsersAndPermissions( 232 AccessControlProtos.UsersAndPermissions proto) { 233 ListMultimap<String, Permission> result = ArrayListMultimap.create(); 234 for (AccessControlProtos.UsersAndPermissions.UserPermissions userPerms: 235 proto.getUserPermissionsList()) { 236 String user = userPerms.getUser().toStringUtf8(); 237 for (AccessControlProtos.Permission perm: userPerms.getPermissionsList()) { 238 result.put(user, toPermission(perm)); 239 } 240 } 241 return result; 242 } 243 244 /** 245 * Converts a TablePermission proto to a client TablePermission object. 246 * @param proto the protobuf TablePermission 247 * @return the converted TablePermission 248 */ 249 public static TablePermission toTablePermission(AccessControlProtos.TablePermission proto) { 250 Permission.Action[] actions = toPermissionActions(proto.getActionList()); 251 TableName table = null; 252 byte[] qualifier = null; 253 byte[] family = null; 254 if (!proto.hasTableName()) { 255 throw new IllegalStateException("TableName cannot be empty"); 256 } 257 table = ProtobufUtil.toTableName(proto.getTableName()); 258 if (proto.hasFamily()) { 259 family = proto.getFamily().toByteArray(); 260 } 261 if (proto.hasQualifier()) { 262 qualifier = proto.getQualifier().toByteArray(); 263 } 264 return new TablePermission(table, family, qualifier, actions); 265 } 266 267 /** 268 * Converts a Permission proto to a client Permission object. 269 * @param proto the protobuf Permission 270 * @return the converted Permission 271 */ 272 public static Permission toPermission(AccessControlProtos.Permission proto) { 273 if (proto.getType() == AccessControlProtos.Permission.Type.Global) { 274 AccessControlProtos.GlobalPermission perm = proto.getGlobalPermission(); 275 Permission.Action[] actions = toPermissionActions(perm.getActionList()); 276 return Permission.newBuilder().withActions(actions).build(); 277 } 278 if (proto.getType() == AccessControlProtos.Permission.Type.Namespace) { 279 AccessControlProtos.NamespacePermission perm = proto.getNamespacePermission(); 280 Permission.Action[] actions = toPermissionActions(perm.getActionList()); 281 if (!proto.hasNamespacePermission()) { 282 throw new IllegalStateException("Namespace must not be empty in NamespacePermission"); 283 } 284 return Permission.newBuilder(perm.getNamespaceName().toStringUtf8()).withActions(actions) 285 .build(); 286 } 287 if (proto.getType() == AccessControlProtos.Permission.Type.Table) { 288 AccessControlProtos.TablePermission perm = proto.getTablePermission(); 289 Permission.Action[] actions = toPermissionActions(perm.getActionList()); 290 byte[] qualifier = null; 291 byte[] family = null; 292 TableName table = null; 293 if (!perm.hasTableName()) { 294 throw new IllegalStateException("TableName cannot be empty"); 295 } 296 table = ProtobufUtil.toTableName(perm.getTableName()); 297 if (perm.hasFamily()) { 298 family = perm.getFamily().toByteArray(); 299 } 300 if (perm.hasQualifier()) { 301 qualifier = perm.getQualifier().toByteArray(); 302 } 303 return Permission.newBuilder(table).withFamily(family).withQualifier(qualifier) 304 .withActions(actions).build(); 305 } 306 throw new IllegalStateException("Unrecognize Perm Type: " + proto.getType()); 307 } 308 309 /** 310 * Convert a client Permission to a Permission proto 311 * 312 * @param perm the client Permission 313 * @return the protobuf Permission 314 */ 315 public static AccessControlProtos.Permission toPermission(Permission perm) { 316 AccessControlProtos.Permission.Builder ret = AccessControlProtos.Permission.newBuilder(); 317 if (perm instanceof NamespacePermission) { 318 NamespacePermission namespace = (NamespacePermission) perm; 319 ret.setType(AccessControlProtos.Permission.Type.Namespace); 320 AccessControlProtos.NamespacePermission.Builder builder = 321 AccessControlProtos.NamespacePermission.newBuilder(); 322 builder.setNamespaceName(ByteString.copyFromUtf8(namespace.getNamespace())); 323 Permission.Action[] actions = perm.getActions(); 324 if (actions != null) { 325 for (Permission.Action a : actions) { 326 builder.addAction(toPermissionAction(a)); 327 } 328 } 329 ret.setNamespacePermission(builder); 330 } else if (perm instanceof TablePermission) { 331 TablePermission table = (TablePermission) perm; 332 ret.setType(AccessControlProtos.Permission.Type.Table); 333 AccessControlProtos.TablePermission.Builder builder = 334 AccessControlProtos.TablePermission.newBuilder(); 335 builder.setTableName(ProtobufUtil.toProtoTableName(table.getTableName())); 336 if (table.hasFamily()) { 337 builder.setFamily(ByteStringer.wrap(table.getFamily())); 338 } 339 if (table.hasQualifier()) { 340 builder.setQualifier(ByteStringer.wrap(table.getQualifier())); 341 } 342 Permission.Action[] actions = perm.getActions(); 343 if (actions != null) { 344 for (Permission.Action a : actions) { 345 builder.addAction(toPermissionAction(a)); 346 } 347 } 348 ret.setTablePermission(builder); 349 } else { 350 // perm instanceof GlobalPermission 351 ret.setType(AccessControlProtos.Permission.Type.Global); 352 AccessControlProtos.GlobalPermission.Builder builder = 353 AccessControlProtos.GlobalPermission.newBuilder(); 354 Permission.Action[] actions = perm.getActions(); 355 if (actions != null) { 356 for (Permission.Action a: actions) { 357 builder.addAction(toPermissionAction(a)); 358 } 359 } 360 ret.setGlobalPermission(builder); 361 } 362 return ret.build(); 363 } 364 365 /** 366 * Converts a list of Permission.Action proto to an array of client Permission.Action objects. 367 * 368 * @param protoActions the list of protobuf Actions 369 * @return the converted array of Actions 370 */ 371 public static Permission.Action[] 372 toPermissionActions(List<AccessControlProtos.Permission.Action> protoActions) { 373 Permission.Action[] actions = new Permission.Action[protoActions.size()]; 374 for (int i = 0; i < protoActions.size(); i++) { 375 actions[i] = toPermissionAction(protoActions.get(i)); 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(ByteString.copyFromUtf8(perm.getUser())) 435 .setPermission(toPermission(perm.getPermission())) 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().toStringUtf8(), toPermission(proto.getPermission())); 459 } 460 461 /** 462 * Convert a ListMultimap<String, TablePermission> where key is username 463 * to a protobuf UserPermission 464 * 465 * @param perm the list of user and table permissions 466 * @return the protobuf UserTablePermissions 467 */ 468 public static AccessControlProtos.UsersAndPermissions toUserTablePermissions( 469 ListMultimap<String, UserPermission> perm) { 470 AccessControlProtos.UsersAndPermissions.Builder builder = 471 AccessControlProtos.UsersAndPermissions.newBuilder(); 472 for (Map.Entry<String, Collection<UserPermission>> entry : perm.asMap().entrySet()) { 473 AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder = 474 AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder(); 475 userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey())); 476 for (UserPermission userPerm: entry.getValue()) { 477 userPermBuilder.addPermissions(toPermission(userPerm.getPermission())); 478 } 479 builder.addUserPermissions(userPermBuilder.build()); 480 } 481 return builder.build(); 482 } 483 484 /** 485 * A utility used to grant a user global permissions. 486 * <p> 487 * It's also called by the shell, in case you want to find references. 488 * 489 * @param protocol the AccessControlService protocol proxy 490 * @param userShortName the short name of the user to grant permissions 491 * @param actions the permissions to be granted 492 * @throws ServiceException 493 * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead. 494 */ 495 @Deprecated 496 public static void grant(RpcController controller, 497 AccessControlService.BlockingInterface protocol, String userShortName, boolean mergeExistingPermissions, 498 Permission.Action... actions) throws ServiceException { 499 List<AccessControlProtos.Permission.Action> permActions = 500 Lists.newArrayListWithCapacity(actions.length); 501 for (Permission.Action a : actions) { 502 permActions.add(toPermissionAction(a)); 503 } 504 AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, mergeExistingPermissions, 505 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 506 protocol.grant(controller, request); 507 } 508 509 /** 510 * A utility used to grant a user table permissions. The permissions will 511 * be for a table table/column family/qualifier. 512 * <p> 513 * It's also called by the shell, in case you want to find references. 514 * 515 * @param protocol the AccessControlService protocol proxy 516 * @param userShortName the short name of the user to grant permissions 517 * @param tableName optional table name 518 * @param f optional column family 519 * @param q optional qualifier 520 * @param actions the permissions to be granted 521 * @throws ServiceException 522 * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead. 523 */ 524 @Deprecated 525 public static void grant(RpcController controller, 526 AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName, 527 byte[] f, byte[] q, boolean mergeExistingPermissions, Permission.Action... actions) 528 throws ServiceException { 529 List<AccessControlProtos.Permission.Action> permActions = 530 Lists.newArrayListWithCapacity(actions.length); 531 for (Permission.Action a : actions) { 532 permActions.add(toPermissionAction(a)); 533 } 534 AccessControlProtos.GrantRequest request = 535 buildGrantRequest(userShortName, tableName, f, q, mergeExistingPermissions, 536 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 537 protocol.grant(controller, request); 538 } 539 540 /** 541 * A utility used to grant a user namespace permissions. 542 * <p> 543 * It's also called by the shell, in case you want to find references. 544 * 545 * @param controller RpcController 546 * @param protocol the AccessControlService protocol proxy 547 * @param namespace the short name of the user to grant permissions 548 * @param actions the permissions to be granted 549 * @throws ServiceException 550 * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead. 551 */ 552 @Deprecated 553 public static void grant(RpcController controller, 554 AccessControlService.BlockingInterface protocol, String userShortName, String namespace, 555 boolean mergeExistingPermissions, Permission.Action... actions) throws ServiceException { 556 List<AccessControlProtos.Permission.Action> permActions = 557 Lists.newArrayListWithCapacity(actions.length); 558 for (Permission.Action a : actions) { 559 permActions.add(toPermissionAction(a)); 560 } 561 AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, namespace, mergeExistingPermissions, 562 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 563 protocol.grant(controller, request); 564 } 565 566 /** 567 * A utility used to revoke a user's global permissions. 568 * <p> 569 * It's also called by the shell, in case you want to find references. 570 * 571 * @param controller RpcController 572 * @param protocol the AccessControlService protocol proxy 573 * @param userShortName the short name of the user to revoke permissions 574 * @param actions the permissions to be revoked 575 * @throws ServiceException on failure 576 * @deprecated Use {@link Admin#revoke(UserPermission)} instead. 577 */ 578 @Deprecated 579 public static void revoke(RpcController controller, 580 AccessControlService.BlockingInterface protocol, String userShortName, 581 Permission.Action... actions) throws ServiceException { 582 List<AccessControlProtos.Permission.Action> permActions = 583 Lists.newArrayListWithCapacity(actions.length); 584 for (Permission.Action a : actions) { 585 permActions.add(toPermissionAction(a)); 586 } 587 AccessControlProtos.RevokeRequest request = buildRevokeRequest(userShortName, 588 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 589 protocol.revoke(controller, request); 590 } 591 592 /** 593 * A utility used to revoke a user's table permissions. The permissions will 594 * be for a table/column family/qualifier. 595 * <p> 596 * It's also called by the shell, in case you want to find references. 597 * 598 * @param controller RpcController 599 * @param protocol the AccessControlService protocol proxy 600 * @param userShortName the short name of the user to revoke permissions 601 * @param tableName optional table name 602 * @param f optional column family 603 * @param q optional qualifier 604 * @param actions the permissions to be revoked 605 * @throws ServiceException on failure 606 * @deprecated Use {@link Admin#revoke(UserPermission)} instead. 607 */ 608 @Deprecated 609 public static void revoke(RpcController controller, 610 AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName, 611 byte[] f, byte[] q, Permission.Action... actions) throws ServiceException { 612 List<AccessControlProtos.Permission.Action> permActions = 613 Lists.newArrayListWithCapacity(actions.length); 614 for (Permission.Action a : actions) { 615 permActions.add(toPermissionAction(a)); 616 } 617 AccessControlProtos.RevokeRequest request = buildRevokeRequest(userShortName, tableName, f, q, 618 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 619 protocol.revoke(controller, request); 620 } 621 622 /** 623 * A utility used to revoke a user's namespace permissions. 624 * <p> 625 * It's also called by the shell, in case you want to find references. 626 * 627 * @param controller RpcController 628 * @param protocol the AccessControlService protocol proxy 629 * @param userShortName the short name of the user to revoke permissions 630 * @param namespace optional table name 631 * @param actions the permissions to be revoked 632 * @throws ServiceException on failure 633 * @deprecated Use {@link Admin#revoke(UserPermission)} instead. 634 */ 635 @Deprecated 636 public static void revoke(RpcController controller, 637 AccessControlService.BlockingInterface protocol, String userShortName, String namespace, 638 Permission.Action... actions) throws ServiceException { 639 List<AccessControlProtos.Permission.Action> permActions = 640 Lists.newArrayListWithCapacity(actions.length); 641 for (Permission.Action a : actions) { 642 permActions.add(toPermissionAction(a)); 643 } 644 AccessControlProtos.RevokeRequest request = buildRevokeRequest(userShortName, namespace, 645 permActions.toArray(new AccessControlProtos.Permission.Action[actions.length])); 646 protocol.revoke(controller, request); 647 } 648 649 /** 650 * A utility used to get user's global permissions. 651 * <p> 652 * It's also called by the shell, in case you want to find references. 653 * 654 * @param controller RpcController 655 * @param protocol the AccessControlService protocol proxy 656 * @throws ServiceException on failure 657 * @deprecated Use {@link Admin#getUserPermissions(GetUserPermissionsRequest)} instead. 658 */ 659 @Deprecated 660 public static List<UserPermission> getUserPermissions(RpcController controller, 661 AccessControlService.BlockingInterface protocol) throws ServiceException { 662 return getUserPermissions(controller, protocol, HConstants.EMPTY_STRING); 663 } 664 665 /** 666 * A utility used to get user's global permissions based on the specified user name. 667 * @param controller RpcController 668 * @param protocol the AccessControlService protocol proxy 669 * @param userName User name, if empty then all user permissions will be retrieved. 670 * @throws ServiceException 671 * @deprecated Use {@link Admin#getUserPermissions(GetUserPermissionsRequest)} instead. 672 */ 673 @Deprecated 674 public static List<UserPermission> getUserPermissions(RpcController controller, 675 AccessControlService.BlockingInterface protocol, String userName) throws ServiceException { 676 AccessControlProtos.GetUserPermissionsRequest.Builder builder = 677 AccessControlProtos.GetUserPermissionsRequest.newBuilder(); 678 builder.setType(AccessControlProtos.Permission.Type.Global); 679 if (!StringUtils.isEmpty(userName)) { 680 builder.setUserName(ByteString.copyFromUtf8(userName)); 681 } 682 683 AccessControlProtos.GetUserPermissionsRequest request = builder.build(); 684 AccessControlProtos.GetUserPermissionsResponse response = 685 protocol.getUserPermissions(controller, request); 686 List<UserPermission> perms = new ArrayList<>(response.getUserPermissionCount()); 687 for (AccessControlProtos.UserPermission perm : response.getUserPermissionList()) { 688 perms.add(toUserPermission(perm)); 689 } 690 return perms; 691 } 692 693 /** 694 * A utility used to get user table permissions. 695 * <p> 696 * It's also called by the shell, in case you want to find references. 697 * 698 * @param controller RpcController 699 * @param protocol the AccessControlService protocol proxy 700 * @param t optional table name 701 * @throws ServiceException 702 * @deprecated Use {@link Admin#getUserPermissions(GetUserPermissionsRequest)} instead. 703 */ 704 @Deprecated 705 public static List<UserPermission> getUserPermissions(RpcController controller, 706 AccessControlService.BlockingInterface protocol, 707 TableName t) throws ServiceException { 708 return getUserPermissions(controller, protocol, t, null, null, HConstants.EMPTY_STRING); 709 } 710 711 /** 712 * A utility used to get user table permissions based on the column family, column qualifier and 713 * user name. 714 * @param controller RpcController 715 * @param protocol the AccessControlService protocol proxy 716 * @param t optional table name 717 * @param columnFamily Column family 718 * @param columnQualifier Column qualifier 719 * @param userName User name, if empty then all user permissions will be retrieved. 720 * @throws ServiceException 721 * @deprecated Use {@link Admin#getUserPermissions(GetUserPermissionsRequest)} instead. 722 */ 723 @Deprecated 724 public static List<UserPermission> getUserPermissions(RpcController controller, 725 AccessControlService.BlockingInterface protocol, TableName t, byte[] columnFamily, 726 byte[] columnQualifier, String userName) throws ServiceException { 727 AccessControlProtos.GetUserPermissionsRequest.Builder builder = 728 AccessControlProtos.GetUserPermissionsRequest.newBuilder(); 729 if (t != null) { 730 builder.setTableName(ProtobufUtil.toProtoTableName(t)); 731 } 732 if (Bytes.len(columnFamily) > 0) { 733 builder.setColumnFamily(ByteString.copyFrom(columnFamily)); 734 } 735 if (Bytes.len(columnQualifier) > 0) { 736 builder.setColumnQualifier(ByteString.copyFrom(columnQualifier)); 737 } 738 if (!StringUtils.isEmpty(userName)) { 739 builder.setUserName(ByteString.copyFromUtf8(userName)); 740 } 741 742 builder.setType(AccessControlProtos.Permission.Type.Table); 743 AccessControlProtos.GetUserPermissionsRequest request = builder.build(); 744 AccessControlProtos.GetUserPermissionsResponse response = 745 protocol.getUserPermissions(controller, request); 746 List<UserPermission> perms = new ArrayList<>(response.getUserPermissionCount()); 747 for (AccessControlProtos.UserPermission perm : response.getUserPermissionList()) { 748 perms.add(toUserPermission(perm)); 749 } 750 return perms; 751 } 752 753 /** 754 * A utility used to get permissions for selected namespace. 755 * <p> 756 * It's also called by the shell, in case you want to find references. 757 * 758 * @param controller RpcController 759 * @param protocol the AccessControlService protocol proxy 760 * @param namespace name of the namespace 761 * @throws ServiceException 762 * @deprecated Use {@link Admin#getUserPermissions(GetUserPermissionsRequest)} instead. 763 */ 764 @Deprecated 765 public static List<UserPermission> getUserPermissions(RpcController controller, 766 AccessControlService.BlockingInterface protocol, 767 byte[] namespace) throws ServiceException { 768 return getUserPermissions(controller, protocol, namespace, HConstants.EMPTY_STRING); 769 } 770 771 /** 772 * A utility used to get permissions for selected namespace based on the specified user name. 773 * @param controller RpcController 774 * @param protocol the AccessControlService protocol proxy 775 * @param namespace name of the namespace 776 * @param userName User name, if empty then all user permissions will be retrieved. 777 * @throws ServiceException 778 * @deprecated Use {@link Admin#getUserPermissions(GetUserPermissionsRequest)} instead. 779 */ 780 @Deprecated 781 public static List<UserPermission> getUserPermissions(RpcController controller, 782 AccessControlService.BlockingInterface protocol, byte[] namespace, String userName) 783 throws ServiceException { 784 AccessControlProtos.GetUserPermissionsRequest.Builder builder = 785 AccessControlProtos.GetUserPermissionsRequest.newBuilder(); 786 if (namespace != null) { 787 builder.setNamespaceName(ByteStringer.wrap(namespace)); 788 } 789 if (!StringUtils.isEmpty(userName)) { 790 builder.setUserName(ByteString.copyFromUtf8(userName)); 791 } 792 builder.setType(AccessControlProtos.Permission.Type.Namespace); 793 AccessControlProtos.GetUserPermissionsRequest request = builder.build(); 794 AccessControlProtos.GetUserPermissionsResponse response = 795 protocol.getUserPermissions(controller, request); 796 List<UserPermission> perms = new ArrayList<>(response.getUserPermissionCount()); 797 for (AccessControlProtos.UserPermission perm : response.getUserPermissionList()) { 798 perms.add(toUserPermission(perm)); 799 } 800 return perms; 801 } 802 803 /** 804 * Validates whether specified user has permission to perform actions on the mentioned table, 805 * column family or column qualifier. 806 * @param controller RpcController 807 * @param protocol the AccessControlService protocol proxy 808 * @param tableName Table name, it shouldn't be null or empty. 809 * @param columnFamily The column family. Optional argument, can be empty. If empty then 810 * validation will happen at table level. 811 * @param columnQualifier The column qualifier. Optional argument, can be empty. If empty then 812 * validation will happen at table and column family level. columnQualifier will not be 813 * considered if columnFamily is passed as null or empty. 814 * @param userName User name, it shouldn't be null or empty. 815 * @param actions Actions 816 * @return true if access allowed, otherwise false 817 * @throws ServiceException 818 * @deprecated Use {@link Admin#hasUserPermissions(String, List)} instead. 819 */ 820 @Deprecated 821 public static boolean hasPermission(RpcController controller, 822 AccessControlService.BlockingInterface protocol, TableName tableName, byte[] columnFamily, 823 byte[] columnQualifier, String userName, Permission.Action[] actions) 824 throws ServiceException { 825 AccessControlProtos.TablePermission.Builder tablePermissionBuilder = 826 AccessControlProtos.TablePermission.newBuilder(); 827 tablePermissionBuilder 828 .setTableName(org.apache.hadoop.hbase.protobuf.ProtobufUtil.toProtoTableName(tableName)); 829 if (Bytes.len(columnFamily) > 0) { 830 tablePermissionBuilder.setFamily(ByteStringer.wrap(columnFamily)); 831 } 832 if (Bytes.len(columnQualifier) > 0) { 833 tablePermissionBuilder.setQualifier(ByteString.copyFrom(columnQualifier)); 834 } 835 for (Permission.Action a : actions) { 836 tablePermissionBuilder.addAction(toPermissionAction(a)); 837 } 838 AccessControlProtos.HasPermissionRequest request = AccessControlProtos.HasPermissionRequest 839 .newBuilder().setTablePermission(tablePermissionBuilder) 840 .setUserName(ByteString.copyFromUtf8(userName)).build(); 841 AccessControlProtos.HasPermissionResponse response = 842 protocol.hasPermission(controller, request); 843 return response.getHasPermission(); 844 } 845 846 /** 847 * Convert a protobuf UserTablePermissions to a ListMultimap<Username, UserPermission> 848 * @param proto the proto UsersAndPermissions 849 * @return a ListMultimap with user and its permissions 850 */ 851 public static ListMultimap<String, UserPermission> toUserPermission( 852 AccessControlProtos.UsersAndPermissions proto) { 853 ListMultimap<String, UserPermission> userPermission = ArrayListMultimap.create(); 854 AccessControlProtos.UsersAndPermissions.UserPermissions userPerm; 855 for (int i = 0; i < proto.getUserPermissionsCount(); i++) { 856 userPerm = proto.getUserPermissions(i); 857 String username = userPerm.getUser().toStringUtf8(); 858 for (int j = 0; j < userPerm.getPermissionsCount(); j++) { 859 userPermission.put(username, 860 new UserPermission(username, toPermission(userPerm.getPermissions(j)))); 861 } 862 } 863 return userPermission; 864 } 865 866 /** 867 * Convert a protobuf UserTablePermissions to a ListMultimap<Username, Permission> 868 * @param proto the proto UsersAndPermissions 869 * @return a ListMultimap with user and its permissions 870 */ 871 public static ListMultimap<String, Permission> toPermission( 872 AccessControlProtos.UsersAndPermissions proto) { 873 ListMultimap<String, Permission> perms = ArrayListMultimap.create(); 874 AccessControlProtos.UsersAndPermissions.UserPermissions userPerm; 875 for (int i = 0; i < proto.getUserPermissionsCount(); i++) { 876 userPerm = proto.getUserPermissions(i); 877 String username = userPerm.getUser().toStringUtf8(); 878 for (int j = 0; j < userPerm.getPermissionsCount(); j++) { 879 perms.put(username, toPermission(userPerm.getPermissions(j))); 880 } 881 } 882 return perms; 883 } 884 885 /** 886 * Create a request to revoke user table permissions. 887 * 888 * @param username the short user name whose permissions to be revoked 889 * @param tableName optional table name the permissions apply 890 * @param family optional column family 891 * @param qualifier optional qualifier 892 * @param actions the permissions to be revoked 893 * @return A {@link AccessControlProtos} RevokeRequest 894 */ 895 public static AccessControlProtos.RevokeRequest buildRevokeRequest( 896 String username, TableName tableName, byte[] family, byte[] qualifier, 897 AccessControlProtos.Permission.Action... actions) { 898 AccessControlProtos.Permission.Builder ret = 899 AccessControlProtos.Permission.newBuilder(); 900 AccessControlProtos.TablePermission.Builder permissionBuilder = 901 AccessControlProtos.TablePermission.newBuilder(); 902 for (AccessControlProtos.Permission.Action a : actions) { 903 permissionBuilder.addAction(a); 904 } 905 if (tableName != null) { 906 permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName)); 907 } 908 if (family != null) { 909 permissionBuilder.setFamily(ByteStringer.wrap(family)); 910 } 911 if (qualifier != null) { 912 permissionBuilder.setQualifier(ByteStringer.wrap(qualifier)); 913 } 914 ret.setType(AccessControlProtos.Permission.Type.Table) 915 .setTablePermission(permissionBuilder); 916 return AccessControlProtos.RevokeRequest.newBuilder() 917 .setUserPermission( 918 AccessControlProtos.UserPermission.newBuilder() 919 .setUser(ByteString.copyFromUtf8(username)) 920 .setPermission(ret) 921 ).build(); 922 } 923}