HBASE-17472: Correct the semantic of permission grant

Signed-off-by: zhangduo <zhangduo@apache.org>
This commit is contained in:
huzheng 2017-01-25 15:20:42 +08:00 committed by zhangduo
parent d08bafad1a
commit 22fa1cd3df
11 changed files with 392 additions and 91 deletions

View File

@ -85,56 +85,104 @@ public class AccessControlClient {
* @param userName
* @param family
* @param qual
* @param mergeExistingPermissions If set to false, later granted permissions will override
* previous granted permissions. otherwise, it'll merge with previous granted
* permissions.
* @param actions
* @throws Throwable
*/
public static void grant(Connection connection, final TableName tableName,
final String userName, final byte[] family, final byte[] qual,
private static void grant(Connection connection, final TableName tableName,
final String userName, final byte[] family, final byte[] qual, boolean mergeExistingPermissions,
final Permission.Action... actions) throws Throwable {
/* TODO: Priority is not used.
HBaseRpcController controller
= ((ClusterConnection) connection).getRpcControllerFactory().newController();
controller.setPriority(tableName);
*/
// TODO: Priority is not used.
try (Table table = connection.getTable(ACL_TABLE_NAME)) {
AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName, tableName,
family, qual, actions);
family, qual, mergeExistingPermissions, actions);
}
}
/**
* Grants permission on the specified table for the specified user.
* If permissions for a specified user exists, later granted permissions will override previous granted permissions.
* @param connection The Connection instance to use
* @param tableName
* @param userName
* @param family
* @param qual
* @param actions
* @throws Throwable
*/
public static void grant(Connection connection, final TableName tableName, final String userName,
final byte[] family, final byte[] qual, final Permission.Action... actions) throws Throwable {
grant(connection, tableName, userName, family, qual, true, actions);
}
/**
* Grants permission on the specified namespace for the specified user.
* @param connection
* @param namespace
* @param userName
* @param mergeExistingPermissions If set to false, later granted permissions will override
* previous granted permissions. otherwise, it'll merge with previous granted
* permissions.
* @param actions
* @throws Throwable
*/
private static void grant(Connection connection, final String namespace, final String userName,
boolean mergeExistingPermissions, final Permission.Action... actions) throws Throwable {
// TODO: Pass an rpcController.
try (Table table = connection.getTable(ACL_TABLE_NAME)) {
AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName, namespace,
mergeExistingPermissions, actions);
}
}
/**
* Grants permission on the specified namespace for the specified user.
* If permissions on the specified namespace exists, later granted permissions will override previous granted
* permissions.
* @param connection The Connection instance to use
* @param namespace
* @param userName
* @param actions
* @throws Throwable
*/
public static void grant(Connection connection, final String namespace,
final String userName, final Permission.Action... actions) throws Throwable {
/* TODO: Pass an rpcController.
HBaseRpcController controller
= ((ClusterConnection) connection).getRpcControllerFactory().newController();
*/
public static void grant(Connection connection, final String namespace, final String userName,
final Permission.Action... actions) throws Throwable {
grant(connection, namespace, userName, true, actions);
}
/**
* Grants permission on the specified namespace for the specified user.
* @param connection
* @param userName
* @param mergeExistingPermissions If set to false, later granted permissions will override
* previous granted permissions. otherwise, it'll merge with previous granted
* permissions.
* @param actions
* @throws Throwable
*/
private static void grant(Connection connection, final String userName,
boolean mergeExistingPermissions, final Permission.Action... actions) throws Throwable {
// TODO: Pass an rpcController
try (Table table = connection.getTable(ACL_TABLE_NAME)) {
AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName, namespace,
actions);
AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName,
mergeExistingPermissions, actions);
}
}
/**
* @param connection The Connection instance to use
* Grant global permissions for the specified user.
* If permissions for the specified user exists, later granted permissions will override previous granted
* permissions.
* @param connection
* @param userName
* @param actions
* @throws Throwable
*/
public static void grant(Connection connection, final String userName,
final Permission.Action... actions) throws Throwable {
/* TODO: Pass an rpcController
HBaseRpcController controller
= ((ClusterConnection) connection).getRpcControllerFactory().newController();
*/
try (Table table = connection.getTable(ACL_TABLE_NAME)) {
AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName, actions);
}
final Permission.Action... actions) throws Throwable {
grant(connection, userName, true, actions);
}
public static boolean isAccessControllerRunning(Connection connection)

