final byte[] family1 = Bytes.toBytes("f1");
final byte[] family2 = Bytes.toBytes("f2");
final byte[] qualifier = Bytes.toBytes("q");
// create table
HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
if (admin.tableExists(tableName)) {
admin.disableTable(tableName);
admin.deleteTable(tableName);
}
HTableDescriptor htd = new HTableDescriptor(tableName);
htd.addFamily(new HColumnDescriptor(family1));
htd.addFamily(new HColumnDescriptor(family2));
admin.createTable(htd);
// create temp users
User tblUser = User
.createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser", new String[0]);
User gblUser = User
.createUserForTesting(TEST_UTIL.getConfiguration(), "gbluser", new String[0]);
// prepare actions:
PrivilegedExceptionAction putActionAll = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Put p = new Put(Bytes.toBytes("a"));
p.add(family1, qualifier, Bytes.toBytes("v1"));
p.add(family2, qualifier, Bytes.toBytes("v2"));
HTable t = new HTable(conf, tableName);
try {
t.put(p);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction putAction1 = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Put p = new Put(Bytes.toBytes("a"));
p.add(family1, qualifier, Bytes.toBytes("v1"));
HTable t = new HTable(conf, tableName);
try {
t.put(p);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction putAction2 = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Put p = new Put(Bytes.toBytes("a"));
p.add(family2, qualifier, Bytes.toBytes("v2"));
HTable t = new HTable(conf, tableName);
try {
t.put(p);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction getActionAll = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Get g = new Get(Bytes.toBytes("random_row"));
g.addFamily(family1);
g.addFamily(family2);
HTable t = new HTable(conf, tableName);
try {
t.get(g);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction getAction1 = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Get g = new Get(Bytes.toBytes("random_row"));
g.addFamily(family1);
HTable t = new HTable(conf, tableName);
try {
t.get(g);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction getAction2 = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Get g = new Get(Bytes.toBytes("random_row"));
g.addFamily(family2);
HTable t = new HTable(conf, tableName);
try {
t.get(g);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction deleteActionAll = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Delete d = new Delete(Bytes.toBytes("random_row"));
d.deleteFamily(family1);
d.deleteFamily(family2);
HTable t = new HTable(conf, tableName);
try {
t.delete(d);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction deleteAction1 = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Delete d = new Delete(Bytes.toBytes("random_row"));
d.deleteFamily(family1);
HTable t = new HTable(conf, tableName);
try {
t.delete(d);
} finally {
t.close();
}
return null;
}
};
PrivilegedExceptionAction deleteAction2 = new PrivilegedExceptionAction() {
public Object run() throws Exception {
Delete d = new Delete(Bytes.toBytes("random_row"));
d.deleteFamily(family2);
HTable t = new HTable(conf, tableName);
try {
t.delete(d);
} finally {
t.close();
}
return null;
}
};
// initial check:
verifyDenied(tblUser, getActionAll, getAction1, getAction2);
verifyDenied(tblUser, putActionAll, putAction1, putAction2);
verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
verifyDenied(gblUser, getActionAll, getAction1, getAction2);
verifyDenied(gblUser, putActionAll, putAction1, putAction2);
verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// grant table read permission
HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
try {
AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class,
tableName);
protocol.grant(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, null,
Permission.Action.READ));
protocol.grant(new UserPermission(Bytes.toBytes(gblUser.getShortName()),
Permission.Action.READ));
} finally {
acl.close();
}
Thread.sleep(100);
// check
verifyAllowed(tblUser, getActionAll, getAction1, getAction2);
verifyDenied(tblUser, putActionAll, putAction1, putAction2);
verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
verifyAllowed(gblUser, getActionAll, getAction1, getAction2);
verifyDenied(gblUser, putActionAll, putAction1, putAction2);
verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// grant table write permission
acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
try {
AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class,
tableName);
protocol.grant(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, null,
Permission.Action.WRITE));
protocol.grant(new UserPermission(Bytes.toBytes(gblUser.getShortName()),
Permission.Action.WRITE));
} finally {
acl.close();
}
Thread.sleep(100);
verifyDenied(tblUser, getActionAll, getAction1, getAction2);
verifyAllowed(tblUser, putActionAll, putAction1, putAction2);
verifyAllowed(tblUser, deleteActionAll, deleteAction1, deleteAction2);
verifyDenied(gblUser, getActionAll, getAction1, getAction2);
verifyAllowed(gblUser, putActionAll, putAction1, putAction2);
verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// revoke table permission
acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
try {
AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class,
tableName);
protocol.grant(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, null,
Permission.Action.READ, Permission.Action.WRITE));
protocol.revoke(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, null));
protocol.revoke(new UserPermission(Bytes.toBytes(gblUser.getShortName())));
} finally {
acl.close();
}
Thread.sleep(100);
verifyDenied(tblUser, getActionAll, getAction1, getAction2);
verifyDenied(tblUser, putActionAll, putAction1, putAction2);
verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
verifyDenied(gblUser, getActionAll, getAction1, getAction2);
verifyDenied(gblUser, putActionAll, putAction1, putAction2);
verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// grant column family read permission
acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
try {
AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class,
tableName);
protocol.grant(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, family1,
Permission.Action.READ));
protocol.grant(new UserPermission(Bytes.toBytes(gblUser.getShortName()),
Permission.Action.READ));
} finally {
acl.close();
}
Thread.sleep(100);
// Access should be denied for family2
verifyAllowed(tblUser, getActionAll, getAction1);
verifyDenied(tblUser, getAction2);
verifyDenied(tblUser, putActionAll, putAction1, putAction2);
verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
verifyAllowed(gblUser, getActionAll, getAction1, getAction2);
verifyDenied(gblUser, putActionAll, putAction1, putAction2);
verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// grant column family write permission
acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
try {
AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class,
tableName);
protocol.grant(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, family2,
Permission.Action.WRITE));
protocol.grant(new UserPermission(Bytes.toBytes(gblUser.getShortName()),
Permission.Action.WRITE));
} finally {
acl.close();
}
Thread.sleep(100);
// READ from family1, WRITE to family2 are allowed
verifyAllowed(tblUser, getActionAll, getAction1);
verifyAllowed(tblUser, putAction2, deleteAction2);
verifyDenied(tblUser, getAction2);
verifyDenied(tblUser, putActionAll, putAction1);
verifyDenied(tblUser, deleteActionAll, deleteAction1);
verifyDenied(gblUser, getActionAll, getAction1, getAction2);
verifyAllowed(gblUser, putActionAll, putAction1, putAction2);
verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// revoke column family permission
acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
try {
AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class,
tableName);
protocol.revoke(new UserPermission(Bytes.toBytes(tblUser.getShortName()), tableName, family2));
protocol.revoke(new UserPermission(Bytes.toBytes(gblUser.getShortName())));
} finally {
acl.close();
}
Thread.sleep(100);
// Revoke on family2 should not have impact on family1 permissions
verifyAllowed(tblUser, getActionAll, getAction1);
verifyDenied(tblUser, getAction2);
verifyDenied(tblUser, putActionAll, putAction1, putAction2);
verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
// Should not have access as global permissions are completely revoked
verifyDenied(gblUser, getActionAll, getAction1, getAction2);
verifyDenied(gblUser, putActionAll, putAction1, putAction2);
verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
// delete table
admin.disableTable(tableName);
admin.deleteTable(tableName);
}