From 93e1ac19fa28a946ab0a68da1d01319bf8a339ad Mon Sep 17 00:00:00 2001 From: liuhy Date: Fri, 24 Jul 2026 09:25:02 -0700 Subject: [PATCH] Validate ACL create inputs --- .../studio/instance/acl/AclService.java | 9 ++++ .../studio/instance/acl/AclServiceTest.java | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/server/src/main/java/com/rocketmq/studio/instance/acl/AclService.java b/server/src/main/java/com/rocketmq/studio/instance/acl/AclService.java index ceff7680..94fed414 100644 --- a/server/src/main/java/com/rocketmq/studio/instance/acl/AclService.java +++ b/server/src/main/java/com/rocketmq/studio/instance/acl/AclService.java @@ -41,6 +41,12 @@ public List listRules(String clusterId, String principal) { public AclRuleVO createRule(AclRuleVO rule) { log.info("Creating ACL rule for principal={}", rule.getPrincipal()); + if (isBlank(rule.getPrincipal())) { + throw new BusinessException(400, "ACL principal is required"); + } + if (isBlank(rule.getResource())) { + throw new BusinessException(400, "ACL resource is required"); + } rule.setId(UUID.randomUUID().toString()); rule.setCreatedAt(LocalDateTime.now()); return aclRepository.saveRule(rule); @@ -71,6 +77,9 @@ public List listUsers() { public AclUserVO createUser(AclUserVO user) { log.info("Creating ACL user username={}", user.getUsername()); + if (isBlank(user.getUsername())) { + throw new BusinessException(400, "ACL username is required"); + } user.setId(UUID.randomUUID().toString()); user.setAccessKey(UUID.randomUUID().toString().replace("-", "")); user.setSecretKey(UUID.randomUUID().toString().replace("-", "")); diff --git a/server/src/test/java/com/rocketmq/studio/instance/acl/AclServiceTest.java b/server/src/test/java/com/rocketmq/studio/instance/acl/AclServiceTest.java index c27008cb..fd553fda 100644 --- a/server/src/test/java/com/rocketmq/studio/instance/acl/AclServiceTest.java +++ b/server/src/test/java/com/rocketmq/studio/instance/acl/AclServiceTest.java @@ -17,6 +17,7 @@ package com.rocketmq.studio.instance.acl; +import com.rocketmq.studio.common.exception.BusinessException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -28,6 +29,7 @@ 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.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -85,6 +87,34 @@ void createRuleShouldSetIdAndTimestamp() { verify(aclRepository).saveRule(any(AclRuleVO.class)); } + @Test + void createRuleShouldRequirePrincipal() { + AclRuleVO input = AclRuleVO.builder() + .principal(" ") + .resource("topic-1") + .build(); + + assertThatThrownBy(() -> aclService.createRule(input)) + .isInstanceOf(BusinessException.class) + .satisfies(ex -> assertThat(((BusinessException) ex).getCode()).isEqualTo(400)) + .hasMessage("ACL principal is required"); + verify(aclRepository, never()).saveRule(any(AclRuleVO.class)); + } + + @Test + void createRuleShouldRequireResource() { + AclRuleVO input = AclRuleVO.builder() + .principal("user1") + .resource(" ") + .build(); + + assertThatThrownBy(() -> aclService.createRule(input)) + .isInstanceOf(BusinessException.class) + .satisfies(ex -> assertThat(((BusinessException) ex).getCode()).isEqualTo(400)) + .hasMessage("ACL resource is required"); + verify(aclRepository, never()).saveRule(any(AclRuleVO.class)); + } + @Test void deleteRuleShouldDelegateToRepository() { aclService.deleteRule("rule-1"); @@ -158,6 +188,20 @@ void createUserShouldGenerateKeysAndSetTimestamp() { verify(aclRepository).saveUser(any(AclUserVO.class)); } + @Test + void createUserShouldRequireUsername() { + AclUserVO input = AclUserVO.builder() + .username(" ") + .admin(false) + .build(); + + assertThatThrownBy(() -> aclService.createUser(input)) + .isInstanceOf(BusinessException.class) + .satisfies(ex -> assertThat(((BusinessException) ex).getCode()).isEqualTo(400)) + .hasMessage("ACL username is required"); + verify(aclRepository, never()).saveUser(any(AclUserVO.class)); + } + @Test void deleteUserShouldDelegateToRepository() { aclService.deleteUser("user-1");