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

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new 4864a922 fix(acl): allow clearing whiteRemoteAddress via update 
wrapper (#1637)
4864a922 is described below

commit 4864a922a24f77199f38ddcc0b0c9f1f3ce3cc08
Author: youngkermit8-coder <[email protected]>
AuthorDate: Tue Aug 11 20:42:52 2026 +0800

    fix(acl): allow clearing whiteRemoteAddress via update wrapper (#1637)
    
    Signed-off-by: youngkermit8-coder <[email protected]>
---
 .../instance/acl/MybatisPlusAclRepository.java     |  8 +++++++
 .../instance/acl/MybatisPlusAclRepositoryTest.java | 27 ++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
 
b/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
index 42f3f781..f8243b72 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
@@ -17,6 +17,7 @@
 package org.apache.rocketmq.studio.instance.acl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import org.apache.rocketmq.studio.common.exception.BusinessException;
 import org.apache.rocketmq.studio.common.util.CredentialUtils;
 import org.apache.rocketmq.studio.persistence.entity.RmqAclRule;
@@ -176,6 +177,13 @@ public class MybatisPlusAclRepository implements 
AclRepository {
         entity.setUpdatedAt(LocalDateTime.now());
         if (existing != null) {
             userMapper.updateById(entity);
+            if (entity.getWhiteRemoteAddress() == null) {
+                // MyBatis-Plus omits null entity fields from updateById. 
Assign this column
+                // explicitly so clearing the whitelist does not silently 
retain its old value.
+                userMapper.update(null, new UpdateWrapper<RmqAclUser>()
+                        .eq("id", entity.getId())
+                        .set("white_remote_address", null));
+            }
         } else {
             userMapper.insert(entity);
         }
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
index 5eaf35db..9365c246 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
@@ -17,6 +17,7 @@
 package org.apache.rocketmq.studio.instance.acl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import org.apache.rocketmq.studio.common.exception.BusinessException;
 import org.apache.rocketmq.studio.common.util.CredentialUtils;
 import org.apache.rocketmq.studio.persistence.entity.RmqAclRule;
@@ -38,6 +39,7 @@ import java.util.List;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -187,6 +189,31 @@ class MybatisPlusAclRepositoryTest {
         assertThat(captor.getValue().getWhiteRemoteAddress()).isNull();
     }
 
+    @Test
+    void updateShouldExplicitlyClearBlankWhiteRemoteAddress() {
+        RmqAclUser existing = userEntity("plain-svc-x", "svc-x",
+                CredentialUtils.encodeBase64("kept-secret-value"));
+        existing.setWhiteRemoteAddress("10.0.1.0/24");
+        
when(userMapper.selectOne(any(QueryWrapper.class))).thenReturn(existing);
+        when(userMapper.updateById(any(RmqAclUser.class))).thenReturn(1);
+        when(userMapper.update(isNull(), 
any(UpdateWrapper.class))).thenReturn(1);
+        when(ruleMapper.delete(any(QueryWrapper.class))).thenReturn(0);
+
+        PlainAccessConfigVO config = PlainAccessConfigVO.builder()
+                .accessKey("svc-x")
+                .whiteRemoteAddress("   ")
+                .build();
+
+        PlainAccessConfigVO result = 
repository.createAndUpdatePlainAccessConfig(config);
+
+        @SuppressWarnings("rawtypes")
+        ArgumentCaptor<UpdateWrapper> captor = 
ArgumentCaptor.forClass(UpdateWrapper.class);
+        verify(userMapper).update(isNull(), captor.capture());
+        
assertThat(captor.getValue().getSqlSet()).contains("white_remote_address");
+        
assertThat(captor.getValue().getParamNameValuePairs()).containsValue(null);
+        assertThat(result.getWhiteRemoteAddress()).isNull();
+    }
+
     @Test
     void examineShouldMaskAccountSecrets() {
         String plaintext = "supersecret-abcdef";

Reply via email to