Skip to content

Commit

Permalink
[#5665] refactor(auth): Underlying datasource authorization privilege…
Browse files Browse the repository at this point in the history
… abstraction (#5674)

### What changes were proposed in this pull request?

1. abstract AuthorizationMetadataObject interface
2. abstract AuthorizationPrivilege interface
3. abstract AuthorizationSecurableObject interface
4. abstract AuthorizationPrivilegesMappingProvider interface

### Why are the changes needed?

Fix: #5665

### Does this PR introduce _any_ user-facing change?

N/A

### How was this patch tested?

CI Passed.
  • Loading branch information
xunliu authored Nov 27, 2024
1 parent 93b623b commit b953226
Show file tree
Hide file tree
Showing 16 changed files with 575 additions and 572 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.gravitino.authorization.AuthorizationMetadataObject;
import org.apache.gravitino.authorization.AuthorizationPrivilege;
import org.apache.gravitino.authorization.AuthorizationSecurableObject;
import org.apache.gravitino.authorization.Owner;
import org.apache.gravitino.authorization.Privilege;
import org.apache.gravitino.exceptions.AuthorizationPluginException;
Expand All @@ -49,7 +52,7 @@ public class RangerHelper {
/** The `*` gives access to all resources */
public static final String RESOURCE_ALL = "*";
/** The owner privileges, the owner can do anything on the metadata object */
private final Set<RangerPrivilege> ownerPrivileges;
private final Set<AuthorizationPrivilege> ownerPrivileges;
/** The policy search keys */
protected final List<String> policyResourceDefines;

Expand All @@ -69,7 +72,7 @@ public RangerHelper(
RangerClient rangerClient,
String rangerAdminName,
String rangerServiceName,
Set<RangerPrivilege> ownerPrivileges,
Set<AuthorizationPrivilege> ownerPrivileges,
List<String> resourceDefines) {
this.rangerClient = rangerClient;
this.rangerAdminName = rangerAdminName;
Expand Down Expand Up @@ -102,7 +105,8 @@ void checkPolicyItemAccess(RangerPolicy.RangerPolicyItem policyItem)
* We cannot clean the policy items because one Ranger policy maybe contains multiple Gravitino
* securable objects. <br>
*/
void addPolicyItem(RangerPolicy policy, String roleName, RangerSecurableObject securableObject) {
void addPolicyItem(
RangerPolicy policy, String roleName, AuthorizationSecurableObject securableObject) {
// Add the policy items by the securable object's privileges
securableObject
.privileges()
Expand Down Expand Up @@ -191,20 +195,20 @@ public List<RangerPolicy> wildcardSearchPolies(List<String> metadataNames)
/**
* Find the managed policy for the ranger securable object.
*
* @param rangerMetadataObject The ranger securable object to find the managed policy.
* @param AuthorizationMetadataObject The ranger securable object to find the managed policy.
* @return The managed policy for the metadata object.
*/
public RangerPolicy findManagedPolicy(RangerMetadataObject rangerMetadataObject)
public RangerPolicy findManagedPolicy(AuthorizationMetadataObject AuthorizationMetadataObject)
throws AuthorizationPluginException {
List<RangerPolicy> policies = wildcardSearchPolies(rangerMetadataObject.names());
List<RangerPolicy> policies = wildcardSearchPolies(AuthorizationMetadataObject.names());
if (!policies.isEmpty()) {
/**
* Because Ranger doesn't support the precise search, Ranger will return the policy meets the
* wildcard(*,?) conditions, If you use `db.table` condition to search policy, the Ranger will
* match `db1.table1`, `db1.table2`, `db*.table*`, So we need to manually precisely filter
* this research results.
*/
List<String> nsMetadataObj = rangerMetadataObject.names();
List<String> nsMetadataObj = AuthorizationMetadataObject.names();
Map<String, String> preciseFilters = new HashMap<>();
for (int i = 0; i < nsMetadataObj.size(); i++) {
preciseFilters.put(policyResourceDefines.get(i), nsMetadataObj.get(i));
Expand Down Expand Up @@ -438,7 +442,7 @@ protected void updatePolicyOwner(RangerPolicy policy, Owner preOwner, Owner newO
});
}

protected RangerPolicy createPolicyAddResources(RangerMetadataObject metadataObject) {
protected RangerPolicy createPolicyAddResources(AuthorizationMetadataObject metadataObject) {
RangerPolicy policy = new RangerPolicy();
policy.setService(rangerServiceName);
policy.setName(metadataObject.fullName());
Expand All @@ -451,7 +455,8 @@ protected RangerPolicy createPolicyAddResources(RangerMetadataObject metadataObj
return policy;
}

protected RangerPolicy addOwnerToNewPolicy(RangerMetadataObject metadataObject, Owner newOwner) {
protected RangerPolicy addOwnerToNewPolicy(
AuthorizationMetadataObject metadataObject, Owner newOwner) {
RangerPolicy policy = createPolicyAddResources(metadataObject);

ownerPrivileges.forEach(
Expand All @@ -476,7 +481,7 @@ protected RangerPolicy addOwnerToNewPolicy(RangerMetadataObject metadataObject,
}

protected RangerPolicy addOwnerRoleToNewPolicy(
RangerMetadataObject metadataObject, String ownerRoleName) {
AuthorizationMetadataObject metadataObject, String ownerRoleName) {
RangerPolicy policy = createPolicyAddResources(metadataObject);

ownerPrivileges.forEach(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.gravitino.authorization.ranger;

import com.google.common.base.Preconditions;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.gravitino.MetadataObject;
import org.apache.gravitino.annotation.Unstable;
import org.apache.gravitino.authorization.AuthorizationMetadataObject;

/**
* The Ranger MetadataObject is the basic unit of the Gravitino system. It represents the Apache
* Ranger metadata object in the Apache Gravitino system. The object can be a catalog, schema,
* table, column, etc.
*/
@Unstable
public interface RangerMetadataObject {
/** The helper class for {@link AuthorizationMetadataObject}. */
public class RangerMetadataObject implements AuthorizationMetadataObject {
/**
* The type of object in the Ranger system. Every type will map one kind of the entity of the
* Gravitino type system.
*/
enum Type {
public enum Type implements AuthorizationMetadataObject.Type {
/** A schema is a sub collection of the catalog. The schema can contain tables, columns, etc. */
SCHEMA(MetadataObject.Type.SCHEMA),
/** A table is mapped the table of relational data sources like Apache Hive, MySQL, etc. */
Expand All @@ -49,13 +43,13 @@ enum Type {
this.metadataType = type;
}

public MetadataObject.Type getMetadataType() {
public MetadataObject.Type metadataObjectType() {
return metadataType;
}

public static Type fromMetadataType(MetadataObject.Type metadataType) {
for (Type type : Type.values()) {
if (type.getMetadataType() == metadataType) {
if (type.metadataObjectType() == metadataType) {
return type;
}
}
Expand All @@ -64,47 +58,97 @@ public static Type fromMetadataType(MetadataObject.Type metadataType) {
}
}

/**
* The parent full name of the object. If the object doesn't have parent, this method will return
* null.
*
* @return The parent full name of the object.
*/
@Nullable
String parent();
/** The implementation of the {@link MetadataObject}. */
private final String name;

/**
* The name of the object.
*
* @return The name of the object.
*/
String name();
private final String parent;

/**
* The all name list of the object.
*
* @return The name list of the object.
*/
List<String> names();
private final AuthorizationMetadataObject.Type type;

/**
* The full name of the object. Full name will be separated by "." to represent a string
* identifier of the object, like catalog, catalog.table, etc.
* Create the metadata object with the given name, parent and type.
*
* @return The name of the object.
* @param parent The parent of the metadata object
* @param name The name of the metadata object
* @param type The type of the metadata object
*/
default String fullName() {
if (parent() == null) {
return name();
} else {
return parent() + "." + name();
public RangerMetadataObject(String parent, String name, AuthorizationMetadataObject.Type type) {
this.parent = parent;
this.name = name;
this.type = type;
}

@Override
public String name() {
return name;
}

@Override
public List<String> names() {
return DOT_SPLITTER.splitToList(fullName());
}

@Override
public String parent() {
return parent;
}

@Override
public AuthorizationMetadataObject.Type type() {
return type;
}

@Override
public void validateAuthorizationMetadataObject() throws IllegalArgumentException {
List<String> names = names();
Preconditions.checkArgument(
names != null && !names.isEmpty(), "Cannot create a Ranger metadata object with no names");
Preconditions.checkArgument(
names.size() <= 3,
"Cannot create a Ranger metadata object with the name length which is greater than 3");
Preconditions.checkArgument(
type != null, "Cannot create a Ranger metadata object with no type");

Preconditions.checkArgument(
names.size() != 1 || type == RangerMetadataObject.Type.SCHEMA,
"If the length of names is 1, it must be the SCHEMA type");

Preconditions.checkArgument(
names.size() != 2 || type == RangerMetadataObject.Type.TABLE,
"If the length of names is 2, it must be the TABLE type");

Preconditions.checkArgument(
names.size() != 3 || type == RangerMetadataObject.Type.COLUMN,
"If the length of names is 3, it must be COLUMN");

for (String name : names) {
Preconditions.checkArgument(name != null, "Cannot create a metadata object with null name");
}
}

/**
* The type of the object.
*
* @return The type of the object.
*/
Type type();
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (!(o instanceof RangerMetadataObject)) {
return false;
}

RangerMetadataObject that = (RangerMetadataObject) o;
return java.util.Objects.equals(name, that.name)
&& java.util.Objects.equals(parent, that.parent)
&& type == that.type;
}

@Override
public int hashCode() {
return java.util.Objects.hash(name, parent, type);
}

@Override
public String toString() {
return "MetadataObject: [fullName=" + fullName() + "], [type=" + type + "]";
}
}

This file was deleted.

Loading

0 comments on commit b953226

Please sign in to comment.