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 2197a1c20 fix: bound ACL rule page sizes (#2439)
2197a1c20 is described below

commit 2197a1c201ac74866bf20dd865c1a4803c81ed5d
Author: xdz997 <[email protected]>
AuthorDate: Fri Aug 21 17:45:43 2026 +0800

    fix: bound ACL rule page sizes (#2439)
---
 .../rocketmq/studio/instance/acl/AclService.java   | 24 +++++++++++-
 .../studio/instance/acl/AclControllerTest.java     | 18 +++++++++
 .../studio/instance/acl/AclServiceTest.java        | 45 +++++++++++++++++++---
 3 files changed, 80 insertions(+), 7 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/instance/acl/AclService.java 
b/server/src/main/java/org/apache/rocketmq/studio/instance/acl/AclService.java
index 26b818cac..9bd074e60 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/instance/acl/AclService.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/instance/acl/AclService.java
@@ -46,6 +46,7 @@ public class AclService {
 
     private static final SecureRandom CREDENTIAL_RANDOM = new SecureRandom();
     private static final int DEFAULT_RULE_PAGE_SIZE = 20;
+    private static final int MAX_PAGE_SIZE = 100;
 
     private final AclRepository aclRepository;
     private final OperationAuditService operationAuditService;
@@ -70,8 +71,8 @@ public class AclService {
 
     public PageResult<AclRuleVO> listRules(String principal, String resource, 
String scope, String decision,
             String aclVersion, String instanceId, Integer page, Integer 
pageSize) {
-        int normalizedPage = normalizePage(page);
-        int normalizedPageSize = normalizePageSize(pageSize);
+        int normalizedPage = requireValidPage(page);
+        int normalizedPageSize = requireValidPageSize(pageSize);
         if (isTencentInstance(instanceId)) {
             List<AclRuleVO> filtered = tencentAclService.listRules(instanceId, 
principal).stream()
                     .filter(rule -> containsIgnoreCase(rule.getResource(), 
resource))
@@ -358,6 +359,25 @@ public class AclService {
         return pageSize == null || pageSize < 1 ? DEFAULT_RULE_PAGE_SIZE : 
pageSize;
     }
 
+    private static int requireValidPage(Integer page) {
+        if (page != null && page < 1) {
+            throw invalidPagination();
+        }
+        return normalizePage(page);
+    }
+
+    private static int requireValidPageSize(Integer pageSize) {
+        if (pageSize != null && (pageSize < 1 || pageSize > MAX_PAGE_SIZE)) {
+            throw invalidPagination();
+        }
+        return normalizePageSize(pageSize);
+    }
+
+    private static BusinessException invalidPagination() {
+        return new BusinessException(400,
+                "page must be >= 1 and pageSize must be between 1 and " + 
MAX_PAGE_SIZE);
+    }
+
     private static boolean containsIgnoreCase(String value, String 
expectedFragment) {
         if (!StringUtils.hasText(expectedFragment)) {
             return true;
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclControllerTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclControllerTest.java
index 60d6b14e8..b72f8862b 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclControllerTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclControllerTest.java
@@ -140,6 +140,24 @@ class AclControllerTest {
                 eq("1.0"), isNull(), eq(3), eq(5));
     }
 
+    @Test
+    void listRulesShouldRejectPageSizeAboveTheInventoryLimit() throws 
Exception {
+        when(aclService.listRules(isNull(), isNull(), isNull(), isNull(), 
isNull(), isNull(),
+                eq(1), eq(101))).thenThrow(new BusinessException(400,
+                "page must be >= 1 and pageSize must be between 1 and 100"));
+
+        mockMvc.perform(get("/api/acl/rules")
+                        .param("page", "1")
+                        .param("pageSize", "101"))
+                .andExpect(status().isBadRequest())
+                .andExpect(jsonPath("$.code").value(400))
+                .andExpect(jsonPath("$.message")
+                        .value("page must be >= 1 and pageSize must be between 
1 and 100"));
+
+        verify(aclService).listRules(isNull(), isNull(), isNull(), isNull(), 
isNull(), isNull(),
+                eq(1), eq(101));
+    }
+
     @Test
     void createRuleShouldReturnCreatedRule() throws Exception {
         AclRuleVO input = AclRuleVO.builder()
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclServiceTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclServiceTest.java
index c951bdafb..b9b64d246 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclServiceTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/AclServiceTest.java
@@ -25,6 +25,7 @@ import 
org.apache.rocketmq.studio.common.domain.enums.InstanceType;
 import org.apache.rocketmq.studio.common.domain.enums.InstanceVendor;
 import org.apache.rocketmq.studio.instance.InstanceRepository;
 import org.apache.rocketmq.studio.instance.InstanceVO;
+import org.apache.rocketmq.studio.provider.tencent.TencentAclService;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -51,6 +52,7 @@ import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -66,6 +68,9 @@ class AclServiceTest {
     @Mock
     private InstanceRepository instanceRepository;
 
+    @Mock
+    private TencentAclService tencentAclService;
+
     @InjectMocks
     private AclService aclService;
 
@@ -143,13 +148,43 @@ class AclServiceTest {
     }
 
     @Test
-    void listRulesShouldNormalizeInvalidPaginationBounds() {
-        when(aclRepository.findRulePage(null, null, null, null, null, 1, 20))
-                .thenReturn(PageResult.empty(1, 20));
+    void listRulesShouldRejectInvalidPaginationBeforeQueryingRules() {
+        assertThatThrownBy(() -> aclService.listRules(null, null, null, null, 
null,
+                null, 0, 20))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("page must be >= 1 and pageSize must be between 1 
and 100")
+                .satisfies(error -> assertThat(((BusinessException) 
error).getCode()).isEqualTo(400));
+        assertThatThrownBy(() -> aclService.listRules(null, null, null, null, 
null,
+                null, 1, 0))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("page must be >= 1 and pageSize must be between 1 
and 100");
+        assertThatThrownBy(() -> aclService.listRules(null, null, null, null, 
null,
+                null, 1, 101))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("page must be >= 1 and pageSize must be between 1 
and 100");
 
-        aclService.listRules(null, null, null, null, null, null, 0, 0);
+        verifyNoInteractions(aclRepository);
+    }
 
-        verify(aclRepository).findRulePage(null, null, null, null, null, 1, 
20);
+    @Test
+    void listRulesShouldAcceptTheMaximumPageSizeForApacheRules() {
+        when(aclRepository.findRulePage(null, null, null, null, null, 1, 100))
+                .thenReturn(PageResult.empty(1, 100));
+
+        aclService.listRules(null, null, null, null, null, null, 1, 100);
+
+        verify(aclRepository).findRulePage(null, null, null, null, null, 1, 
100);
+    }
+
+    @Test
+    void listRulesShouldRejectInvalidPaginationBeforeTencentRuleDiscovery() {
+        assertThatThrownBy(() -> aclService.listRules(null, null, null, null, 
null,
+                "tencent-instance", 1, 101))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("page must be >= 1 and pageSize must be between 1 
and 100");
+
+        verifyNoInteractions(instanceRepository);
+        verifyNoInteractions(tencentAclService);
     }
 
     @Test

Reply via email to