You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by yo...@apache.org on 2023/07/31 12:57:41 UTC

[iotdb] 03/12: [IOTDB-5134] Fix Auth Module Contain (#10545)

This is an automated email from the ASF dual-hosted git repository.

yongzao pushed a commit to branch compute-resource-balance-1.2
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 5037231a1d76d156c3685a5f49c488add7dd3e93
Author: ZhangHongYin <46...@users.noreply.github.com>
AuthorDate: Thu Jul 13 19:36:55 2023 +0800

    [IOTDB-5134] Fix Auth Module Contain (#10545)
---
 .../Administration-Management/Administration.md    |  4 +-
 .../Administration-Management/Administration.md    |  4 +-
 .../Security-Management.md                         |  4 +-
 docs/zh/UserGuide/SQL-Manual/SQL-Manual.md         |  4 +-
 .../UserGuide/User-Manuel/Authority-Management.md  |  4 +-
 .../java/org/apache/iotdb/db/it/IoTDBAuthIT.java   | 16 ++---
 .../org/apache/iotdb/db/auth/AuthorityChecker.java | 84 ++++++++++++----------
 .../auth/authorizer/LocalFileAuthorizerTest.java   |  6 +-
 .../iotdb/commons/auth/entity/PrivilegeType.java   |  4 +-
 9 files changed, 69 insertions(+), 61 deletions(-)

diff --git a/docs/UserGuide/Administration-Management/Administration.md b/docs/UserGuide/Administration-Management/Administration.md
index 2bf7d882424..c62e34d20b0 100644
--- a/docs/UserGuide/Administration-Management/Administration.md
+++ b/docs/UserGuide/Administration-Management/Administration.md
@@ -91,7 +91,7 @@ The SQL statement will not be executed and the corresponding error prompt is giv
 
 ```
 IoTDB> INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 Now, we use root user to grant the two users write privileges to the corresponding databases.
@@ -144,7 +144,7 @@ Msg: The statement is executed successfully.
 After revoking, ln_write_user has no permission to writing data to root.ln.**
 ```
 INSERT INTO root.ln.wf01.wt01(timestamp, status) values(1509465600000, true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 ### SQL Statements
diff --git a/docs/zh/UserGuide/Administration-Management/Administration.md b/docs/zh/UserGuide/Administration-Management/Administration.md
index e171f7513c9..e9305565cb7 100644
--- a/docs/zh/UserGuide/Administration-Management/Administration.md
+++ b/docs/zh/UserGuide/Administration-Management/Administration.md
@@ -90,7 +90,7 @@ INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
 
 ```
 IoTDB> INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 现在,我们用root用户分别赋予他们向对应 database 数据的写入权限.
@@ -143,7 +143,7 @@ Msg: The statement is executed successfully.
 撤销权限后,ln_write_user就没有向root.ln.**写入数据的权限了。
 ```
 INSERT INTO root.ln.wf01.wt01(timestamp, status) values(1509465600000, true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 ### SQL 语句
diff --git a/docs/zh/UserGuide/Deployment-and-Maintenance/Security-Management.md b/docs/zh/UserGuide/Deployment-and-Maintenance/Security-Management.md
index f44034b1274..299df40f3fe 100644
--- a/docs/zh/UserGuide/Deployment-and-Maintenance/Security-Management.md
+++ b/docs/zh/UserGuide/Deployment-and-Maintenance/Security-Management.md
@@ -95,7 +95,7 @@ INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
 
 ```
 IoTDB> INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 现在,我们用root用户分别赋予他们向对应 database 数据的写入权限.
@@ -151,7 +151,7 @@ Msg: The statement is executed successfully.
 
 ```
 INSERT INTO root.ln.wf01.wt01(timestamp, status) values(1509465600000, true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 #### SQL 语句
diff --git a/docs/zh/UserGuide/SQL-Manual/SQL-Manual.md b/docs/zh/UserGuide/SQL-Manual/SQL-Manual.md
index dba87ab6c9c..0efe43bb550 100644
--- a/docs/zh/UserGuide/SQL-Manual/SQL-Manual.md
+++ b/docs/zh/UserGuide/SQL-Manual/SQL-Manual.md
@@ -2051,7 +2051,7 @@ INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
 
 IoTDB> INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
 
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 
 用root用户分别赋予他们向对应 database 数据的写入权限
 
@@ -2081,7 +2081,7 @@ REVOKE USER `ln_write_user` PRIVILEGES CREATE_USER
 
 INSERT INTO root.ln.wf01.wt01(timestamp, status) values(1509465600000, true)
 
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 
 ### 5、SQL 语句
 
diff --git a/docs/zh/UserGuide/User-Manuel/Authority-Management.md b/docs/zh/UserGuide/User-Manuel/Authority-Management.md
index d59c8fc31f8..dd6491e42e1 100644
--- a/docs/zh/UserGuide/User-Manuel/Authority-Management.md
+++ b/docs/zh/UserGuide/User-Manuel/Authority-Management.md
@@ -93,7 +93,7 @@ INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
 
 ```
 IoTDB> INSERT INTO root.ln.wf01.wt01(timestamp,status) values(1509465600000,true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 现在,我们用root用户分别赋予他们向对应 database 数据的写入权限.
@@ -149,7 +149,7 @@ Msg: The statement is executed successfully.
 
 ```
 INSERT INTO root.ln.wf01.wt01(timestamp, status) values(1509465600000, true)
-Msg: 602: No permissions for this operation, please add privilege INSERT_TIMESERIES.
+Msg: 602: No permissions for this operation, please add privilege WRITE_DATA.
 ```
 
 ### SQL 语句
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBAuthIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBAuthIT.java
index 2df47a3588b..78dbe87e4df 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBAuthIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBAuthIT.java
@@ -362,7 +362,7 @@ public class IoTDBAuthIT {
 
         adminStmt.execute("CREATE ROLE admin");
         adminStmt.execute(
-            "GRANT ROLE admin PRIVILEGES MANAGE_DATABASE,WRITE_SCHEMA,READ_DATA,WRITE_DATA on root.**");
+            "GRANT ROLE admin PRIVILEGES MANAGE_DATABASE,WRITE_SCHEMA,WRITE_DATA on root.**");
         adminStmt.execute("GRANT admin TO tempuser");
 
         userStmt.execute("CREATE DATABASE root.a");
@@ -495,15 +495,15 @@ public class IoTDBAuthIT {
       String ans =
           ",root.a.b : READ_SCHEMA"
               + ",\n"
-              + "role1,root.a.b.c : READ_DATA WRITE_DATA READ_SCHEMA"
+              + "role1,root.a.b.c : WRITE_DATA READ_SCHEMA"
               + ",\n"
-              + "role1,root.d.b.c : READ_DATA WRITE_DATA READ_SCHEMA"
+              + "role1,root.d.b.c : WRITE_DATA READ_SCHEMA"
               + ",\n";
       try {
         validateResultSet(resultSet, ans);
 
         resultSet = adminStmt.executeQuery("LIST PRIVILEGES USER user1 ON root.a.b.c");
-        ans = "role1,root.a.b.c : READ_DATA WRITE_DATA READ_SCHEMA,\n";
+        ans = "role1,root.a.b.c : WRITE_DATA READ_SCHEMA,\n";
         validateResultSet(resultSet, ans);
 
         adminStmt.execute("REVOKE role1 from user1");
@@ -540,19 +540,17 @@ public class IoTDBAuthIT {
         adminStmt.execute("GRANT ROLE role1 PRIVILEGES READ_SCHEMA,WRITE_DATA ON root.a.b.c");
         adminStmt.execute("GRANT ROLE role1 PRIVILEGES READ_SCHEMA,WRITE_DATA ON root.d.b.c");
         resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1");
-        ans =
-            "root.a.b.c : READ_DATA WRITE_DATA READ_SCHEMA,\n"
-                + "root.d.b.c : READ_DATA WRITE_DATA READ_SCHEMA,\n";
+        ans = "root.a.b.c : WRITE_DATA READ_SCHEMA,\n" + "root.d.b.c : WRITE_DATA READ_SCHEMA,\n";
         validateResultSet(resultSet, ans);
 
         resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1 ON root.a.b.c");
-        ans = "root.a.b.c : READ_DATA WRITE_DATA READ_SCHEMA,\n";
+        ans = "root.a.b.c : WRITE_DATA READ_SCHEMA,\n";
         validateResultSet(resultSet, ans);
 
         adminStmt.execute("REVOKE ROLE role1 PRIVILEGES READ_SCHEMA,WRITE_DATA ON root.a.b.c");
 
         resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1");
-        ans = "root.d.b.c : READ_DATA WRITE_DATA READ_SCHEMA,\n";
+        ans = "root.d.b.c : WRITE_DATA READ_SCHEMA,\n";
         validateResultSet(resultSet, ans);
 
         resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1 ON root.a.b.c");
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
index a7feb9966c8..905f895d349 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
@@ -72,26 +72,31 @@ public class AuthorityChecker {
       return true;
     }
 
-    int permission = translateToPermissionId(type);
-    if (permission == -1) {
-      return false;
-    } else if (permission == PrivilegeType.ALTER_PASSWORD.ordinal()
-        && username.equals(targetUser)) {
-      // A user can modify his own password
-      return true;
-    }
+    int[] permissions = translateToPermissionId(type);
+    for (int permission : permissions) {
+      if (permission == -1) {
+        continue;
+      } else if (permission == PrivilegeType.ALTER_PASSWORD.ordinal()
+          && username.equals(targetUser)) {
+        // A user can modify his own password
+        return true;
+      }
 
-    List<PartialPath> allPath = new ArrayList<>();
-    if (paths != null && !paths.isEmpty()) {
-      for (PartialPath path : paths) {
-        allPath.add(path == null ? AuthUtils.ROOT_PATH_PRIVILEGE_PATH : path);
+      List<PartialPath> allPath = new ArrayList<>();
+      if (paths != null && !paths.isEmpty()) {
+        for (PartialPath path : paths) {
+          allPath.add(path == null ? AuthUtils.ROOT_PATH_PRIVILEGE_PATH : path);
+        }
+      } else {
+        allPath.add(AuthUtils.ROOT_PATH_PRIVILEGE_PATH);
       }
-    } else {
-      allPath.add(AuthUtils.ROOT_PATH_PRIVILEGE_PATH);
-    }
 
-    TSStatus status = authorizerManager.checkPath(username, allPath, permission);
-    return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode();
+      TSStatus status = authorizerManager.checkPath(username, allPath, permission);
+      if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+        return true;
+      }
+    }
+    return false;
   }
 
   private static boolean checkOnePath(String username, PartialPath path, int permission)
@@ -113,11 +118,16 @@ public class AuthorityChecker {
     long startTime = System.nanoTime();
     try {
       if (!checkAuthorization(statement, session.getUsername())) {
-        return RpcUtils.getStatus(
-            TSStatusCode.NO_PERMISSION,
-            "No permissions for this operation, please add privilege "
-                + PrivilegeType.values()[
-                    AuthorityChecker.translateToPermissionId(statement.getType())]);
+        StringBuilder prompt =
+            new StringBuilder("No permissions for this operation, please add privilege ");
+        int[] permissions = translateToPermissionId(statement.getType());
+        for (int i = 0; i < permissions.length; i++) {
+          if (i != 0) {
+            prompt.append(" or ");
+          }
+          prompt.append(PrivilegeType.values()[permissions[i]]);
+        }
+        return RpcUtils.getStatus(TSStatusCode.NO_PERMISSION, prompt.toString());
       }
     } catch (AuthException e) {
       logger.warn("Meets error while checking authorization.", e);
@@ -150,16 +160,18 @@ public class AuthorityChecker {
         username, statement.getPaths(), statement.getType(), targetUser);
   }
 
-  private static int translateToPermissionId(StatementType type) {
+  private static int[] translateToPermissionId(StatementType type) {
     switch (type) {
       case SHOW_SCHEMA_TEMPLATE:
       case SHOW_NODES_IN_SCHEMA_TEMPLATE:
       case SHOW_PATH_SET_SCHEMA_TEMPLATE:
       case SHOW_PATH_USING_SCHEMA_TEMPLATE:
-        return PrivilegeType.READ_SCHEMA.ordinal();
+        return new int[] {
+          PrivilegeType.READ_SCHEMA.ordinal(), PrivilegeType.WRITE_SCHEMA.ordinal()
+        };
       case STORAGE_GROUP_SCHEMA:
       case DELETE_STORAGE_GROUP:
-        return PrivilegeType.MANAGE_DATABASE.ordinal();
+        return new int[] {PrivilegeType.MANAGE_DATABASE.ordinal()};
       case TTL:
       case CREATE_TIMESERIES:
       case CREATE_ALIGNED_TIMESERIES:
@@ -177,7 +189,7 @@ public class AuthorityChecker {
       case ALTER_LOGICAL_VIEW:
       case RENAME_LOGICAL_VIEW:
       case DELETE_LOGICAL_VIEW:
-        return PrivilegeType.WRITE_SCHEMA.ordinal();
+        return new int[] {PrivilegeType.WRITE_SCHEMA.ordinal()};
       case SHOW:
       case QUERY:
       case GROUP_BY_TIME:
@@ -192,7 +204,7 @@ public class AuthorityChecker {
       case COUNT:
       case CREATE_FUNCTION:
       case DROP_FUNCTION:
-        return PrivilegeType.READ_DATA.ordinal();
+        return new int[] {PrivilegeType.READ_DATA.ordinal(), PrivilegeType.WRITE_DATA.ordinal()};
       case INSERT:
       case DELETE:
       case LOAD_DATA:
@@ -201,35 +213,35 @@ public class AuthorityChecker {
       case BATCH_INSERT_ONE_DEVICE:
       case BATCH_INSERT_ROWS:
       case MULTI_BATCH_INSERT:
-        return PrivilegeType.WRITE_DATA.ordinal();
+        return new int[] {PrivilegeType.WRITE_DATA.ordinal()};
       case CREATE_USER:
       case DELETE_USER:
       case LIST_USER:
       case LIST_USER_ROLES:
       case LIST_USER_PRIVILEGE:
-        return PrivilegeType.MANAGE_USER.ordinal();
+        return new int[] {PrivilegeType.MANAGE_USER.ordinal()};
       case CREATE_ROLE:
       case DELETE_ROLE:
       case LIST_ROLE:
       case LIST_ROLE_USERS:
       case LIST_ROLE_PRIVILEGE:
-        return PrivilegeType.MANAGE_ROLE.ordinal();
+        return new int[] {PrivilegeType.MANAGE_ROLE.ordinal()};
       case MODIFY_PASSWORD:
-        return PrivilegeType.ALTER_PASSWORD.ordinal();
+        return new int[] {PrivilegeType.ALTER_PASSWORD.ordinal()};
       case GRANT_USER_PRIVILEGE:
       case REVOKE_USER_PRIVILEGE:
       case GRANT_ROLE_PRIVILEGE:
       case REVOKE_ROLE_PRIVILEGE:
       case GRANT_USER_ROLE:
       case REVOKE_USER_ROLE:
-        return PrivilegeType.GRANT_PRIVILEGE.ordinal();
+        return new int[] {PrivilegeType.GRANT_PRIVILEGE.ordinal()};
       case CREATE_TRIGGER:
       case DROP_TRIGGER:
-        return PrivilegeType.USE_TRIGGER.ordinal();
+        return new int[] {PrivilegeType.USE_TRIGGER.ordinal()};
       case CREATE_CONTINUOUS_QUERY:
       case DROP_CONTINUOUS_QUERY:
       case SHOW_CONTINUOUS_QUERIES:
-        return PrivilegeType.USE_CQ.ordinal();
+        return new int[] {PrivilegeType.USE_CQ.ordinal()};
       case CREATE_PIPEPLUGIN:
       case DROP_PIPEPLUGIN:
       case SHOW_PIPEPLUGINS:
@@ -238,10 +250,10 @@ public class AuthorityChecker {
       case STOP_PIPE:
       case DROP_PIPE:
       case SHOW_PIPES:
-        return PrivilegeType.USE_PIPE.ordinal();
+        return new int[] {PrivilegeType.USE_PIPE.ordinal()};
       default:
         logger.error("Unrecognizable operator type ({}) for AuthorityChecker.", type);
-        return -1;
+        return new int[] {-1};
     }
   }
 }
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java
index 8b532268ca5..eccde64eb02 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java
@@ -200,10 +200,8 @@ public class LocalFileAuthorizerTest {
 
     // a user can get all role permissions.
     Set<Integer> permissions = authorizer.getPrivileges(user.getName(), nodeName);
-    assertEquals(4, permissions.size());
-    assertTrue(permissions.contains(0));
+    assertEquals(2, permissions.size());
     assertTrue(permissions.contains(1));
-    assertTrue(permissions.contains(2));
     assertTrue(permissions.contains(3));
     assertFalse(permissions.contains(4));
 
@@ -215,7 +213,7 @@ public class LocalFileAuthorizerTest {
     // revoke a role from a user, the user will lose all role's permission
     authorizer.revokeRoleFromUser(roleName, user.getName());
     Set<Integer> revokeRolePermissions = authorizer.getPrivileges(user.getName(), nodeName);
-    assertEquals(2, revokeRolePermissions.size());
+    assertEquals(1, revokeRolePermissions.size());
     assertTrue(revokeRolePermissions.contains(1));
     assertFalse(revokeRolePermissions.contains(2));
 
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PrivilegeType.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PrivilegeType.java
index c3ef891ea7e..8f5f7bbd131 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PrivilegeType.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PrivilegeType.java
@@ -29,9 +29,9 @@ import java.util.Set;
 /** This enum class contains all available privileges in IoTDB. */
 public enum PrivilegeType {
   READ_DATA(true),
-  WRITE_DATA(true, true, READ_DATA),
+  WRITE_DATA(true),
   READ_SCHEMA(true),
-  WRITE_SCHEMA(true, true, READ_SCHEMA),
+  WRITE_SCHEMA(true),
   MANAGE_USER,
   MANAGE_ROLE,
   GRANT_PRIVILEGE,