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

shuwenwei pushed a commit to branch AuthEnhance
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/AuthEnhance by this push:
     new 63a840f2915 user and role management
63a840f2915 is described below

commit 63a840f2915b82c7f5fbee6fa27f4d2529bca7cc
Author: shuwenwei <[email protected]>
AuthorDate: Wed Sep 17 16:14:15 2025 +0800

    user and role management
---
 .../iotdb/confignode/persistence/AuthorInfo.java   | 10 +++-
 .../config/executor/ClusterConfigTaskExecutor.java | 10 ++--
 .../relational/security/AccessControlImpl.java     | 25 +++++-----
 .../security/TreeAccessCheckVisitor.java           | 57 ++++++++++++----------
 4 files changed, 57 insertions(+), 45 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
index bafb17ce87e..7550d888e55 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
@@ -502,7 +502,15 @@ public class AuthorInfo implements SnapshotProcessor {
 
   public PermissionInfoResp executeListUsers(final AuthorPlan plan) throws 
AuthException {
     final PermissionInfoResp result = new PermissionInfoResp();
-    final List<String> userList = authorizer.listAllUsers();
+    final List<String> userList;
+    boolean hasPermissionToListOtherUsers = plan.getUserName().isEmpty();
+    if (!hasPermissionToListOtherUsers) {
+      // userList may be modified later
+      userList = new ArrayList<>(1);
+      userList.add(plan.getUserName());
+    } else {
+      userList = authorizer.listAllUsers();
+    }
     if (!plan.getRoleName().isEmpty()) {
       final Role role = authorizer.getRole(plan.getRoleName());
       if (role == null) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index 4032c331c66..3133059be5e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -1618,10 +1618,14 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
     try (ConfigNodeClient client =
         
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
       // TODO: send all paths in one RPC
+      PathPatternTree authorityScope = showTTLStatement.getAuthorityScope();
       for (PartialPath pathPattern : showTTLStatement.getPaths()) {
-        TShowTTLReq req = new 
TShowTTLReq(Arrays.asList(pathPattern.getNodes()));
-        TShowTTLResp resp = client.showTTL(req);
-        databaseToTTL.putAll(resp.getPathTTLMap());
+        for (PartialPath overlappedPathPattern :
+            authorityScope.getOverlappedPathPatterns(pathPattern)) {
+          TShowTTLReq req = new 
TShowTTLReq(Arrays.asList(overlappedPathPattern.getNodes()));
+          TShowTTLResp resp = client.showTTL(req);
+          databaseToTTL.putAll(resp.getPathTTLMap());
+        }
       }
     } catch (ClientManagerException | TException e) {
       future.setException(e);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
index e0268913d39..ef913ea8f64 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
@@ -224,10 +224,9 @@ public class AccessControlImpl implements AccessControl {
         authChecker.checkGlobalPrivilege(userName, 
TableModelPrivilege.MANAGE_USER);
         return;
       case LIST_USER:
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
-          return;
+        if (!hasGlobalPrivilege(userName, PrivilegeType.MANAGE_USER)) {
+          statement.setUserName(userName);
         }
-        authChecker.checkGlobalPrivilege(userName, 
TableModelPrivilege.MANAGE_USER);
         return;
       case CREATE_ROLE:
         if (AuthorityChecker.SUPER_USER.equals(statement.getRoleName())) {
@@ -269,15 +268,13 @@ public class AccessControlImpl implements AccessControl {
         authChecker.checkGlobalPrivilege(userName, 
TableModelPrivilege.MANAGE_ROLE);
         return;
       case LIST_ROLE:
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
+        if (statement.getUserName() != null && 
!statement.getUserName().equals(userName)) {
+          authChecker.checkGlobalPrivilege(userName, 
TableModelPrivilege.MANAGE_ROLE);
           return;
         }
-
-        // user can list his roles.
-        if (statement.getUserName() != null && 
statement.getUserName().equals(userName)) {
-          return;
+        if (!hasGlobalPrivilege(userName, PrivilegeType.MANAGE_ROLE)) {
+          statement.setUserName(userName);
         }
-        authChecker.checkGlobalPrivilege(userName, 
TableModelPrivilege.MANAGE_ROLE);
         return;
       case LIST_ROLE_PRIV:
         if (AuthorityChecker.SUPER_USER.equals(userName)) {
@@ -295,7 +292,7 @@ public class AccessControlImpl implements AccessControl {
         if (AuthorityChecker.SUPER_USER.equals(statement.getUserName())) {
           throw new AccessDeniedException("Cannot grant/revoke privileges of 
admin user");
         }
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
+        if (hasGlobalPrivilege(userName, PrivilegeType.SECURITY)) {
           return;
         }
         for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -310,7 +307,7 @@ public class AccessControlImpl implements AccessControl {
         if (AuthorityChecker.SUPER_USER.equals(statement.getUserName())) {
           throw new AccessDeniedException("Cannot grant/revoke all privileges 
of admin user");
         }
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
+        if (hasGlobalPrivilege(userName, PrivilegeType.SECURITY)) {
           return;
         }
         for (TableModelPrivilege privilege : TableModelPrivilege.values()) {
@@ -334,7 +331,7 @@ public class AccessControlImpl implements AccessControl {
           throw new SemanticException(
               "Cannot grant or revoke any privileges to information_schema");
         }
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
+        if (hasGlobalPrivilege(userName, PrivilegeType.SECURITY)) {
           return;
         }
         for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -355,7 +352,7 @@ public class AccessControlImpl implements AccessControl {
           throw new SemanticException(
               "Cannot grant or revoke any privileges to information_schema");
         }
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
+        if (hasGlobalPrivilege(userName, PrivilegeType.SECURITY)) {
           return;
         }
         for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -373,7 +370,7 @@ public class AccessControlImpl implements AccessControl {
         if (AuthorityChecker.SUPER_USER.equals(statement.getUserName())) {
           throw new AccessDeniedException("Cannot grant/revoke privileges of 
admin user");
         }
-        if (AuthorityChecker.SUPER_USER.equals(userName)) {
+        if (hasGlobalPrivilege(userName, PrivilegeType.SECURITY)) {
           return;
         }
         for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java
index 86caed88ebc..369675243f2 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java
@@ -134,6 +134,7 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.sys.ShowVersionStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.TestConnectionStatement;
+import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 
 import com.google.common.collect.ImmutableList;
@@ -358,7 +359,7 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
               false, "Cannot create user has same name with admin user");
         }
         if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
         return AuthorityChecker.getTSStatus(
             AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_USER),
@@ -368,7 +369,7 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
         // users can change passwords of themselves
         if (AuthorityChecker.SUPER_USER.equals(context.userName)
             || statement.getUserName().equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
         return AuthorityChecker.getTSStatus(
             AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_USER),
@@ -380,24 +381,24 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
           return AuthorityChecker.getTSStatus(false, "Cannot drop admin user 
or yourself");
         }
         if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
         return AuthorityChecker.getTSStatus(
             AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_USER),
             PrivilegeType.MANAGE_USER);
 
       case LIST_USER:
-        if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+        if (AuthorityChecker.SUPER_USER.equals(context.userName)
+            || AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.SECURITY)) {
+          return RpcUtils.SUCCESS_STATUS;
         }
-        return AuthorityChecker.getTSStatus(
-            AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_USER),
-            PrivilegeType.MANAGE_USER);
+        statement.setUserName(context.userName);
+        return RpcUtils.SUCCESS_STATUS;
 
       case LIST_USER_PRIVILEGE:
         if (AuthorityChecker.SUPER_USER.equals(context.userName)
             || context.userName.equals(statement.getUserName())) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
         return AuthorityChecker.getTSStatus(
             AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_USER),
@@ -405,27 +406,28 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
 
       case LIST_ROLE_PRIVILEGE:
         if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
         if (!AuthorityChecker.checkRole(context.userName, 
statement.getRoleName())) {
           return AuthorityChecker.getTSStatus(
               AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_ROLE),
               PrivilegeType.MANAGE_ROLE);
         } else {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
 
       case LIST_ROLE:
-        if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+        if (AuthorityChecker.SUPER_USER.equals(context.userName)
+            || AuthorityChecker.checkSystemPermission(
+                context.userName, PrivilegeType.MANAGE_ROLE)) {
+          return RpcUtils.SUCCESS_STATUS;
         }
-        if (statement.getUserName() != null && 
context.userName.equals(statement.getUserName())) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
-        } else {
-          return AuthorityChecker.getTSStatus(
-              AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_ROLE),
-              PrivilegeType.MANAGE_ROLE);
+        // list roles of other user is not allowed
+        if (statement.getUserName() != null && 
!statement.getUserName().equals(context.userName)) {
+          return AuthorityChecker.getTSStatus(false, 
PrivilegeType.MANAGE_ROLE);
         }
+        statement.setUserName(context.userName);
+        return RpcUtils.SUCCESS_STATUS;
 
       case CREATE_ROLE:
         if (AuthorityChecker.SUPER_USER.equals(statement.getRoleName())) {
@@ -436,7 +438,7 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
       case GRANT_USER_ROLE:
       case REVOKE_USER_ROLE:
         if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+          return RpcUtils.SUCCESS_STATUS;
         }
         return AuthorityChecker.getTSStatus(
             AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.MANAGE_ROLE),
@@ -450,8 +452,9 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
           return AuthorityChecker.getTSStatus(
               false, "Cannot grant/revoke privileges of admin user");
         }
-        if (AuthorityChecker.SUPER_USER.equals(context.userName)) {
-          return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+        if (AuthorityChecker.SUPER_USER.equals(context.userName)
+            || AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.SECURITY)) {
+          return RpcUtils.SUCCESS_STATUS;
         }
 
         for (String s : statement.getPrivilegeList()) {
@@ -479,7 +482,7 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
                 false, "Not support Relation statement in tree sql_dialect");
           }
         }
-        return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+        return RpcUtils.SUCCESS_STATUS;
       default:
         throw new IllegalArgumentException("Unknown authorType: " + 
authorType);
     }
@@ -1066,8 +1069,8 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
   // ======================== TTL related ===========================
   @Override
   public TSStatus visitSetTTL(SetTTLStatement statement, 
TreeAccessCheckContext context) {
-    if 
(AuthorityChecker.checkSuperUserOrSystemAdmin(context.userName).getCode()
-        == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+    if (AuthorityChecker.SUPER_USER.equals(context.userName)
+        || AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.SYSTEM)) {
       return SUCCEED;
     }
     List<PartialPath> checkedPaths = statement.getPaths();
@@ -1080,8 +1083,8 @@ public class TreeAccessCheckVisitor extends 
StatementVisitor<TSStatus, TreeAcces
 
   @Override
   public TSStatus visitShowTTL(ShowTTLStatement showTTLStatement, 
TreeAccessCheckContext context) {
-    if 
(AuthorityChecker.checkSuperUserOrSystemAdmin(context.userName).getCode()
-        == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+    if (AuthorityChecker.SUPER_USER.equals(context.userName)
+        || AuthorityChecker.checkSystemPermission(context.userName, 
PrivilegeType.SYSTEM)) {
       return SUCCEED;
     }
     return visitAuthorityInformation(showTTLStatement, context);

Reply via email to