Skip to content

Commit

Permalink
[#5124] feat(auth-ranger): Ranger plugin should support rename operation
Browse files Browse the repository at this point in the history
  • Loading branch information
xunliu committed Oct 23, 2024
1 parent 436d256 commit a248f11
Show file tree
Hide file tree
Showing 10 changed files with 600 additions and 132 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* 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.gravitino.authorization;

import com.google.common.base.Preconditions;
import java.util.Objects;
import org.apache.gravitino.MetadataObject;
import org.apache.gravitino.annotation.Evolving;

/** The RoleChange interface defines the public API for managing roles in an authorization. */
@Evolving
public interface MetadataObjectChange {
/**
* Update a metadata entity RoleChange.
*
* @param metadataObject The metadata object.
* @param newMetadataObject The new metadata object.
* @return return a RoleChange for the rename metadata object.
*/
static MetadataObjectChange rename(
MetadataObject metadataObject, MetadataObject newMetadataObject) {
return new RenameMetadataObject(metadataObject, newMetadataObject);
}

/** A RenameMetadataObject is to rename securable object's metadata entity. <br> */
final class RenameMetadataObject implements MetadataObjectChange {
private final MetadataObject metadataObject;
private final MetadataObject newMetadataObject;

private RenameMetadataObject(MetadataObject metadataObject, MetadataObject newMetadataObject) {
Preconditions.checkArgument(
!metadataObject.fullName().equals(newMetadataObject.fullName()),
"The metadata object must be different!");
Preconditions.checkArgument(
metadataObject.type().equals(newMetadataObject.type()),
"The metadata object type must be same!");

this.metadataObject = metadataObject;
this.newMetadataObject = newMetadataObject;
}

/**
* Returns the metadataObject to be renamed.
*
* @return return a metadataObject.
*/
public MetadataObject getMetadataObject() {
return this.metadataObject;
}

/**
* Returns the new metadataObject object.
*
* @return return a metadataObject object.
*/
public MetadataObject getNewMetadataObject() {
return this.newMetadataObject;
}

/**
* Compares this RenameMetadataObject instance with another object for equality. The comparison
* is based on the old metadata entity and new metadata entity.
*
* @param o The object to compare with this instance.
* @return true if the given object represents the same rename metadata entity; false otherwise.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RenameMetadataObject that = (RenameMetadataObject) o;
return metadataObject.equals(that.metadataObject)
&& newMetadataObject.equals(that.newMetadataObject);
}

/**
* Generates a hash code for this RenameMetadataObject instance. The hash code is based on the
* old metadata entity and new metadata entity.
*
* @return A hash code value for this update metadata entity operation.
*/
@Override
public int hashCode() {
return Objects.hash(metadataObject, newMetadataObject);
}

/**
* Returns a string representation of the RenameMetadataObject instance. This string format
* includes the class name followed by the update metadata entity object operation.
*
* @return A string representation of the RenameMetadataObject instance.
*/
@Override
public String toString() {
return "RENAMEMETADATAOBJECT " + metadataObject + " " + newMetadataObject;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public Set<Privilege.Name> allowPrivilegesRule() {
}

/** Translate the Gravitino securable object to the Ranger owner securable object. */
@Override
public List<RangerSecurableObject> translateOwner(MetadataObject gravitinoMetadataObject) {
List<RangerSecurableObject> rangerSecurableObjects = new ArrayList<>();

Expand Down Expand Up @@ -197,14 +198,14 @@ public List<RangerSecurableObject> translateOwner(MetadataObject gravitinoMetada
// Add `{schema}.{table}` for the TABLE permission
rangerSecurableObjects.add(
generateRangerSecurableObject(
convertToRangerMetadataObject(gravitinoMetadataObject),
translateMetadataObject(gravitinoMetadataObject).names(),
RangerMetadataObject.Type.TABLE,
ownerMappingRule()));
// Add `{schema}.{table}.*` for the COLUMN permission
rangerSecurableObjects.add(
generateRangerSecurableObject(
Stream.concat(
convertToRangerMetadataObject(gravitinoMetadataObject).stream(),
translateMetadataObject(gravitinoMetadataObject).names().stream(),
Stream.of(RangerHelper.RESOURCE_ALL))
.collect(Collectors.toList()),
RangerMetadataObject.Type.COLUMN,
Expand All @@ -220,6 +221,7 @@ public List<RangerSecurableObject> translateOwner(MetadataObject gravitinoMetada
}

/** Translate the Gravitino securable object to the Ranger securable object. */
@Override
public List<RangerSecurableObject> translatePrivilege(SecurableObject securableObject) {
List<RangerSecurableObject> rangerSecurableObjects = new ArrayList<>();

Expand Down Expand Up @@ -350,14 +352,14 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
// Add `{schema}.{table}` for the TABLE permission
rangerSecurableObjects.add(
generateRangerSecurableObject(
convertToRangerMetadataObject(securableObject),
translateMetadataObject(securableObject).names(),
RangerMetadataObject.Type.TABLE,
rangerPrivileges));
// Add `{schema}.{table}.*` for the COLUMN permission
rangerSecurableObjects.add(
generateRangerSecurableObject(
Stream.concat(
convertToRangerMetadataObject(securableObject).stream(),
translateMetadataObject(securableObject).names().stream(),
Stream.of(RangerHelper.RESOURCE_ALL))
.collect(Collectors.toList()),
RangerMetadataObject.Type.COLUMN,
Expand All @@ -383,16 +385,26 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
}

/**
* Because the Ranger securable object is different from the Gravitino securable object, we need
* to convert the Gravitino securable object to the Ranger securable object.
* Because the Ranger metadata object is different from the Gravitino metadata object, we need to
* convert the Gravitino metadata object to the Ranger metadata object.
*/
List<String> convertToRangerMetadataObject(MetadataObject metadataObject) {
@Override
public RangerMetadataObject translateMetadataObject(MetadataObject metadataObject) {
Preconditions.checkArgument(
!(metadataObject instanceof RangerPrivileges),
"The metadata object must be not a RangerPrivileges object.");
List<String> nsMetadataObject =
Lists.newArrayList(SecurableObjects.DOT_SPLITTER.splitToList(metadataObject.fullName()));
Preconditions.checkArgument(
nsMetadataObject.size() > 0, "The metadata object must have at least one name.");
nsMetadataObject.remove(0); // remove the catalog name
return nsMetadataObject;

RangerMetadataObject.Type type =
RangerMetadataObject.Type.fromMetadataType(metadataObject.type());
validateRangerMetadataObject(nsMetadataObject, type);
return new RangerMetadataObjects.RangerMetadataObjectImpl(
RangerMetadataObjects.getParentFullName(nsMetadataObject),
RangerMetadataObjects.getLastName(nsMetadataObject),
type);
}
}
Loading

0 comments on commit a248f11

Please sign in to comment.