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