This is an automated email from the ASF dual-hosted git repository. yongzao pushed a commit to branch rename-user-sql in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 2f7d29abe5a23cf1b826522be8daa6676f8bf033 Author: Yongzao <[email protected]> AuthorDate: Sun Sep 28 17:06:44 2025 +0800 ready 4 adding tests --- .../java/org/apache/iotdb/db/auth/BasicAuthorityCache.java | 3 +++ .../org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java | 6 ++++-- .../plan/execution/config/TreeConfigTaskVisitor.java | 10 ++++++++++ .../plan/relational/security/AccessControlImpl.java | 13 ++++++++++++- .../plan/relational/security/TreeAccessCheckVisitor.java | 10 +++++----- .../plan/relational/sql/ast/RelationalAuthorStatement.java | 10 ++++++++++ .../queryengine/plan/relational/sql/parser/AstBuilder.java | 8 ++++++++ 7 files changed, 52 insertions(+), 8 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java index bcff1df36b8..b90469b6f70 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java @@ -60,6 +60,9 @@ public class BasicAuthorityCache implements IAuthorCache { @Override public void putUserCache(String userName, User user) { + if (user.getUserId() == AuthorityChecker.SUPER_USER_ID) { + AuthorityChecker.setSuperUser(user.getName()); + } userCache.put(userName, user); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java index 955558eeec9..feea7d5f6ff 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java @@ -711,7 +711,8 @@ public class ClusterAuthorityFetcher implements IAuthorityFetcher { AuthUtils.strToPermissions(authorStatement.getPrivilegeList()), authorStatement.getGrantOpt(), AuthUtils.serializePartialPathList(authorStatement.getNodeNameList()), - authorStatement.getExecutedByUserId()); + authorStatement.getExecutedByUserId(), + authorStatement.getNewUsername()); } private TAuthorizerRelationalReq statementToAuthorizerReq( @@ -727,6 +728,7 @@ public class ClusterAuthorityFetcher implements IAuthorityFetcher { ? Collections.emptySet() : authorStatement.getPrivilegeIds(), authorStatement.isGrantOption(), - authorStatement.getExecutedByUserId()); + authorStatement.getExecutedByUserId(), + authorStatement.getNewUsername()); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java index 93843b579fc..fd838c71cac 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java @@ -315,6 +315,9 @@ public class TreeConfigTaskVisitor extends StatementVisitor<IConfigTask, MPPQuer if (statement.getAuthorType() == AuthorType.UPDATE_USER) { visitUpdateUser(statement); } + if (statement.getAuthorType() == AuthorType.RENAME_USER) { + visitRenameUser(statement); + } TSStatus status = statement.checkStatementIsValid(context.getSession().getUserName()); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { throw new AccessDeniedException(status.getMessage()); @@ -331,6 +334,13 @@ public class TreeConfigTaskVisitor extends StatementVisitor<IConfigTask, MPPQuer DataNodeAuthUtils.verifyPasswordReuse(statement.getUserName(), statement.getNewPassword()); } + private void visitRenameUser(AuthorStatement statement) { + User user = AuthorityChecker.getAuthorityFetcher().getUser(statement.getUserName()); + if (user == null) { + throw new SemanticException("User " + statement.getUserName() + " not found"); + } + } + @Override public IConfigTask visitMerge(MergeStatement mergeStatement, MPPQueryContext context) { return new MergeTask(mergeStatement); 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 4157d259a0a..a33c38037bb 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 @@ -252,7 +252,6 @@ public class AccessControlImpl implements AccessControl { switch (type) { case CREATE_USER: case DROP_USER: - case UPDATE_USER: auditEntity .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.SECURITY); @@ -262,6 +261,18 @@ public class AccessControlImpl implements AccessControl { } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); return; + case RENAME_USER: + case UPDATE_USER: + auditEntity.setAuditLogOperation(AuditLogOperation.DDL); + // users can change the username and password of themselves + // the superuser can affect anyone + if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId() + || statement.getUserName().equals(userName)) { + ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName); + return; + } + authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); + return; case LIST_USER_PRIV: auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) 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 c3ce4c6803d..1a97456d784 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 @@ -517,18 +517,18 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces PrivilegeType.MANAGE_USER, statement::getUserName); case UPDATE_USER: - // users can change passwords of themselves + case RENAME_USER: + context.setAuditLogOperation(AuditLogOperation.DDL); + // users can change the username and password of themselves if (statement.getUserName().equals(context.getUsername())) { + recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; } - context - .setAuditLogOperation(AuditLogOperation.DDL) - .setPrivilegeType(PrivilegeType.SECURITY); + context.setPrivilegeType(PrivilegeType.SECURITY); return checkGlobalAuth( context.setAuditLogOperation(AuditLogOperation.DDL), PrivilegeType.MANAGE_USER, statement::getUserName); - case LIST_USER: context .setAuditLogOperation(AuditLogOperation.QUERY) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java index ed970393538..b7929ae13c9 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java @@ -54,6 +54,7 @@ public class RelationalAuthorStatement extends Statement { private boolean grantOption; private long executedByUserId; + private String newUsername; public RelationalAuthorStatement( AuthorRType authorType, @@ -174,6 +175,14 @@ public class RelationalAuthorStatement extends Statement { this.executedByUserId = executedByUserId; } + public String getNewUsername() { + return newUsername; + } + + public void setNewUsername(String newUsername) { + this.newUsername = newUsername; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -234,6 +243,7 @@ public class RelationalAuthorStatement extends Statement { case REVOKE_ROLE_SYS: case REVOKE_USER_SYS: case REVOKE_USER_ROLE: + case RENAME_USER: return QueryType.WRITE; case LIST_ROLE: case LIST_USER: diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java index 43de4fcc77d..8f859ffe6f7 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java @@ -1741,6 +1741,14 @@ public class AstBuilder extends RelationalSqlBaseVisitor<Node> { return stmt; } + @Override + public Node visitRenameUserStatement(RelationalSqlParser.RenameUserStatementContext ctx) { + RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.RENAME_USER); + stmt.setUserName(((Identifier) visit(ctx.username)).getValue()); + stmt.setNewUsername(((Identifier) visit(ctx.newUsername)).getValue()); + return stmt; + } + @Override public Node visitGrantUserRoleStatement(RelationalSqlParser.GrantUserRoleStatementContext ctx) { RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.GRANT_USER_ROLE);
