Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2967] feat(api,server): Add the more privileges #2965

Merged
merged 42 commits into from
Apr 22, 2024

Conversation

qqqttt123
Copy link
Contributor

@qqqttt123 qqqttt123 commented Apr 16, 2024

What changes were proposed in this pull request?

Add the more privileges and check the privilege constraint about securable object.

Why are the changes needed?

Fix: #2967

Does this PR introduce any user-facing change?

No.

How was this patch tested?

Add new UT.

@qqqttt123 qqqttt123 self-assigned this Apr 16, 2024
@qqqttt123 qqqttt123 marked this pull request as draft April 16, 2024 07:20
@qqqttt123 qqqttt123 force-pushed the ISSUE-2235-part2 branch 2 times, most recently from 1f48ae3 to c891960 Compare April 16, 2024 07:41
@qqqttt123 qqqttt123 changed the title [#2235][part-2] feat(api,server): Add the more privileges [#2968] feat(api,server): Add the more privileges Apr 16, 2024
@qqqttt123 qqqttt123 changed the title [#2968] feat(api,server): Add the more privileges [#2967] feat(api,server): Add the more privileges Apr 16, 2024
@qqqttt123
Copy link
Contributor Author

The logic of this pull request is simple, there exists duplicate code, although this is a little large, so I don't divide it into two pull requests.

@qqqttt123 qqqttt123 marked this pull request as ready for review April 16, 2024 08:02
@qqqttt123 qqqttt123 requested a review from jerryshao April 16, 2024 08:03
@jerryshao
Copy link
Contributor

Is it ready for reviewing? @qqqttt123

@qqqttt123
Copy link
Contributor Author

Is it ready for reviewing? @qqqttt123

Yes. It is ready.

/** The privilege to drop a table. */
DROP_TABLE,
/** The privilege to read a table. */
READ_TABLE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need both LOAD_XXX and READ/WRITE_XXX? How will user use them?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also how do you distinguish whether the table has read or write privilege from Gravitino?

Copy link
Contributor Author

@qqqttt123 qqqttt123 Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Yes, LOAD_TABLE is a meta data operation and the READ_TABLE is a data operation. They are different operations.
  2. Gravitino doesn't disitinguish the privilege. User doesn't use Gravitino to read or write table.
    Gravitino set the privileges of read/ write table to the underlying system. The underlying system will judge the privilege of read/write when the users access the underlying system.

@@ -33,12 +44,54 @@
public class RoleOperations {
private static final Logger LOG = LoggerFactory.getLogger(RoleOperations.class);

private static final String PRIVILEGE_ERROR_MSG = "%s shouldn't bind the privilege %s";
private static final String UNSUPPORTED_ERROR_MSG = "%s uses an unsupported catalog type";
private static final List<Privilege> CATALOG_PRIVILEGES =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you mentioned before that catalog will have the schema privileges like create schema, how do you achieve this in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can see the comment of checkSecurableObjectPrivileges

/** The privilege to read a topic. */
READ_TOPIC,
/** The privilege to write a topic. */
WRITE_TOPIC
Copy link
Contributor

@jerryshao jerryshao Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name here are too specific for metadata, users may not know it is, like LOAD? I think you'd better have a more suitable name for users easy to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOAD_TOPIC means that we read the meta data of topic while READ_TOPIC means that we read data of topic.

@qqqttt123
Copy link
Contributor Author

@jerryshao I refactor the code

  1. Remove LOAD_TABLE,LOAD_TOPIC,LOAD_FILESET.
  2. Refactor the comment and the logic of checking privileges.

@qqqttt123 qqqttt123 requested a review from jerryshao April 17, 2024 09:06
@qqqttt123
Copy link
Contributor Author

The CI pipeline of python failed. It's unrelated to this pull request.

@@ -33,12 +44,76 @@
public class RoleOperations {
private static final Logger LOG = LoggerFactory.getLogger(RoleOperations.class);

private static final String UNSUPPORTED_ERROR_MSG = "%s is an unsupported catalog type";
private static final List<Privilege> CATALOG_PRIVILEGES_EXCEPT_FOR_LIST =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you put the code in core, what is the specific reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check logic needs to get the type of catalog. We should use tree lock to get the catalog. We usually use the tree lock in the operation instead of core.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@jerryshao
Copy link
Contributor

I think you should really polish the code to make your check logic more clear and easy-to-understand before it is ready to review.

@qqqttt123
Copy link
Contributor Author

I think you should really polish the code to make your check logic more clear and easy-to-understand before it is ready to review.

I have no idea to make this pull request more clear.
I have tried to add more comments and wrap more methods. It's not suitable to use state machine.

@qqqttt123 qqqttt123 force-pushed the ISSUE-2235-part2 branch 2 times, most recently from 59773bc to 6763ffa Compare April 20, 2024 06:03
@qqqttt123
Copy link
Contributor Author

@jerryshao I have removed the check code and add more privileges.

/** The privilege to alter a catalog. */
ALTER_CATALOG,
/** The privilege to drop a catalog. */
DROP_CATALOG,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can also add a bit to each privilege like 0x01, 0x10, so that later on when we have a privilege like ALL_PRIVILEGE that can be represented as a combination of several privileges, you can think of this.

/** The privilege to drop a schema. */
DROP_SCHEMA,
/** The privilege to show tables. */
SHOW_TABLE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SHOW_TABLES or SHOW_TABLE, I think for SHOW_XXX, it should add "s", right?

Copy link
Contributor Author

@qqqttt123 qqqttt123 Apr 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From UI's view, to show resources tree. Maybe we don't need show metalakes, show tables, show schemas privilege. Every one should have the privilege. I want to remove them a little.

Copy link
Contributor Author

@qqqttt123 qqqttt123 Apr 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Em...OK, I will correct this. My concern is that we don't use LOAD_A_SCHEMA. But I really want to all list entities this.

Comment on lines 75 to 85
USE_METALAKE,
/** The privilege to manage a metalake. */
MANAGE_METALAKE,
/** The privilege to create a metalake. */
CREATE_METALAKE,
/** The privilege to manage users. */
MANAGE_USER,
/** The privilege to manage groups. */
MANAGE_GROUP,
/** The privilege to manage roles. */
MANAGE_ROLE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These privileges should be explained well in the document and comment.

* A role is used for access control. A role will indicate that it has some privileges to access
* some securable objects.
*/
ROLE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a ROLE securable object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will create a special role for one entity.
One creator of one entity should have the privilege to grant the owner role to others.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example? If it is user A who create a table "foo", so the privilege this "grant role", the securable object is table "foo", grant to user A, am I right? the securable object is table, not role, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's ok, too. I will remove the entity.

* The type of securable object in the Gravitino system. Every type will map one kind of the entity
* of the underlying system.
*/
public enum SecurableObjectType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these Type enum class can be an inner class in SecurableObject.

List<SecurableObjectType> typeInDifferentLevels =
Lists.newArrayList(SecurableObjectType.CATALOG, SecurableObjectType.SCHEMA);

if (names.length == 1 && type != SecurableObjectType.CATALOG) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For metalake, the length should also be 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add some test code.

Comment on lines 65 to 67
if (names.length > 2) {
typeInDifferentLevels.add(type);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the meaning of these codes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactor these code to make it more clear.

@@ -38,27 +76,39 @@ public static SecurableObject of(String... names) {
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,"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all metalakes, not all catalogs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will modify the comment. I will explain ofMetalake and ofAllMetalakes.

@@ -144,16 +193,19 @@ private static void checkCatalog(SecurableObject catalog) {
}
}

private static final SecurableObject ALL_CATALOGS = new SecurableObjectImpl(null, "*");
private static final SecurableObject ALL_METALAKES =
new SecurableObjectImpl(null, "*", SecurableObjectType.CATALOG);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this type correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My fault. I will add some tests for this class.

@qqqttt123
Copy link
Contributor Author

@jerryshao All comments are addressed.

/** The privilege to manage groups, including add,remove and get a group. */
MANAGE_GROUP(1L << 23),
/** The privilege to manage roles, including create,drop,alter,grant and revoke a role. */
MANAGE_ROLE(1L << 24);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid that 64 bit may not be enough when we continue to add more fine-grained privileges, what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* represent a fileset.<br>
* `*` can represent all th metalakes <br>
* `metalake` can represent all the catalogs of this metalake. <br>
* To use other securable objects which represents all entities," you can use their parent entity,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest you add more descriptions and examples about this securable object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored the comment.

Comment on lines 69 to 72
for (int parentNum = names.length - 2; parentNum >= 0; parentNum--) {
curType = getParentSecurableObjectType(curType);
types.add(curType);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part of code is a bit of hardcoded, can you please refine this code and remove this hardcoded numbers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @return The created {@link SecurableObject}
*/
public static SecurableObject parse(String securableObjectIdentifier) {
public static SecurableObject parse(String securableObjectIdentifier, SecurableObject.Type type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit unknown about this securableObjectIdentifier, so I would suggest not introducing new name/concept, you can use "fullName" and add more comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @param names The names of the securable object.
* @return The created {@link SecurableObject}
*/
public static SecurableObject of(String... names) {
public static SecurableObject of(SecurableObject.Type type, String... names) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This names maybe errorprone, you require that names be ordered like catalog, schema, table, but in your code you cannot do such enforcement, so I would suggest you redefine your interface to avoid misuse.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the public.

Comment on lines 71 to 75
MANAGE_USER(1L << 22),
/** The privilege to manage groups, including add,remove and get a group. */
MANAGE_GROUP(1L << 23),
/** The privilege to manage roles, including create,drop,alter,grant and revoke a role. */
MANAGE_ROLE(1L << 24);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest we use fine-grained privilege for USER, GROUP, ROLE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@qqqttt123
Copy link
Contributor Author

@jerryshao All comments are addressed.

@qqqttt123 qqqttt123 requested a review from jerryshao April 22, 2024 06:57
* `SecurableObjects.ofTopic("topic1")` to create the securable object, or you can use full name
* `catalog1.schema1.topic1` and type `TOPIC` in the RESTFUL API. <br>
* If you want to use a fileset named `fileset1` in the schema named `schema1`, you can use the code
* `SecurableObjects.ofFileset("fileset1)` to create the securable object, or you can use full name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is different the API you offered, you miss the parent securable object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@qqqttt123 qqqttt123 requested a review from jerryshao April 22, 2024 13:13
@qqqttt123
Copy link
Contributor Author

I test this pull request with the commands as follows;

curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" -d '{"name":"metalake1","privileges":["USE_CATALOG"], "securableObject":{"fullName": "catalog","type": "catalog"}}' \
http://localhost:8090/api/metalakes/metalake/roles
{"code":0,"role":{"name":"metalake1","audit":{"creator":"anonymous","createTime":"2024-04-22T13:44:24.839Z"},"privileges":["USE_CATALOG"],"securableObject":{"fullName":"catalog","type":"catalog"}}}%  

It's ok.

@qqqttt123 qqqttt123 merged commit 2a1ba00 into apache:main Apr 22, 2024
22 checks passed
diqiu50 pushed a commit to diqiu50/gravitino that referenced this pull request Jun 13, 2024
### What changes were proposed in this pull request?

Add the more privileges and check the privilege constraint about
securable object.

### Why are the changes needed?

Fix: apache#2967 

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

### How was this patch tested?
Add new UT.

---------

Co-authored-by: Heng Qin <qqtt@123.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Subtask] Add more privileges for the Role
2 participants