-
Notifications
You must be signed in to change notification settings - Fork 387
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into iceberg-load-properties
- Loading branch information
Showing
77 changed files
with
2,521 additions
and
420 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
api/src/main/java/com/datastrato/gravitino/authorization/Privilege.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright 2024 Datastrato Pvt Ltd. | ||
* This software is licensed under the Apache License version 2. | ||
*/ | ||
package com.datastrato.gravitino.authorization; | ||
|
||
import com.datastrato.gravitino.annotation.Evolving; | ||
|
||
/** | ||
* The interface of a privilege. The privilege represents the ability to execute kinds of operations | ||
* for kinds of entities | ||
*/ | ||
@Evolving | ||
public interface Privilege { | ||
|
||
/** @return The generic name of the privilege. */ | ||
Name name(); | ||
|
||
/** @return A readable string representation for the privilege. */ | ||
String simpleString(); | ||
|
||
/** The name of this privilege. */ | ||
enum Name { | ||
/** The privilege of load a catalog. */ | ||
LOAD_CATALOG | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
api/src/main/java/com/datastrato/gravitino/authorization/Privileges.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* Copyright 2024 Datastrato Pvt Ltd. | ||
* This software is licensed under the Apache License version 2. | ||
*/ | ||
package com.datastrato.gravitino.authorization; | ||
|
||
/** The helper class for {@link Privilege}. */ | ||
public class Privileges { | ||
|
||
/** | ||
* Returns the Privilege from the string representation. | ||
* | ||
* @param privilege The string representation of the privilege. | ||
* @return The Privilege. | ||
*/ | ||
public static Privilege fromString(String privilege) { | ||
Privilege.Name name = Privilege.Name.valueOf(privilege); | ||
return fromName(name); | ||
} | ||
|
||
/** | ||
* Returns the Privilege from the `Privilege.Name`. | ||
* | ||
* @param name The `Privilege.Name` of the privilege. | ||
* @return The Privilege. | ||
*/ | ||
public static Privilege fromName(Privilege.Name name) { | ||
switch (name) { | ||
case LOAD_CATALOG: | ||
return LoadCatalog.get(); | ||
default: | ||
throw new IllegalArgumentException("Don't support the privilege: " + name); | ||
} | ||
} | ||
|
||
/** The privilege of load a catalog. */ | ||
public static class LoadCatalog implements Privilege { | ||
private static final LoadCatalog INSTANCE = new LoadCatalog(); | ||
|
||
/** @return The instance of the privilege. */ | ||
public static LoadCatalog get() { | ||
return INSTANCE; | ||
} | ||
|
||
private LoadCatalog() {} | ||
|
||
/** @return The generic name of the privilege. */ | ||
@Override | ||
public Name name() { | ||
return Name.LOAD_CATALOG; | ||
} | ||
|
||
/** @return A readable string representation for the privilege. */ | ||
@Override | ||
public String simpleString() { | ||
return "load catalog"; | ||
} | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
api/src/main/java/com/datastrato/gravitino/authorization/Role.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright 2024 Datastrato Pvt Ltd. | ||
* This software is licensed under the Apache License version 2. | ||
*/ | ||
package com.datastrato.gravitino.authorization; | ||
|
||
import com.datastrato.gravitino.Auditable; | ||
import com.datastrato.gravitino.annotation.Evolving; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* The interface of a role. The role is the entity which has kinds of privileges. One role can have | ||
* multiple privileges of one securable object. Gravitino chooses to bind one securable object to | ||
* one role to avoid granting too many privileges to one role. | ||
*/ | ||
@Evolving | ||
public interface Role extends Auditable { | ||
|
||
/** | ||
* The name of the role. | ||
* | ||
* @return The name of the role. | ||
*/ | ||
String name(); | ||
|
||
/** | ||
* The properties of the role. Note, this method will return null if the properties are not set. | ||
* | ||
* @return The properties of the role. | ||
*/ | ||
Map<String, String> properties(); | ||
|
||
/** | ||
* The privileges of the role. All privileges belong to one securable object. For example: If the | ||
* securable object is a table, the privileges could be `READ TABLE`, `WRITE TABLE`, etc. If a | ||
* schema has the privilege of `LOAD TABLE`. It means the role can all tables of the schema. | ||
* | ||
* @return The privileges of the role. | ||
*/ | ||
List<Privilege> privileges(); | ||
|
||
/** | ||
* The securable object represents a special kind of entity with a unique identifier. All | ||
* securable objects are organized by tree structure. For example: If the securable object is a | ||
* table, the identifier may be `catalog1.schema1.table1`. | ||
* | ||
* @return The securable object of the role. | ||
*/ | ||
SecurableObject securableObject(); | ||
} |
39 changes: 39 additions & 0 deletions
39
api/src/main/java/com/datastrato/gravitino/authorization/SecurableObject.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright 2024 Datastrato Pvt Ltd. | ||
* This software is licensed under the Apache License version 2. | ||
*/ | ||
package com.datastrato.gravitino.authorization; | ||
|
||
import com.datastrato.gravitino.annotation.Evolving; | ||
import javax.annotation.Nullable; | ||
|
||
/** | ||
* The securable object is the entity which access can be granted. Unless allowed by a grant, access | ||
* is denied. Gravitino organizes the securable objects using tree structure. The securable object | ||
* may be a catalog, a table or a schema, etc. For example, `catalog1.schema1.table1` represents a | ||
* table named `table1`. It's in the schema named `schema1`. The schema is in the catalog named | ||
* `catalog1`. Similarly, `catalog1.schema1.topic1` can represent a topic. | ||
* `catalog1.schema1.fileset1` can represent a fileset. `*` represents all the catalogs. If you want | ||
* to use other securable objects which represents all entities," you can use their parent entity, | ||
* For example if you want to have read table privileges of all tables of `catalog1.schema1`, " you | ||
* can use add `read table` privilege for `catalog1.schema1` directly | ||
*/ | ||
@Evolving | ||
public interface SecurableObject { | ||
|
||
/** | ||
* The parent securable object. If the securable object doesn't have parent, this method will | ||
* return null. | ||
* | ||
* @return The parent securable object. | ||
*/ | ||
@Nullable | ||
SecurableObject parent(); | ||
|
||
/** | ||
* The name of th securable object. | ||
* | ||
* @return The name of the securable object. | ||
*/ | ||
String name(); | ||
} |
189 changes: 189 additions & 0 deletions
189
api/src/main/java/com/datastrato/gravitino/authorization/SecurableObjects.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/* | ||
* Copyright 2024 Datastrato Pvt Ltd. | ||
* This software is licensed under the Apache License version 2. | ||
*/ | ||
package com.datastrato.gravitino.authorization; | ||
|
||
import java.util.Objects; | ||
|
||
/** The helper class for {@link SecurableObject}. */ | ||
public class SecurableObjects { | ||
|
||
/** | ||
* Create the {@link SecurableObject} with the given names. | ||
* | ||
* @param names The names of the securable object. | ||
* @return The created {@link SecurableObject} | ||
*/ | ||
public static SecurableObject of(String... names) { | ||
if (names == null) { | ||
throw new IllegalArgumentException("Cannot create a securable object with null names"); | ||
} | ||
|
||
if (names.length == 0) { | ||
throw new IllegalArgumentException("Cannot create a securable object with no names"); | ||
} | ||
|
||
SecurableObject parent = null; | ||
for (String name : names) { | ||
if (name == null) { | ||
throw new IllegalArgumentException("Cannot create a securable object with null name"); | ||
} | ||
|
||
if (name.equals("*")) { | ||
throw new IllegalArgumentException( | ||
"Cannot create a securable object with `*` name. If you want to use a securable object which represents all catalogs," | ||
+ " you use the method `ofAllCatalogs`." | ||
+ " If you want to create an another securable object which represents all entities," | ||
+ " you can use its parent entity, For example," | ||
+ " if you want to have read table privileges of all tables of `catalog1.schema1`," | ||
+ " you can use add `read table` privilege for `catalog1.schema1` directly"); | ||
} | ||
|
||
parent = new SecurableObjectImpl(parent, name); | ||
} | ||
|
||
return parent; | ||
} | ||
|
||
/** | ||
* Create the catalog {@link SecurableObject} with the given catalog name. | ||
* | ||
* @param catalog The catalog name | ||
* @return The created catalog {@link SecurableObject} | ||
*/ | ||
public static SecurableObject ofCatalog(String catalog) { | ||
return of(catalog); | ||
} | ||
|
||
/** | ||
* Create the schema {@link SecurableObject} with the given securable catalog object and schema | ||
* name. | ||
* | ||
* @param catalog The securable catalog object | ||
* @param schema The schema name | ||
* @return The created schema {@link SecurableObject} | ||
*/ | ||
public static SecurableObject ofSchema(SecurableObject catalog, String schema) { | ||
checkCatalog(catalog); | ||
|
||
return of(catalog.name(), schema); | ||
} | ||
|
||
/** | ||
* Create the table {@link SecurableObject} with the given securable schema object and table name. | ||
* | ||
* @param schema The securable schema object | ||
* @param table The table name | ||
* @return The created table {@link SecurableObject} | ||
*/ | ||
public static SecurableObject ofTable(SecurableObject schema, String table) { | ||
checkSchema(schema); | ||
|
||
return of(schema.parent().name(), schema.name(), table); | ||
} | ||
|
||
/** | ||
* Create the topic {@link SecurableObject} with the given securable schema object and topic name. | ||
* | ||
* @param schema The securable schema object | ||
* @param topic The topic name | ||
* @return The created topic {@link SecurableObject} | ||
*/ | ||
public static SecurableObject ofTopic(SecurableObject schema, String topic) { | ||
checkSchema(schema); | ||
|
||
return of(schema.parent().name(), schema.name(), topic); | ||
} | ||
|
||
/** | ||
* Create the table {@link SecurableObject} with the given securable schema object and fileset | ||
* name. | ||
* | ||
* @param schema The securable schema object | ||
* @param fileset The fileset name | ||
* @return The created fileset {@link SecurableObject} | ||
*/ | ||
public static SecurableObject ofFileset(SecurableObject schema, String fileset) { | ||
checkSchema(schema); | ||
|
||
return of(schema.parent().name(), schema.name(), fileset); | ||
} | ||
|
||
/** | ||
* All catalogs is a special securable object .You can give the securable object the privileges | ||
* `LOAD CATALOG`, `CREATE CATALOG`, etc. It means that you can load any catalog and create any | ||
* which doesn't exist. | ||
* | ||
* @return The created {@link SecurableObject} | ||
*/ | ||
public static SecurableObject ofAllCatalogs() { | ||
return ALL_CATALOGS; | ||
} | ||
|
||
private static void checkSchema(SecurableObject schema) { | ||
if (schema == null) { | ||
throw new IllegalArgumentException("Securable schema object can't be null"); | ||
} | ||
checkCatalog(schema.parent()); | ||
} | ||
|
||
private static void checkCatalog(SecurableObject catalog) { | ||
if (catalog == null) { | ||
throw new IllegalArgumentException("Securable catalog object can't be null"); | ||
} | ||
|
||
if (catalog.parent() != null) { | ||
throw new IllegalArgumentException( | ||
String.format("The parent of securable catalog object %s must be null", catalog.name())); | ||
} | ||
} | ||
|
||
private static final SecurableObject ALL_CATALOGS = new SecurableObjectImpl(null, "*"); | ||
|
||
private static class SecurableObjectImpl implements SecurableObject { | ||
|
||
private final SecurableObject parent; | ||
private final String name; | ||
|
||
SecurableObjectImpl(SecurableObject parent, String name) { | ||
this.parent = parent; | ||
this.name = name; | ||
} | ||
|
||
@Override | ||
public SecurableObject parent() { | ||
return parent; | ||
} | ||
|
||
@Override | ||
public String name() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(parent, name); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
if (parent != null) { | ||
return parent.toString() + "." + name; | ||
} else { | ||
return name; | ||
} | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
if (!(other instanceof SecurableObject)) { | ||
return false; | ||
} | ||
|
||
SecurableObject otherSecurableObject = (SecurableObject) other; | ||
return Objects.equals(parent, otherSecurableObject.parent()) | ||
&& Objects.equals(name, otherSecurableObject.name()); | ||
} | ||
} | ||
} |
Oops, something went wrong.