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),