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 142042f25 fix(acl): validate plain permission entries (#2563)
142042f25 is described below
commit 142042f25bf1a1df4851cf99d98df9eb9a7f5d3e
Author: btlqql <[email protected]>
AuthorDate: Tue Aug 25 17:37:25 2026 +0800
fix(acl): validate plain permission entries (#2563)
---
.../studio/instance/acl/MybatisPlusAclRepository.java | 15 +++++++++++++++
.../instance/acl/MybatisPlusAclRepositoryTest.java | 17 +++++++++++++++++
2 files changed, 32 insertions(+)
diff --git
a/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
b/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
index 4ab94bd05..76d7520f0 100644
---
a/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
+++
b/server/src/main/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepository.java
@@ -177,6 +177,8 @@ public class MybatisPlusAclRepository implements
AclRepository {
@Override
@Transactional
public PlainAccessConfigVO
createAndUpdatePlainAccessConfig(PlainAccessConfigVO config) {
+ validatePermissionEntries(config.getTopicPerms(), "topicPerms");
+ validatePermissionEntries(config.getGroupPerms(), "groupPerms");
List<RmqAclUser> existingAccounts = userMapper.selectList(
new QueryWrapper<RmqAclUser>().eq("access_key",
config.getAccessKey()));
if (existingAccounts.size() > 1) {
@@ -356,6 +358,19 @@ public class MybatisPlusAclRepository implements
AclRepository {
return new String[]{entry.substring(0, idx).trim(),
entry.substring(idx + 1).trim()};
}
+ private static void validatePermissionEntries(List<String> entries, String
field) {
+ if (entries == null) {
+ return;
+ }
+ for (int index = 0; index < entries.size(); index++) {
+ String[] parts = splitPerm(entries.get(index));
+ if (parts == null || parts[0].isBlank() || parts[1].isBlank()) {
+ throw new BusinessException(400,
+ field + "[" + index + "] must use non-blank
resource=permission format");
+ }
+ }
+ }
+
// ── Mapping ────────────────────────────────────────────────────
private static AclRuleVO toRuleVO(RmqAclRule entity) {
diff --git
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
index a7a5fc195..21626d723 100644
---
a/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
+++
b/server/src/test/java/org/apache/rocketmq/studio/instance/acl/MybatisPlusAclRepositoryTest.java
@@ -48,6 +48,7 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@@ -62,6 +63,22 @@ class MybatisPlusAclRepositoryTest {
@InjectMocks
private MybatisPlusAclRepository repository;
+ @Test
+ void upsertShouldRejectMalformedPermissionEntriesBeforeMutatingAccount() {
+ PlainAccessConfigVO config = PlainAccessConfigVO.builder()
+ .accessKey("svc-x")
+ .secretKey("secret-x")
+ .topicPerms(List.of("orders=PUB", "missing-permission"))
+ .build();
+
+ assertThatThrownBy(() ->
repository.createAndUpdatePlainAccessConfig(config))
+ .isInstanceOf(BusinessException.class)
+ .hasMessage("topicPerms[1] must use non-blank
resource=permission format")
+ .satisfies(error -> assertThat(((BusinessException)
error).getCode()).isEqualTo(400));
+
+ verifyNoInteractions(userMapper, ruleMapper);
+ }
+
@Test
void findRulePageShouldApplyFiltersAndPreserveFilteredTotal() {
RmqAclRule entity = new RmqAclRule();