View File

@ -53,7 +53,7 @@ public class AccessControlUtil {
*/
public static AccessControlProtos.GrantRequest buildGrantRequest(
String username, TableName tableName, byte[] family, byte[] qualifier,
AccessControlProtos.Permission.Action... actions) {
boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) {
AccessControlProtos.Permission.Builder ret =
AccessControlProtos.Permission.newBuilder();
AccessControlProtos.TablePermission.Builder permissionBuilder =
@ -79,7 +79,7 @@ public class AccessControlUtil {
AccessControlProtos.UserPermission.newBuilder()
.setUser(ByteString.copyFromUtf8(username))
.setPermission(ret)
).build();
).setMergeExistingPermissions(mergeExistingPermissions).build();
}
/**
@ -91,7 +91,7 @@ public class AccessControlUtil {
* @return A {@link AccessControlProtos} GrantRequest
*/
public static AccessControlProtos.GrantRequest buildGrantRequest(
String username, String namespace,
String username, String namespace, boolean mergeExistingPermissions,
AccessControlProtos.Permission.Action... actions) {
AccessControlProtos.Permission.Builder ret =
AccessControlProtos.Permission.newBuilder();
@ -110,7 +110,7 @@ public class AccessControlUtil {
AccessControlProtos.UserPermission.newBuilder()
.setUser(ByteString.copyFromUtf8(username))
.setPermission(ret)
).build();
).setMergeExistingPermissions(mergeExistingPermissions).build();
}
/**
@ -177,8 +177,8 @@ public class AccessControlUtil {
* @param actions the permissions to be granted
* @return A {@link AccessControlProtos} GrantRequest
*/
public static AccessControlProtos.GrantRequest buildGrantRequest(
String username, AccessControlProtos.Permission.Action... actions) {
public static AccessControlProtos.GrantRequest buildGrantRequest(String username,
boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) {
AccessControlProtos.Permission.Builder ret =
AccessControlProtos.Permission.newBuilder();
AccessControlProtos.GlobalPermission.Builder permissionBuilder =
@ -193,7 +193,7 @@ public class AccessControlUtil {
AccessControlProtos.UserPermission.newBuilder()
.setUser(ByteString.copyFromUtf8(username))
.setPermission(ret)
).build();
).setMergeExistingPermissions(mergeExistingPermissions).build();
}
public static AccessControlProtos.UsersAndPermissions toUsersAndPermissions(String user,
@ -490,14 +490,14 @@ public class AccessControlUtil {
* @throws ServiceException
*/
public static void grant(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName,
AccessControlService.BlockingInterface protocol, String userShortName, boolean mergeExistingPermissions,
Permission.Action... actions) throws ServiceException {
List<AccessControlProtos.Permission.Action> permActions =
Lists.newArrayListWithCapacity(actions.length);
for (Permission.Action a : actions) {
permActions.add(toPermissionAction(a));
}
AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName,
AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, mergeExistingPermissions,
permActions.toArray(new AccessControlProtos.Permission.Action[actions.length]));
protocol.grant(controller, request);
}
@ -518,14 +518,16 @@ public class AccessControlUtil {
*/
public static void grant(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName,
byte[] f, byte[] q, Permission.Action... actions) throws ServiceException {
byte[] f, byte[] q, boolean mergeExistingPermissions, Permission.Action... actions)
throws ServiceException {
List<AccessControlProtos.Permission.Action> permActions =
Lists.newArrayListWithCapacity(actions.length);
for (Permission.Action a : actions) {
permActions.add(toPermissionAction(a));
}
AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, tableName, f, q,
permActions.toArray(new AccessControlProtos.Permission.Action[actions.length]));
AccessControlProtos.GrantRequest request =
buildGrantRequest(userShortName, tableName, f, q, mergeExistingPermissions,
permActions.toArray(new AccessControlProtos.Permission.Action[actions.length]));
protocol.grant(controller, request);
}
@ -541,13 +543,13 @@ public class AccessControlUtil {
*/
public static void grant(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, String namespace,
Permission.Action... actions) throws ServiceException {
boolean mergeExistingPermissions, Permission.Action... actions) throws ServiceException {
List<AccessControlProtos.Permission.Action> permActions =
Lists.newArrayListWithCapacity(actions.length);
for (Permission.Action a : actions) {
permActions.add(toPermissionAction(a));
}
AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, namespace,
AccessControlProtos.GrantRequest request = buildGrantRequest(userShortName, namespace, mergeExistingPermissions,
permActions.toArray(new AccessControlProtos.Permission.Action[actions.length]));
protocol.grant(controller, request);
}

View File

@ -305,6 +305,21 @@ public class TablePermission extends Permission {
return super.implies(action);
}
public boolean tableFieldsEqual(TablePermission other){
if (!(((table == null && other.getTableName() == null) ||
(table != null && table.equals(other.getTableName()))) &&
((family == null && other.getFamily() == null) ||
Bytes.equals(family, other.getFamily())) &&
((qualifier == null && other.getQualifier() == null) ||
Bytes.equals(qualifier, other.getQualifier())) &&
((namespace == null && other.getNamespace() == null) ||
(namespace != null && namespace.equals(other.getNamespace())))
)) {
return false;
}
return true;
}
@Override
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="NP_NULL_ON_SOME_PATH",
justification="Passed on construction except on constructor not to be used")
@ -314,15 +329,7 @@ public class TablePermission extends Permission {
}
TablePermission other = (TablePermission)obj;
if (!(((table == null && other.getTableName() == null) ||
(table != null && table.equals(other.getTableName()))) &&
((family == null && other.getFamily() == null) ||
Bytes.equals(family, other.getFamily())) &&
((qualifier == null && other.getQualifier() == null) ||
Bytes.equals(qualifier, other.getQualifier())) &&
((namespace == null && other.getNamespace() == null) ||
(namespace != null && namespace.equals(other.getNamespace())))
)) {
if(!this.tableFieldsEqual(other)){
return false;
}

View File

@ -5569,6 +5569,16 @@ public final class AccessControlProtos {
* <code>required .hbase.pb.UserPermission user_permission = 1;</code>
*/
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.UserPermissionOrBuilder getUserPermissionOrBuilder();
// optional bool merge_existing_permissions = 2 [default = false];
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
boolean hasMergeExistingPermissions();
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
boolean getMergeExistingPermissions();
}
/**
* Protobuf type {@code hbase.pb.GrantRequest}
@ -5634,6 +5644,11 @@ public final class AccessControlProtos {
bitField0_ |= 0x00000001;
break;
}
case 16: {
bitField0_ |= 0x00000002;
mergeExistingPermissions_ = input.readBool();
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
@ -5696,8 +5711,25 @@ public final class AccessControlProtos {
return userPermission_;
}
// optional bool merge_existing_permissions = 2 [default = false];
public static final int MERGE_EXISTING_PERMISSIONS_FIELD_NUMBER = 2;
private boolean mergeExistingPermissions_;
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
public boolean hasMergeExistingPermissions() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
public boolean getMergeExistingPermissions() {
return mergeExistingPermissions_;
}
private void initFields() {
userPermission_ = org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.UserPermission.getDefaultInstance();
mergeExistingPermissions_ = false;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@ -5722,6 +5754,9 @@ public final class AccessControlProtos {
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeMessage(1, userPermission_);
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBool(2, mergeExistingPermissions_);
}
getUnknownFields().writeTo(output);
}
@ -5735,6 +5770,10 @@ public final class AccessControlProtos {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(1, userPermission_);
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream
.computeBoolSize(2, mergeExistingPermissions_);
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@ -5763,6 +5802,11 @@ public final class AccessControlProtos {
result = result && getUserPermission()
.equals(other.getUserPermission());
}
result = result && (hasMergeExistingPermissions() == other.hasMergeExistingPermissions());
if (hasMergeExistingPermissions()) {
result = result && (getMergeExistingPermissions()
== other.getMergeExistingPermissions());
}
result = result &&
getUnknownFields().equals(other.getUnknownFields());
return result;
@ -5780,6 +5824,10 @@ public final class AccessControlProtos {
hash = (37 * hash) + USER_PERMISSION_FIELD_NUMBER;
hash = (53 * hash) + getUserPermission().hashCode();
}
if (hasMergeExistingPermissions()) {
hash = (37 * hash) + MERGE_EXISTING_PERMISSIONS_FIELD_NUMBER;
hash = (53 * hash) + hashBoolean(getMergeExistingPermissions());
}
hash = (29 * hash) + getUnknownFields().hashCode();
memoizedHashCode = hash;
return hash;
@ -5896,6 +5944,8 @@ public final class AccessControlProtos {
userPermissionBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000001);
mergeExistingPermissions_ = false;
bitField0_ = (bitField0_ & ~0x00000002);
return this;
}
@ -5932,6 +5982,10 @@ public final class AccessControlProtos {
} else {
result.userPermission_ = userPermissionBuilder_.build();
}
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
to_bitField0_ |= 0x00000002;
}
result.mergeExistingPermissions_ = mergeExistingPermissions_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@ -5951,6 +6005,9 @@ public final class AccessControlProtos {
if (other.hasUserPermission()) {
mergeUserPermission(other.getUserPermission());
}
if (other.hasMergeExistingPermissions()) {
setMergeExistingPermissions(other.getMergeExistingPermissions());
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@ -6103,6 +6160,39 @@ public final class AccessControlProtos {
return userPermissionBuilder_;
}
// optional bool merge_existing_permissions = 2 [default = false];
private boolean mergeExistingPermissions_ ;
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
public boolean hasMergeExistingPermissions() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
public boolean getMergeExistingPermissions() {
return mergeExistingPermissions_;
}
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
public Builder setMergeExistingPermissions(boolean value) {
bitField0_ |= 0x00000002;
mergeExistingPermissions_ = value;
onChanged();
return this;
}
/**
* <code>optional bool merge_existing_permissions = 2 [default = false];</code>
*/
public Builder clearMergeExistingPermissions() {
bitField0_ = (bitField0_ & ~0x00000002);
mergeExistingPermissions_ = false;
onChanged();
return this;
}
// @@protoc_insertion_point(builder_scope:hbase.pb.GrantRequest)
}
@ -10432,29 +10522,30 @@ public final class AccessControlProtos {
"\0132-.hbase.pb.UsersAndPermissions.UserPer" +
"missions\032J\n\017UserPermissions\022\014\n\004user\030\001 \002(" +
"\014\022)\n\013permissions\030\002 \003(\0132\024.hbase.pb.Permis" +
"sion\"A\n\014GrantRequest\0221\n\017user_permission\030" +
"\001 \002(\0132\030.hbase.pb.UserPermission\"\017\n\rGrant" +
"Response\"B\n\rRevokeRequest\0221\n\017user_permis" +
"sion\030\001 \002(\0132\030.hbase.pb.UserPermission\"\020\n\016" +
"RevokeResponse\"\205\001\n\031GetUserPermissionsReq" +
"uest\022\'\n\004type\030\001 \001(\0162\031.hbase.pb.Permission" +
".Type\022\'\n\ntable_name\030\002 \001(\0132\023.hbase.pb.Tab",
"leName\022\026\n\016namespace_name\030\003 \001(\014\"O\n\032GetUse" +
"rPermissionsResponse\0221\n\017user_permission\030" +
"\001 \003(\0132\030.hbase.pb.UserPermission\"C\n\027Check" +
"PermissionsRequest\022(\n\npermission\030\001 \003(\0132\024" +
".hbase.pb.Permission\"\032\n\030CheckPermissions" +
"Response2\311\002\n\024AccessControlService\0228\n\005Gra" +
"nt\022\026.hbase.pb.GrantRequest\032\027.hbase.pb.Gr" +
"antResponse\022;\n\006Revoke\022\027.hbase.pb.RevokeR" +
"equest\032\030.hbase.pb.RevokeResponse\022_\n\022GetU" +
"serPermissions\022#.hbase.pb.GetUserPermiss",
"ionsRequest\032$.hbase.pb.GetUserPermission" +
"sResponse\022Y\n\020CheckPermissions\022!.hbase.pb" +
".CheckPermissionsRequest\032\".hbase.pb.Chec" +
"kPermissionsResponseBI\n*org.apache.hadoo" +
"p.hbase.protobuf.generatedB\023AccessContro" +
"lProtosH\001\210\001\001\240\001\001"
"sion\"l\n\014GrantRequest\0221\n\017user_permission\030" +
"\001 \002(\0132\030.hbase.pb.UserPermission\022)\n\032merge" +
"_existing_permissions\030\002 \001(\010:\005false\"\017\n\rGr" +
"antResponse\"B\n\rRevokeRequest\0221\n\017user_per" +
"mission\030\001 \002(\0132\030.hbase.pb.UserPermission\"" +
"\020\n\016RevokeResponse\"\205\001\n\031GetUserPermissions" +
"Request\022\'\n\004type\030\001 \001(\0162\031.hbase.pb.Permiss",
"ion.Type\022\'\n\ntable_name\030\002 \001(\0132\023.hbase.pb." +
"TableName\022\026\n\016namespace_name\030\003 \001(\014\"O\n\032Get" +
"UserPermissionsResponse\0221\n\017user_permissi" +
"on\030\001 \003(\0132\030.hbase.pb.UserPermission\"C\n\027Ch" +
"eckPermissionsRequest\022(\n\npermission\030\001 \003(" +
"\0132\024.hbase.pb.Permission\"\032\n\030CheckPermissi" +
"onsResponse2\311\002\n\024AccessControlService\0228\n\005" +
"Grant\022\026.hbase.pb.GrantRequest\032\027.hbase.pb" +
".GrantResponse\022;\n\006Revoke\022\027.hbase.pb.Revo" +
"keRequest\032\030.hbase.pb.RevokeResponse\022_\n\022G",
"etUserPermissions\022#.hbase.pb.GetUserPerm" +
"issionsRequest\032$.hbase.pb.GetUserPermiss" +
"ionsResponse\022Y\n\020CheckPermissions\022!.hbase" +
".pb.CheckPermissionsRequest\032\".hbase.pb.C" +
"heckPermissionsResponseBI\n*org.apache.ha" +
"doop.hbase.protobuf.generatedB\023AccessCon" +
"trolProtosH\001\210\001\001\240\001\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@ -10508,7 +10599,7 @@ public final class AccessControlProtos {
internal_static_hbase_pb_GrantRequest_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_hbase_pb_GrantRequest_descriptor,
new java.lang.String[] { "UserPermission", });
new java.lang.String[] { "UserPermission", "MergeExistingPermissions", });
internal_static_hbase_pb_GrantResponse_descriptor =
getDescriptor().getMessageTypes().get(7);
internal_static_hbase_pb_GrantResponse_fieldAccessorTable = new

