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