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 b5f7da4  fix: validate audit query and cleanup parameters (#442)
b5f7da4 is described below

commit b5f7da4c399668e9c68bb80d70a584b51d6239e7
Author: btlqql <[email protected]>
AuthorDate: Fri Jul 17 16:40:10 2026 +0800

    fix: validate audit query and cleanup parameters (#442)
---
 .../rocketmq/studio/ops/audit/AuditService.java    | 19 +++++++++-
 .../studio/ops/audit/AuditServiceTest.java         | 43 ++++++++++++++++++++++
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git 
a/server/src/main/java/com/rocketmq/studio/ops/audit/AuditService.java 
b/server/src/main/java/com/rocketmq/studio/ops/audit/AuditService.java
index f5968b8..e1d98b8 100644
--- a/server/src/main/java/com/rocketmq/studio/ops/audit/AuditService.java
+++ b/server/src/main/java/com/rocketmq/studio/ops/audit/AuditService.java
@@ -17,6 +17,7 @@
 package com.rocketmq.studio.ops.audit;
 
 import com.rocketmq.studio.common.domain.PageResult;
+import com.rocketmq.studio.common.exception.BusinessException;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -38,6 +39,7 @@ public class AuditService {
     public PageResult<AuditRecordVO> queryLogs(int page, int pageSize, String 
search,
                                              String operationType, String 
startDate,
                                              String endDate, String result) {
+        validatePagination(page, pageSize);
         log.info("Querying audit logs, page={}, pageSize={}, search={}, 
operationType={}, result={}",
                 page, pageSize, search, operationType, result);
 
@@ -47,8 +49,9 @@ public class AuditService {
         List<AuditRecordVO> allRecords = auditRepository.findAll(search, 
operationType, start, end, result);
         long total = allRecords.size();
 
-        int fromIndex = Math.min((page - 1) * pageSize, allRecords.size());
-        int toIndex = Math.min(fromIndex + pageSize, allRecords.size());
+        long offset = (long) (page - 1) * pageSize;
+        int fromIndex = (int) Math.min(offset, allRecords.size());
+        int toIndex = (int) Math.min((long) fromIndex + pageSize, 
allRecords.size());
         List<AuditRecordVO> pageRecords = allRecords.subList(fromIndex, 
toIndex);
 
         return PageResult.of(pageRecords, total, page, pageSize);
@@ -56,11 +59,23 @@ public class AuditService {
 
 
     public int cleanupLogs(int beforeDays) {
+        if (beforeDays <= 0) {
+            throw new BusinessException(400, "beforeDays must be greater than 
0");
+        }
         log.info("Cleaning up audit logs older than {} days", beforeDays);
         LocalDateTime cutoff = LocalDateTime.now().minusDays(beforeDays);
         return auditRepository.deleteBefore(cutoff);
     }
 
+    private void validatePagination(int page, int pageSize) {
+        if (page <= 0) {
+            throw new BusinessException(400, "page must be greater than 0");
+        }
+        if (pageSize <= 0) {
+            throw new BusinessException(400, "pageSize must be greater than 
0");
+        }
+    }
+
     private LocalDateTime parseDate(String dateStr, boolean startOfDay) {
         if (dateStr == null || dateStr.isEmpty()) {
             return null;
diff --git 
a/server/src/test/java/com/rocketmq/studio/ops/audit/AuditServiceTest.java 
b/server/src/test/java/com/rocketmq/studio/ops/audit/AuditServiceTest.java
index e044632..2abcb63 100644
--- a/server/src/test/java/com/rocketmq/studio/ops/audit/AuditServiceTest.java
+++ b/server/src/test/java/com/rocketmq/studio/ops/audit/AuditServiceTest.java
@@ -17,6 +17,7 @@
 package com.rocketmq.studio.ops.audit;
 
 import com.rocketmq.studio.common.domain.PageResult;
+import com.rocketmq.studio.common.exception.BusinessException;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
@@ -30,6 +31,7 @@ import java.util.Collections;
 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.eq;
 import static org.mockito.ArgumentMatchers.isNull;
@@ -107,6 +109,35 @@ class AuditServiceTest {
         assertThat(result.getTotal()).isEqualTo(1);
     }
 
+    @Test
+    void queryLogsShouldRejectNonPositivePage() {
+        assertThatThrownBy(() -> auditService.queryLogs(0, 10, null, null, 
null, null, null))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("page must be greater than 0")
+                .satisfies(ex -> assertThat(((BusinessException) 
ex).getCode()).isEqualTo(400));
+    }
+
+    @Test
+    void queryLogsShouldRejectNonPositivePageSize() {
+        assertThatThrownBy(() -> auditService.queryLogs(1, 0, null, null, 
null, null, null))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("pageSize must be greater than 0")
+                .satisfies(ex -> assertThat(((BusinessException) 
ex).getCode()).isEqualTo(400));
+    }
+
+    @Test
+    void queryLogsShouldAvoidOffsetOverflow() {
+        AuditRecordVO record = 
AuditRecordVO.builder().operationType("CREATE").build();
+        when(auditRepository.findAll(isNull(), isNull(), isNull(), isNull(), 
isNull()))
+                .thenReturn(List.of(record));
+
+        PageResult<AuditRecordVO> result = auditService.queryLogs(
+                Integer.MAX_VALUE, Integer.MAX_VALUE, null, null, null, null, 
null);
+
+        assertThat(result.getItems()).isEmpty();
+        assertThat(result.getTotal()).isEqualTo(1);
+    }
+
     @Test
     void queryLogsShouldPassSearchFilterToRepository() {
         when(auditRepository.findAll(eq("topic-a"), isNull(), isNull(), 
isNull(), isNull()))
@@ -191,6 +222,18 @@ class AuditServiceTest {
         assertThat(result).isZero();
     }
 
+    @Test
+    void cleanupLogsShouldRejectNonPositiveRetention() {
+        assertThatThrownBy(() -> auditService.cleanupLogs(0))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("beforeDays must be greater than 0")
+                .satisfies(ex -> assertThat(((BusinessException) 
ex).getCode()).isEqualTo(400));
+
+        assertThatThrownBy(() -> auditService.cleanupLogs(-1))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("beforeDays must be greater than 0");
+    }
+
     @Test
     void queryLogsShouldHandleAllFiltersTogether() {
         when(auditRepository.findAll(eq("admin"), eq("DELETE"), 
any(LocalDateTime.class),

Reply via email to