org.apache.hadoop.hbase.security.access.ShadedAccessControlUtil Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.security.access;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.hadoop.hbase.TableName;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.common.collect.ArrayListMultimap;
import org.apache.hbase.thirdparty.com.google.common.collect.ListMultimap;
import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GetUserPermissionsResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.HasUserPermissionsRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
/**
* Convert protobuf objects in AccessControl.proto under hbase-protocol-shaded to user-oriented
* objects and vice versa.
* In HBASE-15638, we create a hbase-protocol-shaded module for upgrading protobuf version to 3.x,
* but there are still some coprocessor endpoints(such as AccessControl, Authentication,
* MulitRowMutation) which depend on hbase-protocol module for CPEP compatibility. In fact, we use
* PB objects in AccessControl.proto under hbase-protocol for access control logic and use shaded
* AccessControl.proto only for serializing/deserializing permissions of .snapshotinfo.
*/
@InterfaceAudience.Private
public class ShadedAccessControlUtil {
/**
* Convert a client user permission to a user permission shaded proto.
*/
public static AccessControlProtos.Permission.Action toPermissionAction(Permission.Action action) {
switch (action) {
case READ:
return AccessControlProtos.Permission.Action.READ;
case WRITE:
return AccessControlProtos.Permission.Action.WRITE;
case EXEC:
return AccessControlProtos.Permission.Action.EXEC;
case CREATE:
return AccessControlProtos.Permission.Action.CREATE;
case ADMIN:
return AccessControlProtos.Permission.Action.ADMIN;
}
throw new IllegalArgumentException("Unknown action value " + action.name());
}
/**
* Convert a Permission.Action shaded proto to a client Permission.Action object.
*/
public static Permission.Action toPermissionAction(AccessControlProtos.Permission.Action action) {
switch (action) {
case READ:
return Permission.Action.READ;
case WRITE:
return Permission.Action.WRITE;
case EXEC:
return Permission.Action.EXEC;
case CREATE:
return Permission.Action.CREATE;
case ADMIN:
return Permission.Action.ADMIN;
}
throw new IllegalArgumentException("Unknown action value " + action.name());
}
/**
* Converts a list of Permission.Action shaded proto to an array of client Permission.Action
* objects.
* @param protoActions the list of shaded protobuf Actions
* @return the converted array of Actions
*/
public static Permission.Action[]
toPermissionActions(List protoActions) {
Permission.Action[] actions = new Permission.Action[protoActions.size()];
for (int i = 0; i < protoActions.size(); i++) {
actions[i] = toPermissionAction(protoActions.get(i));
}
return actions;
}
public static org.apache.hadoop.hbase.TableName toTableName(HBaseProtos.TableName tableNamePB) {
return org.apache.hadoop.hbase.TableName.valueOf(
tableNamePB.getNamespace().asReadOnlyByteBuffer(),
tableNamePB.getQualifier().asReadOnlyByteBuffer());
}
public static HBaseProtos.TableName toProtoTableName(TableName tableName) {
return HBaseProtos.TableName.newBuilder()
.setNamespace(ByteString.copyFrom(tableName.getNamespace()))
.setQualifier(ByteString.copyFrom(tableName.getQualifier())).build();
}
/**
* Converts a Permission shaded proto to a client TablePermission object.
* @param proto the protobuf Permission
* @return the converted TablePermission
*/
public static Permission toPermission(AccessControlProtos.Permission proto) {
if (proto.getType() == AccessControlProtos.Permission.Type.Global) {
AccessControlProtos.GlobalPermission perm = proto.getGlobalPermission();
Permission.Action[] actions = toPermissionActions(perm.getActionList());
return Permission.newBuilder().withActions(actions).build();
}
if (proto.getType() == AccessControlProtos.Permission.Type.Namespace) {
AccessControlProtos.NamespacePermission perm = proto.getNamespacePermission();
Permission.Action[] actions = toPermissionActions(perm.getActionList());
if (!proto.hasNamespacePermission()) {
throw new IllegalStateException("Namespace must not be empty in NamespacePermission");
}
String ns = perm.getNamespaceName().toStringUtf8();
return Permission.newBuilder(ns).withActions(actions).build();
}
if (proto.getType() == AccessControlProtos.Permission.Type.Table) {
AccessControlProtos.TablePermission perm = proto.getTablePermission();
Permission.Action[] actions = toPermissionActions(perm.getActionList());
byte[] qualifier = null;
byte[] family = null;
if (!perm.hasTableName()) {
throw new IllegalStateException("TableName cannot be empty");
}
TableName table = toTableName(perm.getTableName());
if (perm.hasFamily()) family = perm.getFamily().toByteArray();
if (perm.hasQualifier()) qualifier = perm.getQualifier().toByteArray();
return Permission.newBuilder(table).withFamily(family).withQualifier(qualifier)
.withActions(actions).build();
}
throw new IllegalStateException("Unrecognize Perm Type: " + proto.getType());
}
/**
* Convert a client Permission to a Permission shaded proto
* @param perm the client Permission
* @return the protobuf Permission
*/
public static AccessControlProtos.Permission toPermission(Permission perm) {
AccessControlProtos.Permission.Builder ret = AccessControlProtos.Permission.newBuilder();
if (perm instanceof NamespacePermission) {
NamespacePermission nsPerm = (NamespacePermission) perm;
ret.setType(AccessControlProtos.Permission.Type.Namespace);
AccessControlProtos.NamespacePermission.Builder builder =
AccessControlProtos.NamespacePermission.newBuilder();
builder.setNamespaceName(org.apache.hbase.thirdparty.com.google.protobuf.ByteString
.copyFromUtf8(nsPerm.getNamespace()));
Permission.Action[] actions = perm.getActions();
if (actions != null) {
for (Permission.Action a : actions) {
builder.addAction(toPermissionAction(a));
}
}
ret.setNamespacePermission(builder);
} else if (perm instanceof TablePermission) {
TablePermission tablePerm = (TablePermission) perm;
ret.setType(AccessControlProtos.Permission.Type.Table);
AccessControlProtos.TablePermission.Builder builder =
AccessControlProtos.TablePermission.newBuilder();
builder.setTableName(toProtoTableName(tablePerm.getTableName()));
if (tablePerm.hasFamily()) {
builder.setFamily(ByteString.copyFrom(tablePerm.getFamily()));
}
if (tablePerm.hasQualifier()) {
builder.setQualifier(ByteString.copyFrom(tablePerm.getQualifier()));
}
Permission.Action[] actions = perm.getActions();
if (actions != null) {
for (Permission.Action a : actions) {
builder.addAction(toPermissionAction(a));
}
}
ret.setTablePermission(builder);
} else {
// perm.getAccessScope() == Permission.Scope.GLOBAL
ret.setType(AccessControlProtos.Permission.Type.Global);
AccessControlProtos.GlobalPermission.Builder builder =
AccessControlProtos.GlobalPermission.newBuilder();
Permission.Action[] actions = perm.getActions();
if (actions != null) {
for (Permission.Action a : actions) {
builder.addAction(toPermissionAction(a));
}
}
ret.setGlobalPermission(builder);
}
return ret.build();
}
/**
* Convert a shaded protobuf UserTablePermissions to a ListMultimap<String, TablePermission>
* where key is username.
* @param proto the protobuf UserPermission
* @return the converted UserPermission
*/
public static ListMultimap
toUserTablePermissions(AccessControlProtos.UsersAndPermissions proto) {
ListMultimap perms = ArrayListMultimap.create();
AccessControlProtos.UsersAndPermissions.UserPermissions userPerm;
for (int i = 0; i < proto.getUserPermissionsCount(); i++) {
userPerm = proto.getUserPermissions(i);
for (int j = 0; j < userPerm.getPermissionsCount(); j++) {
Permission perm = toPermission(userPerm.getPermissions(j));
perms.put(userPerm.getUser().toStringUtf8(), perm);
}
}
return perms;
}
/**
* Convert a ListMultimap<String, TablePermission> where key is username to a shaded
* protobuf UserPermission
* @param perm the list of user and table permissions
* @return the protobuf UserTablePermissions
*/
public static AccessControlProtos.UsersAndPermissions
toUserTablePermissions(ListMultimap perm) {
AccessControlProtos.UsersAndPermissions.Builder builder =
AccessControlProtos.UsersAndPermissions.newBuilder();
for (Map.Entry> entry : perm.asMap().entrySet()) {
AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder =
AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder();
userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey()));
for (UserPermission userPerm : entry.getValue()) {
userPermBuilder.addPermissions(toPermission(userPerm.getPermission()));
}
builder.addUserPermissions(userPermBuilder.build());
}
return builder.build();
}
/**
* Converts a user permission proto to a client user permission object.
* @param proto the protobuf UserPermission
* @return the converted UserPermission
*/
public static UserPermission toUserPermission(AccessControlProtos.UserPermission proto) {
return new UserPermission(proto.getUser().toStringUtf8(), toPermission(proto.getPermission()));
}
/**
* Convert a client user permission to a user permission proto
* @param perm the client UserPermission
* @return the protobuf UserPermission
*/
public static AccessControlProtos.UserPermission toUserPermission(UserPermission perm) {
return AccessControlProtos.UserPermission.newBuilder()
.setUser(ByteString.copyFromUtf8(perm.getUser()))
.setPermission(toPermission(perm.getPermission())).build();
}
public static GrantRequest buildGrantRequest(UserPermission userPermission,
boolean mergeExistingPermissions) {
return GrantRequest.newBuilder().setUserPermission(toUserPermission(userPermission))
.setMergeExistingPermissions(mergeExistingPermissions).build();
}
public static RevokeRequest buildRevokeRequest(UserPermission userPermission) {
return RevokeRequest.newBuilder().setUserPermission(toUserPermission(userPermission)).build();
}
public static AccessControlProtos.GetUserPermissionsRequest
buildGetUserPermissionsRequest(GetUserPermissionsRequest request) {
AccessControlProtos.GetUserPermissionsRequest.Builder builder =
AccessControlProtos.GetUserPermissionsRequest.newBuilder();
if (request.getUserName() != null && !request.getUserName().isEmpty()) {
builder.setUserName(ByteString.copyFromUtf8(request.getUserName()));
}
if (request.getNamespace() != null && !request.getNamespace().isEmpty()) {
builder.setNamespaceName(ByteString.copyFromUtf8(request.getNamespace()));
builder.setType(AccessControlProtos.Permission.Type.Namespace);
}
if (request.getTableName() != null) {
builder.setTableName(toProtoTableName(request.getTableName()));
builder.setType(AccessControlProtos.Permission.Type.Table);
}
if (!builder.hasType()) {
builder.setType(AccessControlProtos.Permission.Type.Global);
}
if (request.getFamily() != null && request.getFamily().length > 0) {
builder.setColumnFamily(ByteString.copyFrom(request.getFamily()));
}
if (request.getQualifier() != null && request.getQualifier().length > 0) {
builder.setColumnQualifier(ByteString.copyFrom(request.getQualifier()));
}
return builder.build();
}
public static GetUserPermissionsResponse
buildGetUserPermissionsResponse(final List permissions) {
GetUserPermissionsResponse.Builder builder = GetUserPermissionsResponse.newBuilder();
for (UserPermission perm : permissions) {
builder.addUserPermission(toUserPermission(perm));
}
return builder.build();
}
public static HasUserPermissionsRequest buildHasUserPermissionsRequest(String userName,
List permissions) {
HasUserPermissionsRequest.Builder builder = HasUserPermissionsRequest.newBuilder();
if (userName != null && !userName.isEmpty()) {
builder.setUserName(ByteString.copyFromUtf8(userName));
}
for (Permission permission : permissions) {
builder.addPermission(toPermission(permission));
}
return builder.build();
}
}