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

morningman pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 7985a726422 branch-4.0:[enhance](nereids) improve masking of user's 
password for ALTER USER and CREATE USER commands in audit logs #62141 (#64717)
7985a726422 is described below

commit 7985a7264226c87e23ca507ec79bcc1d5fc78573
Author: feiniaofeiafei <[email protected]>
AuthorDate: Wed Jun 24 10:51:40 2026 +0800

    branch-4.0:[enhance](nereids) improve masking of user's password for ALTER 
USER and CREATE USER commands in audit logs #62141 (#64717)
    
    picked from #62141
    
    ---------
    
    Co-authored-by: iaorekhov-1980 <[email protected]>
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |  2 +-
 .../parser/LogicalPlanBuilderForEncryption.java    | 10 ++++
 .../trees/plans/commands/AlterUserCommand.java     |  7 ++-
 .../doris/nereids/parser/EncryptSQLTest.java       | 68 ++++++++++++++++++++++
 4 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index bc5d00304e0..6c991fffd89 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -1111,7 +1111,7 @@ userIdentify
     ;
 
 grantUserIdentify
-    : userIdentify (IDENTIFIED BY PASSWORD? STRING_LITERAL)?
+    : userIdentify (IDENTIFIED BY PASSWORD? pwd=STRING_LITERAL)?
     ;
 
 explain
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilderForEncryption.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilderForEncryption.java
index 3c9eea1d386..4a73424eb06 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilderForEncryption.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilderForEncryption.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.parser;
 
 import org.apache.doris.analysis.BrokerDesc;
+import org.apache.doris.analysis.UserDesc;
 import org.apache.doris.common.Pair;
 import org.apache.doris.common.util.PrintableMap;
 import org.apache.doris.nereids.DorisParser;
@@ -85,6 +86,15 @@ public class LogicalPlanBuilderForEncryption extends 
LogicalPlanBuilder {
         return super.visitSetPassword(ctx);
     }
 
+    // grant user identity clause
+    @Override
+    public UserDesc 
visitGrantUserIdentify(DorisParser.GrantUserIdentifyContext ctx) {
+        if (ctx.pwd != null) {
+            encryptPassword(ctx.pwd.getStartIndex(), ctx.pwd.getStopIndex());
+        }
+        return super.visitGrantUserIdentify(ctx);
+    }
+
     // set ldap password clause
     @Override
     public SetVarOp 
visitSetLdapAdminPassword(DorisParser.SetLdapAdminPasswordContext ctx) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterUserCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterUserCommand.java
index e1bde5ac549..39765e7cc63 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterUserCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterUserCommand.java
@@ -29,7 +29,7 @@ import org.apache.doris.qe.StmtExecutor;
 /**
  * AlterUserCommand
  */
-public class AlterUserCommand extends AlterCommand {
+public class AlterUserCommand extends AlterCommand implements 
NeedAuditEncryption {
 
     private final AlterUserInfo alterUserInfo;
 
@@ -57,4 +57,9 @@ public class AlterUserCommand extends AlterCommand {
     public StmtType stmtType() {
         return StmtType.ALTER;
     }
+
+    @Override
+    public boolean needAuditEncryption() {
+        return true;
+    }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/EncryptSQLTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/EncryptSQLTest.java
index c2a39e366e3..c9398cc3bef 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/EncryptSQLTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/EncryptSQLTest.java
@@ -18,9 +18,13 @@
 package org.apache.doris.nereids.parser;
 
 import org.apache.doris.analysis.AccessTestUtil;
+import org.apache.doris.analysis.StatementBase;
+import org.apache.doris.analysis.UserIdentity;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.jmockit.Deencapsulation;
+import org.apache.doris.common.profile.Profile;
+import org.apache.doris.nereids.StatementContext;
 import org.apache.doris.plugin.AuditEvent;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.MysqlConnectProcessor;
@@ -31,6 +35,8 @@ import mockit.Mock;
 import mockit.MockUp;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.mockito.MockedConstruction;
+import org.mockito.Mockito;
 
 import java.util.List;
 
@@ -407,6 +413,68 @@ public class EncryptSQLTest extends ParserTestBase {
         Assertions.assertTrue(event.errorMessage.contains(errorMsg));
     }
 
+    @Test
+    public void testCreateUserPasswordMasking() throws Exception {
+        ctx.setDatabase("test");
+        try (MockedConstruction<StmtExecutor> ignored = 
Mockito.mockConstruction(StmtExecutor.class,
+                
Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS),
+                (mock, context) -> {
+                    Mockito.doReturn(false).when(mock).isForwardToMaster();
+                    Profile profile = new Profile(false, 0, 0);
+                    Deencapsulation.setField(mock, "profile", profile);
+                    Mockito.doReturn(profile).when(mock).getProfile();
+                    Mockito.doReturn(ctx).when(mock).getContext();
+                    Mockito.doNothing().when(mock).execute();
+                    Deencapsulation.setField(mock, "context", ctx);
+                    if (context.arguments().size() >= 2
+                            && context.arguments().get(1) instanceof 
StatementBase) {
+                        Deencapsulation.setField(mock, "parsedStmt",
+                                context.arguments().get(1));
+                    }
+                    if (ctx.getStatementContext() == null) {
+                        ctx.setStatementContext(new StatementContext());
+                    }
+                })) {
+            ctx.setEnv(env);
+            ctx.setCurrentUserIdentity(UserIdentity.ROOT);
+            // testing for https://github.com/apache/doris/issues/62140
+            String sql = "CREATE USER 'test_user62140'@'%' IDENTIFIED BY 
'123456'";
+            String res = "CREATE USER 'test_user62140'@'%' IDENTIFIED BY 
'*XXX'";
+            parseAndCheck(sql, res);
+        }
+    }
+
+    @Test
+    public void testAlterUserPasswordMasking() throws Exception {
+        ctx.setDatabase("test");
+        try (MockedConstruction<StmtExecutor> ignored = 
Mockito.mockConstruction(StmtExecutor.class,
+                
Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS),
+                (mock, context) -> {
+                    Mockito.doReturn(false).when(mock).isForwardToMaster();
+                    Profile profile = new Profile(false, 0, 0);
+                    Deencapsulation.setField(mock, "profile", profile);
+                    Mockito.doReturn(profile).when(mock).getProfile();
+                    Mockito.doReturn(ctx).when(mock).getContext();
+                    Mockito.doNothing().when(mock).execute();
+                    Deencapsulation.setField(mock, "context", ctx);
+                    if (context.arguments().size() >= 2
+                            && context.arguments().get(1) instanceof 
StatementBase) {
+                        Deencapsulation.setField(mock, "parsedStmt",
+                                context.arguments().get(1));
+                    }
+                    if (ctx.getStatementContext() == null) {
+                        ctx.setStatementContext(new StatementContext());
+                    }
+                })) {
+            ctx.setEnv(env);
+            ctx.setCurrentUserIdentity(UserIdentity.ROOT);
+            // testing for https://github.com/apache/doris/issues/62140
+            String sql = "ALTER USER 'test_user62140'@'%' IDENTIFIED BY 
'123456'";
+            String res = "ALTER USER 'test_user62140'@'%' IDENTIFIED BY 
'*XXX'";
+            parseAndCheck(sql, res);
+        }
+    }
+
     private void parseAndCheck(String sql, String expected) throws Exception {
         processor.executeQuery(sql);
         AuditEvent event = auditEvents.get(auditEvents.size() - 1);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to