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);