View File

@ -79,6 +79,7 @@ message UsersAndPermissions {
message GrantRequest {
required UserPermission user_permission = 1;
optional bool merge_existing_permissions = 2 [default = false];
}
message GrantResponse {

View File

@ -150,8 +150,8 @@ public class AccessControlLists {
* @param t acl table instance. It is closed upon method return.
* @throws IOException in the case of an error accessing the metadata table
*/
static void addUserPermission(Configuration conf, UserPermission userPerm, Table t)
throws IOException {
static void addUserPermission(Configuration conf, UserPermission userPerm, Table t,
boolean mergeExistingPermissions) throws IOException {
Permission.Action[] actions = userPerm.getActions();
byte[] rowKey = userPermissionRowKey(userPerm);
Put p = new Put(rowKey);
@ -163,10 +163,34 @@ public class AccessControlLists {
throw new IOException(msg);
}
byte[] value = new byte[actions.length];
for (int i = 0; i < actions.length; i++) {
value[i] = actions[i].code();
Set<Permission.Action> actionSet = new TreeSet<Permission.Action>();
if(mergeExistingPermissions){
List<UserPermission> perms = getUserPermissions(conf, rowKey);
UserPermission currentPerm = null;
for (UserPermission perm : perms) {
if (Bytes.equals(perm.getUser(), userPerm.getUser())
&& ((userPerm.isGlobal() && ACL_TABLE_NAME.equals(perm.getTableName()))
|| perm.tableFieldsEqual(userPerm))) {
currentPerm = perm;
break;
}
}
if(currentPerm != null && currentPerm.getActions() != null){
actionSet.addAll(Arrays.asList(currentPerm.getActions()));
}
}
// merge current action with new action.
actionSet.addAll(Arrays.asList(actions));
// serialize to byte array.
byte[] value = new byte[actionSet.size()];
int index = 0;
for (Permission.Action action : actionSet) {
value[index++] = action.code();
}
p.addImmutable(ACL_LIST_FAMILY, key, value);
if (LOG.isDebugEnabled()) {
LOG.debug("Writing permission with rowKey "+
@ -181,6 +205,11 @@ public class AccessControlLists {
}
}
static void addUserPermission(Configuration conf, UserPermission userPerm, Table t)
throws IOException{
addUserPermission(conf, userPerm, t, false);
}
/**
* Removes a previously granted permission from the stored access control
* lists. The {@link TablePermission} being removed must exactly match what

View File

@ -2246,7 +2246,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public Void run() throws Exception {
AccessControlLists.addUserPermission(regionEnv.getConfiguration(), perm,
regionEnv.getTable(AccessControlLists.ACL_TABLE_NAME));
regionEnv.getTable(AccessControlLists.ACL_TABLE_NAME), request.getMergeExistingPermissions());
return null;
}
});

View File

@ -371,7 +371,7 @@ public class SecureTestUtil {
BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
AccessControlService.BlockingInterface protocol =
AccessControlService.newBlockingStub(service);
AccessControlUtil.grant(null, protocol, user, actions);
AccessControlUtil.grant(null, protocol, user, false, actions);
}
}
return null;
@ -417,7 +417,7 @@ public class SecureTestUtil {
BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
AccessControlService.BlockingInterface protocol =
AccessControlService.newBlockingStub(service);
AccessControlUtil.grant(null, protocol, user, namespace, actions);
AccessControlUtil.grant(null, protocol, user, namespace, false, actions);
}
}
return null;
@ -439,7 +439,7 @@ public class SecureTestUtil {
try {
AccessControlClient.grant(connection, namespace, user, actions);
} catch (Throwable t) {
t.printStackTrace();
LOG.error("grant failed: ", t);
}
return null;
}
@ -460,7 +460,7 @@ public class SecureTestUtil {
try {
AccessControlClient.revoke(connection, namespace, user, actions);
} catch (Throwable t) {
t.printStackTrace();
LOG.error("revoke failed: ", t);
}
return null;
}
@ -506,7 +506,7 @@ public class SecureTestUtil {
BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
AccessControlService.BlockingInterface protocol =
AccessControlService.newBlockingStub(service);
AccessControlUtil.grant(null, protocol, user, table, family, qualifier, actions);
AccessControlUtil.grant(null, protocol, user, table, family, qualifier, false, actions);
}
}
return null;
@ -528,7 +528,7 @@ public class SecureTestUtil {
try {
AccessControlClient.grant(connection, table, user, family, qualifier, actions);
} catch (Throwable t) {
t.printStackTrace();
LOG.error("grant failed: ", t);
}
return null;
}
@ -549,7 +549,7 @@ public class SecureTestUtil {
try {
AccessControlClient.grant(connection, user, actions);
} catch (Throwable t) {
t.printStackTrace();
LOG.error("grant failed: ", t);
}
return null;
}
@ -594,7 +594,7 @@ public class SecureTestUtil {
try {
AccessControlClient.revoke(connection, table, user, family, qualifier, actions);
} catch (Throwable t) {
t.printStackTrace();
LOG.error("revoke failed: ", t);
}
return null;
}
@ -615,7 +615,7 @@ public class SecureTestUtil {
try {
AccessControlClient.revoke(connection, user, actions);
} catch (Throwable t) {
t.printStackTrace();
LOG.error("revoke failed: ", t);
}
return null;
}

View File

@ -1191,7 +1191,7 @@ public class TestAccessController extends SecureTestUtil {
AccessControlService.BlockingInterface protocol =
AccessControlService.newBlockingStub(service);
AccessControlUtil.grant(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY,
null, Action.READ);
null, false, Action.READ);
}
return null;
}
@ -2404,6 +2404,129 @@ public class TestAccessController extends SecureTestUtil {
}
}
@Test(timeout = 180000)
public void testAccessControlClientMultiGrantRevoke() throws Exception {
User testGrantRevoke =
User.createUserForTesting(conf, "testGrantRevoke", new String[0]);
AccessTestAction getAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
try(Connection conn = ConnectionFactory.createConnection(conf);
Table t = conn.getTable(TEST_TABLE)) {
return t.get(new Get(TEST_ROW));
}
}
};
AccessTestAction putAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
Put p = new Put(TEST_ROW);
p.addColumn(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(1));
try(Connection conn = ConnectionFactory.createConnection(conf);
Table t = conn.getTable(TEST_TABLE)) {
t.put(p);
return null;
}
}
};
verifyDenied(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
// Grant global READ permissions to testGrantRevoke.
String userName = testGrantRevoke.getShortName();
try {
grantGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName,
Permission.Action.READ);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.grant. ", e);
}
verifyAllowed(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
// Grant global READ permissions to testGrantRevoke.
try {
grantGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName,
Permission.Action.WRITE);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.grant. ", e);
}
verifyAllowed(getAction, testGrantRevoke);
verifyAllowed(putAction, testGrantRevoke);
// Revoke global READ permission to testGrantRevoke.
try {
revokeGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName,
Permission.Action.READ, Permission.Action.WRITE);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.revoke ", e);
}
verifyDenied(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
// Grant table READ & WRITE permissions to testGrantRevoke
try {
grantOnTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, TEST_TABLE,
null, null, Permission.Action.READ);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.grant. ", e);
}
verifyAllowed(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
// Grant table WRITE permissions to testGrantRevoke
try {
grantOnTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, TEST_TABLE,
null, null, Action.WRITE);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.grant. ", e);
}
verifyAllowed(getAction, testGrantRevoke);
verifyAllowed(putAction, testGrantRevoke);
// Revoke table READ & WRITE permission to testGrantRevoke.
try {
revokeFromTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, TEST_TABLE, null, null,
Permission.Action.READ, Permission.Action.WRITE);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.revoke ", e);
}
verifyDenied(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
// Grant Namespace READ permissions to testGrantRevoke
String namespace = TEST_TABLE.getNamespaceAsString();
try {
grantOnNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName,
namespace, Permission.Action.READ);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.grant. ", e);
}
verifyAllowed(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
// Grant Namespace WRITE permissions to testGrantRevoke
try {
grantOnNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName,
namespace, Permission.Action.WRITE);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.grant. ", e);
}
verifyAllowed(getAction, testGrantRevoke);
verifyAllowed(putAction, testGrantRevoke);
// Revoke table READ & WRITE permission to testGrantRevoke.
try {
revokeFromNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName,
TEST_TABLE.getNamespaceAsString(), Permission.Action.READ, Permission.Action.WRITE);
} catch (Throwable e) {
LOG.error("error during call of AccessControlClient.revoke ", e);
}
verifyDenied(getAction, testGrantRevoke);
verifyDenied(putAction, testGrantRevoke);
}
@Test (timeout=180000)
public void testAccessControlClientGrantRevokeOnNamespace() throws Exception {
// Create user for testing, who has no READ privileges by default.

View File

@ -359,7 +359,7 @@ public class TestNamespaceCommands extends SecureTestUtil {
acl.coprocessorService(HConstants.EMPTY_START_ROW);
AccessControlService.BlockingInterface protocol =
AccessControlService.newBlockingStub(service);
AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
} finally {
acl.close();
connection.close();
@ -377,7 +377,7 @@ public class TestNamespaceCommands extends SecureTestUtil {
AccessControlService.BlockingInterface protocol =
AccessControlService.newBlockingStub(service);
AccessControlUtil.grant(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
TEST_NAMESPACE, Action.READ);
TEST_NAMESPACE, false, Action.READ);
}
return null;
}

View File

@ -458,7 +458,7 @@ public class TestTablePermissions {
assertEquals("Should have 1 permission for user3", 1, user3Perms.size());
assertEquals("user3 should have ADMIN, READ, CREATE permission",
new Permission.Action[] {
Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.CREATE
Permission.Action.READ, Permission.Action.CREATE, Permission.Action.ADMIN
},
user3Perms.get(0).getActions());
}