Skip to content

Commit

Permalink
USE_CATALOG,USE_SCHEMA
Browse files Browse the repository at this point in the history
  • Loading branch information
xunliu committed Oct 17, 2024
1 parent 18f13ec commit 38b6ffe
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 665 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@
import org.apache.gravitino.authorization.ranger.RangerPrivileges.RangerHivePrivilege;
import org.apache.gravitino.authorization.ranger.reference.RangerDefines.PolicyResource;
import org.apache.gravitino.exceptions.AuthorizationPluginException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RangerAuthorizationHivePlugin extends RangerAuthorizationPlugin {
private static final Logger LOG = LoggerFactory.getLogger(RangerAuthorizationHivePlugin.class);
private static volatile RangerAuthorizationHivePlugin instance = null;

private RangerAuthorizationHivePlugin(Map<String, String> config) {
Expand All @@ -61,8 +64,14 @@ public static synchronized RangerAuthorizationHivePlugin getInstance(Map<String,
/** Set the default mapping Gravitino privilege name to the Ranger rule */
public Map<Privilege.Name, Set<RangerPrivilege>> privilegesMappingRule() {
return ImmutableMap.of(
Privilege.Name.CREATE_CATALOG,
ImmutableSet.of(RangerHivePrivilege.CREATE),
Privilege.Name.USE_CATALOG,
ImmutableSet.of(RangerHivePrivilege.SELECT),
Privilege.Name.CREATE_SCHEMA,
ImmutableSet.of(RangerHivePrivilege.CREATE),
Privilege.Name.USE_SCHEMA,
ImmutableSet.of(RangerHivePrivilege.SELECT),
Privilege.Name.CREATE_TABLE,
ImmutableSet.of(RangerHivePrivilege.CREATE),
Privilege.Name.MODIFY_TABLE,
Expand Down Expand Up @@ -92,7 +101,9 @@ public List<String> policyResourceDefinesRule() {
public Set<Privilege.Name> allowPrivilegesRule() {
return ImmutableSet.of(
Privilege.Name.CREATE_CATALOG,
Privilege.Name.USE_CATALOG,
Privilege.Name.CREATE_SCHEMA,
Privilege.Name.USE_SCHEMA,
Privilege.Name.CREATE_TABLE,
Privilege.Name.MODIFY_TABLE,
Privilege.Name.SELECT_TABLE);
Expand Down Expand Up @@ -183,20 +194,42 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
securableObject.privileges().stream()
.filter(Objects::nonNull)
.forEach(
privilege -> {
gravitinoPrivilege -> {
Set<RangerPrivilege> rangerPrivileges = new HashSet<>();
privilegesMappingRule().get(privilege.name()).stream()
privilegesMappingRule().get(gravitinoPrivilege.name()).stream()
.forEach(
rangerPrivilege ->
rangerPrivileges.add(
new RangerPrivileges.RangerHivePrivilegeImpl(
rangerPrivilege, privilege.condition())));
rangerPrivilege, gravitinoPrivilege.condition())));

switch (privilege.name()) {
switch (gravitinoPrivilege.name()) {
case CREATE_CATALOG:
// Ignore the Gravitino privilege `CREATE_CATALOG` in the
// RangerAuthorizationHivePlugin
break;
case USE_CATALOG:
switch (securableObject.type()) {
case METALAKE:
case CATALOG:
// Add Ranger privilege(`SELECT`) to SCHEMA(`*`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
ImmutableList.of(RangerHelper.RESOURCE_STAR),
MetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
default:
throw new AuthorizationPluginException(
"The privilege %s is not supported for the securable object: %s",
gravitinoPrivilege.name(), securableObject.type());
}
break;
case CREATE_SCHEMA:
switch (securableObject.type()) {
case METALAKE:
case CATALOG:
// Add Ranger privilege(`CREATE`) to SCHEMA(`*`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
ImmutableList.of(RangerHelper.RESOURCE_STAR),
Expand All @@ -206,7 +239,32 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
default:
throw new AuthorizationPluginException(
"The privilege %s is not supported for the securable object: %s",
privilege.name(), securableObject.type());
gravitinoPrivilege.name(), securableObject.type());
}
break;
case USE_SCHEMA:
switch (securableObject.type()) {
case METALAKE:
case CATALOG:
// Add Ranger privilege(`SELECT`) to SCHEMA(`*`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
ImmutableList.of(RangerHelper.RESOURCE_STAR),
MetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
case SCHEMA:
// Add Ranger privilege(`SELECT`) to SCHEMA(`{schema}`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
ImmutableList.of(securableObject.name() /*Schema name*/),
MetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
default:
throw new AuthorizationPluginException(
"The privilege %s is not supported for the securable object: %s",
gravitinoPrivilege.name(), securableObject.type());
}
break;
case CREATE_TABLE:
Expand Down Expand Up @@ -252,10 +310,10 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
rangerPrivileges));
break;
case TABLE:
if (privilege.name() == Privilege.Name.CREATE_TABLE) {
if (gravitinoPrivilege.name() == Privilege.Name.CREATE_TABLE) {
throw new AuthorizationPluginException(
"The privilege %s is not supported for the securable object: %s",
privilege.name(), securableObject.type());
gravitinoPrivilege.name(), securableObject.type());
} else {
// Add `{schema}.{table}` for the TABLE permission
rangerSecurableObjects.add(
Expand All @@ -275,15 +333,17 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
}
break;
default:
throw new AuthorizationPluginException(
"The privilege %s is not supported for the securable object: %s",
privilege.name(), securableObject.type());
LOG.warn(
"RangerAuthorizationHivePlugin -> privilege {} is not supported for the securable object: {}",
gravitinoPrivilege.name(),
securableObject.type());
}
break;
default:
throw new AuthorizationPluginException(
"The privilege %s is not supported for the securable object: %s",
privilege.name(), securableObject.type());
LOG.warn(
"RangerAuthorizationHivePlugin -> privilege {} is not supported for the securable object: {}",
gravitinoPrivilege.name(),
securableObject.type());
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import org.apache.gravitino.MetadataObject;
import org.apache.gravitino.authorization.Group;
import org.apache.gravitino.authorization.Owner;
import org.apache.gravitino.authorization.Privilege;
import org.apache.gravitino.authorization.Role;
import org.apache.gravitino.authorization.RoleChange;
import org.apache.gravitino.authorization.SecurableObject;
Expand Down Expand Up @@ -75,7 +74,6 @@ public abstract class RangerAuthorizationPlugin
protected final RangerClientExtension rangerClient;
private final RangerHelper rangerHelper;
@VisibleForTesting public final String rangerAdminName;
private final Set<Privilege.Name> allowPrivileges;

protected RangerAuthorizationPlugin(Map<String, String> config) {
String rangerUrl = config.get(AuthorizationPropertiesMeta.RANGER_ADMIN_URL);
Expand All @@ -90,7 +88,7 @@ protected RangerAuthorizationPlugin(Map<String, String> config) {
Preconditions.checkArgument(password != null, "Ranger password is required");
Preconditions.checkArgument(rangerServiceName != null, "Ranger service name is required");
rangerClient = new RangerClientExtension(rangerUrl, authType, rangerAdminName, password);
allowPrivileges = allowPrivilegesRule();

rangerHelper =
new RangerHelper(
rangerClient,
Expand Down Expand Up @@ -664,31 +662,30 @@ public void close() throws IOException {}

public boolean validAuthorizationOperation(List<SecurableObject> securableObjects) {
return securableObjects.stream()
.allMatch(
.noneMatch(
securableObject -> {
AtomicBoolean match = new AtomicBoolean(false);
AtomicBoolean match = new AtomicBoolean(true);
securableObject.privileges().stream()
.filter(Objects::nonNull)
.forEach(
privilege -> {
if (!allowPrivileges.contains(privilege.name())) {
if (!allowPrivilegesRule().contains(privilege.name())) {
LOG.error(
"Authorization to ignore privilege({}) on metadata object({})!",
privilege.name(),
securableObject.fullName());
match.set(false);
return;
}

if (privilege.canBindTo(securableObject.type())) {
match.set(true);
} else {
if (!privilege.canBindTo(securableObject.type())) {
LOG.error(
"The privilege({}) is not supported for the metadata object({})!",
privilege.name(),
securableObject.fullName());
match.set(false);
}
});
return match.get();
return !match.get();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,20 @@ public void testValidAuthorizationOperation() {
Assertions.assertTrue(
rangerAuthPlugin.validAuthorizationOperation(Arrays.asList(createCatalog)));

// Ignore the use catalog operation
// Use catalog operation
SecurableObject useCatalogInMetalake =
SecurableObjects.parse(
String.format("metalake"),
MetadataObject.Type.METALAKE,
Lists.newArrayList(Privileges.UseCatalog.allow()));
Assertions.assertFalse(
Assertions.assertTrue(
rangerAuthPlugin.validAuthorizationOperation(Arrays.asList(useCatalogInMetalake)));
SecurableObject useCatalog =
SecurableObjects.parse(
String.format("catalog"),
MetadataObject.Type.CATALOG,
Lists.newArrayList(Privileges.UseCatalog.allow()));
Assertions.assertFalse(rangerAuthPlugin.validAuthorizationOperation(Arrays.asList(useCatalog)));
Assertions.assertTrue(rangerAuthPlugin.validAuthorizationOperation(Arrays.asList(useCatalog)));

// Create schema
SecurableObject createSchemaInMetalake =
Expand All @@ -200,13 +200,13 @@ public void testValidAuthorizationOperation() {
rangerAuthPlugin.validAuthorizationOperation(
Arrays.asList(createSchemaInMetalake, createSchemaInCatalog)));

// Ignore the use schema operation
// Use schema operation
SecurableObject useSchema =
SecurableObjects.parse(
String.format("catalog.schema"),
MetadataObject.Type.SCHEMA,
Lists.newArrayList(Privileges.UseSchema.allow()));
Assertions.assertFalse(rangerAuthPlugin.validAuthorizationOperation(Arrays.asList(useSchema)));
Assertions.assertTrue(rangerAuthPlugin.validAuthorizationOperation(Arrays.asList(useSchema)));

// Table
SecurableObject createTableInMetalake =
Expand Down
Loading

0 comments on commit 38b6ffe

Please sign in to comment.