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 359f70550ea888e463a08e4f54b0a7bd66879bd7 Author: Yongzao <[email protected]> AuthorDate: Sun Sep 28 16:23:30 2025 +0800 commit 4 cp --- .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 7 ++- .../consensus/request/ConfigPhysicalPlanType.java | 4 +- .../consensus/request/write/auth/AuthorPlan.java | 13 ++++- .../request/write/auth/AuthorRelationalPlan.java | 12 ++++- .../request/write/auth/AuthorTreePlan.java | 12 ++++- .../persistence/auth/AuthorPlanExecutor.java | 7 +++ .../persistence/executor/ConfigPlanExecutor.java | 2 + .../thrift/ConfigNodeRPCServiceProcessor.java | 58 +++++++++++++--------- .../plan/relational/type/AuthorRType.java | 4 +- .../db/queryengine/plan/statement/AuthorType.java | 6 +++ .../plan/statement/sys/AuthorStatement.java | 1 + .../commons/auth/authorizer/BasicAuthorizer.java | 5 ++ .../iotdb/commons/auth/authorizer/IAuthorizer.java | 9 ++++ .../commons/auth/authorizer/OpenIdAuthorizer.java | 5 ++ .../iotdb/commons/auth/user/BasicUserManager.java | 21 ++++++++ .../db/relational/grammar/sql/RelationalSql.g4 | 5 ++ .../src/main/thrift/confignode.thrift | 2 + 17 files changed, 141 insertions(+), 32 deletions(-) diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 index 3095adba3f6..8d75981f41a 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 @@ -81,7 +81,7 @@ dmlStatement ; dclStatement - : createUser | createRole | alterUser | grantUser | grantRole | grantRoleToUser + : createUser | createRole | alterUser | renameUser | grantUser | grantRole | grantRoleToUser | revokeUser | revokeRole | revokeRoleFromUser | dropUser | dropRole | listUser | listRole | listPrivilegesUser | listPrivilegesRole ; @@ -1059,6 +1059,11 @@ alterUser : ALTER USER userName=usernameWithRoot SET PASSWORD password=STRING_LITERAL ; +// Rename user +renameUser + : ALTER USER username=usernameWithRoot RENAME TO newUsername=identifier + ; + // Grant User Privileges grantUser : GRANT privileges ON prefixPath (COMMA prefixPath)* TO USER userName=identifier (grantOpt)? diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java index f174352e411..dee820d825d 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java @@ -319,11 +319,13 @@ public enum ConfigPhysicalPlanType { ShowSubscription((short) 2000), + // Authority version after and equal 2.0 DropUserV2((short) 2100), UpdateUserV2((short) 2101), - RUpdateUserV2((short) 2102), RDropUserV2((short) 2103), + RenameUser((short) 2104), + RRenameUser((short) 2105), EnableSeparationOfAdminPowers((short) 2200), diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorPlan.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorPlan.java index a0090e19af6..ba39e8871d3 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorPlan.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorPlan.java @@ -33,6 +33,7 @@ public abstract class AuthorPlan extends ConfigPhysicalReadPlan { protected boolean grantOpt; protected int maxSessionPerUser; protected int minSessionPerUser; + protected String newUsername = ""; // Used for read plans or some write plans whose type name ends with 'V2' protected long executedByUserId; @@ -122,6 +123,10 @@ public abstract class AuthorPlan extends ConfigPhysicalReadPlan { this.userName = userName; } + public String getNewUsername() { + return newUsername; + } + public long getExecutedByUserId() { return executedByUserId; } @@ -144,12 +149,14 @@ public abstract class AuthorPlan extends ConfigPhysicalReadPlan { && Objects.equals(roleName, that.roleName) && Objects.equals(password, that.password) && Objects.equals(newPassword, that.newPassword) - && grantOpt == that.grantOpt; + && grantOpt == that.grantOpt + && Objects.equals(newUsername, that.newUsername); } @Override public int hashCode() { - return Objects.hash(super.getType(), userName, roleName, password, newPassword, grantOpt); + return Objects.hash( + super.getType(), userName, roleName, password, newPassword, grantOpt, newUsername); } @Override @@ -162,6 +169,8 @@ public abstract class AuthorPlan extends ConfigPhysicalReadPlan { + roleName + ", grant option:" + grantOpt + + ", new username:" + + newUsername + "]"; } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorRelationalPlan.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorRelationalPlan.java index 93459018653..c418aa70b4e 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorRelationalPlan.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorRelationalPlan.java @@ -85,7 +85,7 @@ public class AuthorRelationalPlan extends AuthorPlan { permissions, grantOpt, password, - 0); + 0, ""); } public AuthorRelationalPlan( @@ -97,13 +97,15 @@ public class AuthorRelationalPlan extends AuthorPlan { final Set<Integer> permissions, final boolean grantOpt, final String password, - final long executedByUserId) { + final long executedByUserId, + final String newUsername) { super(authorType, userName, roleName, password, "", grantOpt, -1, -1); this.databaseName = databaseName; this.tableName = tableName; this.permissions = permissions; this.executedByUserId = executedByUserId; + this.newUsername = newUsername; } public AuthorRelationalPlan( @@ -196,6 +198,9 @@ public class AuthorRelationalPlan extends AuthorPlan { BasicStructureSerDeUtil.write(maxSessionPerUser, stream); BasicStructureSerDeUtil.write(minSessionPerUser, stream); } + if (authorType == ConfigPhysicalPlanType.RRenameUser) { + BasicStructureSerDeUtil.write(newUsername, stream); + } if (authorType == ConfigPhysicalPlanType.RDropUserV2 || authorType == ConfigPhysicalPlanType.RUpdateUserV2) { BasicStructureSerDeUtil.write(executedByUserId, stream); @@ -221,6 +226,9 @@ public class AuthorRelationalPlan extends AuthorPlan { maxSessionPerUser = buffer.getInt(); minSessionPerUser = buffer.getInt(); } + if (authorType == ConfigPhysicalPlanType.RRenameUser) { + newUsername = BasicStructureSerDeUtil.readString(buffer); + } if (authorType == ConfigPhysicalPlanType.RDropUserV2 || authorType == ConfigPhysicalPlanType.RUpdateUserV2) { executedByUserId = buffer.getLong(); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorTreePlan.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorTreePlan.java index 146faea75be..4df7aa89658 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorTreePlan.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/auth/AuthorTreePlan.java @@ -108,7 +108,7 @@ public class AuthorTreePlan extends AuthorPlan { permissions, grantOpt, nodeNameList, - 0); + 0, ""); } public AuthorTreePlan( @@ -120,11 +120,13 @@ public class AuthorTreePlan extends AuthorPlan { final Set<Integer> permissions, final boolean grantOpt, final List<PartialPath> nodeNameList, - final long executedByUserId) { + final long executedByUserId, + final String newUsername) { super(authorType, userName, roleName, password, newPassword, grantOpt, -1, -1); this.permissions = permissions; this.nodeNameList = nodeNameList; this.executedByUserId = executedByUserId; + this.newUsername = newUsername; } public Set<Integer> getPermissions() { @@ -193,6 +195,9 @@ public class AuthorTreePlan extends AuthorPlan { BasicStructureSerDeUtil.write(maxSessionPerUser, stream); BasicStructureSerDeUtil.write(minSessionPerUser, stream); } + if (authorType == ConfigPhysicalPlanType.RenameUser) { + BasicStructureSerDeUtil.write(newUsername, stream); + } if (authorType == ConfigPhysicalPlanType.DropUserV2 || authorType == ConfigPhysicalPlanType.UpdateUserV2) { BasicStructureSerDeUtil.write(executedByUserId, stream); @@ -225,6 +230,9 @@ public class AuthorTreePlan extends AuthorPlan { maxSessionPerUser = buffer.getInt(); minSessionPerUser = buffer.getInt(); } + if (authorType == ConfigPhysicalPlanType.RenameUser) { + newUsername = BasicStructureSerDeUtil.readString(buffer); + } if (authorType == ConfigPhysicalPlanType.DropUserV2 || authorType == ConfigPhysicalPlanType.UpdateUserV2) { executedByUserId = buffer.getLong(); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/auth/AuthorPlanExecutor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/auth/AuthorPlanExecutor.java index 69bb5779abc..dd271090396 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/auth/AuthorPlanExecutor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/auth/AuthorPlanExecutor.java @@ -123,12 +123,16 @@ public class AuthorPlanExecutor implements IAuthorPlanExecutor { Set<Integer> permissions = authorPlan.getPermissions(); boolean grantOpt = authorPlan.getGrantOpt(); List<PartialPath> nodeNameList = authorPlan.getNodeNameList(); + String newUsername = authorPlan.getNewUsername(); try { switch (authorType) { case UpdateUser: case UpdateUserV2: authorizer.updateUserPassword(userName, newPassword); break; + case RenameUser: + authorizer.renameUser(userName, newUsername); + break; case CreateUser: authorizer.createUser(userName, password); break; @@ -241,6 +245,9 @@ public class AuthorPlanExecutor implements IAuthorPlanExecutor { case RUpdateUserV2: authorizer.updateUserPassword(userName, authorPlan.getPassword()); break; + case RRenameUser: + authorizer.renameUser(userName, roleName); + break; case RDropRole: authorizer.deleteRole(roleName); break; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java index 41d459a9c3b..aa3504ac6d6 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java @@ -483,6 +483,7 @@ public class ConfigPlanExecutor { case RevokeRoleDep: case RevokeRoleFromUserDep: case UpdateUserDep: + case RenameUser: case RCreateRole: case RCreateUser: case RDropUser: @@ -514,6 +515,7 @@ public class ConfigPlanExecutor { case RRevokeRoleSysPri: case RRevokeRoleTBPriv: case RRevokeUserRole: + case RRenameUser: return authorInfo.authorNonQuery((AuthorPlan) physicalPlan); case ApplyConfigNode: return nodeInfo.applyConfigNode((ApplyConfigNodePlan) physicalPlan); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java index 8b206558080..3d577bcdb1a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java @@ -635,16 +635,20 @@ public class ConfigNodeRPCServiceProcessor implements IConfigNodeRPCService.Ifac if (req.getAuthorType() < 0 || req.getAuthorType() >= AuthorType.values().length) { throw new IndexOutOfBoundsException("Invalid Author Type ordinal"); } - ConfigPhysicalPlanType configPhysicalPlanType = - ConfigPhysicalPlanType.values()[ - req.getAuthorType() + ConfigPhysicalPlanType.CreateUser.ordinal()]; - switch (configPhysicalPlanType) { - case UpdateUser: - configPhysicalPlanType = ConfigPhysicalPlanType.UpdateUserV2; - break; - case DropUser: - configPhysicalPlanType = ConfigPhysicalPlanType.DropUserV2; - break; + ConfigPhysicalPlanType configPhysicalPlanType; + if (req.getAuthorType() == AuthorType.RENAME_USER.ordinal()) { + configPhysicalPlanType = ConfigPhysicalPlanType.RenameUser; + } else {configPhysicalPlanType + =ConfigPhysicalPlanType.values()[ + req.getAuthorType() + ConfigPhysicalPlanType.CreateUser.ordinal()]; + switch (configPhysicalPlanType) { + case UpdateUser: + configPhysicalPlanType = ConfigPhysicalPlanType.UpdateUserV2; + break; + case DropUser: + configPhysicalPlanType = ConfigPhysicalPlanType.DropUserV2; + break; + } } return configManager.operatePermission( new AuthorTreePlan( @@ -656,7 +660,8 @@ public class ConfigNodeRPCServiceProcessor implements IConfigNodeRPCService.Ifac req.getPermissions(), req.isGrantOpt(), AuthUtils.deserializePartialPathList(ByteBuffer.wrap(req.getNodeNameList())), - req.getExecutedByUserID())); + req.getExecutedByUserID(), + req.getNewUsername())); } @Override @@ -677,7 +682,7 @@ public class ConfigNodeRPCServiceProcessor implements IConfigNodeRPCService.Ifac req.getPermissions(), req.isGrantOpt(), AuthUtils.deserializePartialPathList(ByteBuffer.wrap(req.getNodeNameList())), - req.getExecutedByUserID())); + req.getExecutedByUserID(), req.getNewUsername())); final TAuthorizerResp resp = new TAuthorizerResp(dataSet.getStatus()); resp.setMemberInfo(dataSet.getMemberList()); resp.setPermissionInfo(dataSet.getPermissionInfoResp()); @@ -691,16 +696,22 @@ public class ConfigNodeRPCServiceProcessor implements IConfigNodeRPCService.Ifac if (req.getAuthorType() < 0 || req.getAuthorType() >= AuthorRType.values().length) { throw new IndexOutOfBoundsException("Invalid Author Type ordinal"); } - ConfigPhysicalPlanType configPhysicalPlanType = - ConfigPhysicalPlanType.values()[ - req.getAuthorType() + ConfigPhysicalPlanType.RCreateUser.ordinal()]; - switch (configPhysicalPlanType) { - case RUpdateUser: - configPhysicalPlanType = ConfigPhysicalPlanType.RUpdateUserV2; - break; - case RDropUser: - configPhysicalPlanType = ConfigPhysicalPlanType.RDropUserV2; - break; + ConfigPhysicalPlanType configPhysicalPlanType; + if (req.getAuthorType() == AuthorRType.RENAME_USER.ordinal()) { + configPhysicalPlanType = ConfigPhysicalPlanType.RRenameUser; + } else { + configPhysicalPlanType + = + ConfigPhysicalPlanType.values()[ + req.getAuthorType() + ConfigPhysicalPlanType.RCreateUser.ordinal()]; + switch (configPhysicalPlanType) { + case RUpdateUser: + configPhysicalPlanType = ConfigPhysicalPlanType.RUpdateUserV2; + break; + case RDropUser: + configPhysicalPlanType = ConfigPhysicalPlanType.RDropUserV2; + break; + } } return configManager.operatePermission( new AuthorRelationalPlan( @@ -712,7 +723,8 @@ public class ConfigNodeRPCServiceProcessor implements IConfigNodeRPCService.Ifac req.getPermissions(), req.isGrantOpt(), req.getPassword(), - req.getExecutedByUserID())); + req.getExecutedByUserID(), + req.getNewUsername())); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/type/AuthorRType.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/type/AuthorRType.java index 1cac0e1bacb..8bbff6a718c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/type/AuthorRType.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/type/AuthorRType.java @@ -49,5 +49,7 @@ public enum AuthorRType { LIST_USER, LIST_ROLE, LIST_USER_PRIV, - LIST_ROLE_PRIV + LIST_ROLE_PRIV, + // Remind to renew the convert codes in ConfigNodeRPCServiceProcessor + RENAME_USER, } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/AuthorType.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/AuthorType.java index 07ba1ecf795..3e3ad61fcd7 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/AuthorType.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/AuthorType.java @@ -35,6 +35,8 @@ public enum AuthorType { LIST_ROLE, LIST_USER_PRIVILEGE, LIST_ROLE_PRIVILEGE, + // Remind to renew the convert codes in ConfigNodeRPCServiceProcessor + RENAME_USER, ; /** @@ -75,6 +77,8 @@ public enum AuthorType { return LIST_USER_PRIVILEGE; case 14: return LIST_ROLE_PRIVILEGE; + case 15: + return RENAME_USER; default: return null; } @@ -117,6 +121,8 @@ public enum AuthorType { return 13; case LIST_ROLE_PRIVILEGE: return 14; + case RENAME_USER: + return 15; default: return -1; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java index 09336734c48..cbbbcd38698 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java @@ -48,6 +48,7 @@ public class AuthorStatement extends Statement implements IConfigStatement { private List<PartialPath> nodeNameList; private boolean grantOpt; private long executedByUserId; + private String newUsername; /** * Constructor with AuthorType. diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java index de800b2be56..ac86ae8d9fc 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java @@ -318,6 +318,11 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService { } } + @Override + public void renameUser(String username, String newUsername) throws AuthException { + userManager.renameUser(username, newUsername); + } + private void forceUpdateUserPassword(String userName, String newPassword) throws AuthException { if (!userManager.updateUserPassword(userName, newPassword, true)) { throw new AuthException( diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java index 52b8ad4e0f4..2745318b69d 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java @@ -167,6 +167,15 @@ public interface IAuthorizer extends SnapshotProcessor { */ void updateUserPassword(String userName, String newPassword) throws AuthException; + /** + * Rename the specified user. + * + * @param username The original name of the specified user. + * @param newUsername The new name to be specified. + * @throws AuthException If the original name does not exist or the new name is already existed. + */ + void renameUser(String username, String newUsername) throws AuthException; + /** * Check if the user have the privilege or grant option on the target. * diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/OpenIdAuthorizer.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/OpenIdAuthorizer.java index 38199adf98f..e1f73260dc3 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/OpenIdAuthorizer.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/OpenIdAuthorizer.java @@ -262,4 +262,9 @@ public class OpenIdAuthorizer extends BasicAuthorizer { public void updateUserPassword(String userName, String newPassword) { throwUnsupportedOperationException(); } + + @Override + public void renameUser(String username, String newUsername) { + throwUnsupportedOperationException(); + } } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java index 0d67aa21b76..c335896c6d2 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java @@ -229,6 +229,27 @@ public abstract class BasicUserManager extends BasicRoleManager { } } + public void renameUser(String username, String newUsername) throws AuthException { + User user = this.getEntity(username); + if (user == null) { + throw new AuthException( + getEntityNotExistErrorCode(), String.format(getNoSuchEntityError(), username)); + } + User tmpUser = this.getEntity(newUsername); + if (tmpUser != null) { + throw new AuthException( + TSStatusCode.USER_ALREADY_EXIST, String.format("Cannot rename user %s to %s, because the target username is already existed.", + username, newUsername + )); + } + lock.writeLock(username); + try { + entityMap.get(username).setName(newUsername); + } finally { + lock.writeUnlock(username); + } + } + public void grantRoleToUser(String roleName, String username) throws AuthException { lock.writeLock(username); try { diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 index 38a461c93f6..24a652fbd12 100644 --- a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 +++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 @@ -157,6 +157,7 @@ statement | grantUserRoleStatement | revokeUserRoleStatement | alterUserStatement + | renameUserStatement | listUserPrivilegeStatement | listRolePrivilegeStatement | listUserStatement @@ -708,6 +709,10 @@ alterUserStatement : ALTER USER userName=identifier SET PASSWORD password=string ; +renameUserStatement + : ALTER USER username=identifier RENAME TO newUsername=identifier + ; + grantUserRoleStatement : GRANT ROLE roleName=identifier TO userName=identifier ; diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift index 8f755f08b0c..8627ddf1770 100644 --- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift +++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift @@ -353,6 +353,7 @@ struct TAuthorizerReq { 7: required bool grantOpt 8: required binary nodeNameList 9: required i64 executedByUserID + 10: required string newUsername } struct TAuthorizerRelationalReq { @@ -365,6 +366,7 @@ struct TAuthorizerRelationalReq { 7: required set<i32> permissions 8: required bool grantOpt 9: required i64 executedByUserID + 10: required string newUsername } struct TAuthorizerResp {
