unbridled-41 opened a new pull request, #5430:
URL: https://github.com/apache/rocketmq-dashboard/pull/5430
## Problem / Evidence
Four search paths passed the user's text straight into a MyBatis-Plus
`.like()`, so `%` and `_` kept their pattern meaning:
| Call path | Code (pre-fix) |
|---|---|
| audit log search (`operator` / `resource_name` / `detail`) |
`ops/audit/MybatisPlusAuditRepository.java:198-201` |
| ACL user search (`username` / `access_key`) |
`instance/acl/MybatisPlusAclRepository.java:123-126` |
| ACL rule search (`principal` / `resource`) |
`instance/acl/MybatisPlusAclRepository.java:418-419` |
| data-source search in settings (`json`) |
`persistence/MybatisPlusSettingsRepository.java:149-150` |
| studio user search (`username`) | `auth/AuthService.java:197-198` |
`.like(column, term)` renders `column LIKE '%term%'` with `term` as a bound
parameter, but binding does not make `%`/`_` literal: `svc_prod` also matches
`svcXprod`, and a lone `%` matches every row. RocketMQ names routinely contain
`_` and `%` (`topic_a`, `GID_prod-1`, `%DLQ%group`), so a literal search is the
common case — e.g. `GET /api/audit-logs?search=%` returns the whole table, and
`GET /api/studio-users?search=a_c` returns `abc`.
The project already knows the rule:
`instance/message/QueryHistoryService.java:353` and
`ops/ai/conversation/MybatisPlusAiConversationRepository.java:126` escape the
term, the second with the note *"a shared util is tracked separately
upstream"*, and `AiConversationPersistenceIntegrationTest` asserts a bare `%`
matches nothing. The five paths above were simply never routed through it.
## Root cause / Fix
Add `common/util/LikePatterns.escape` (backslash first, then `%` and `_`)
and use it in the five unescaped paths; migrate the two existing private copies
to it so the rule lives in one place instead of three.
## Priority & scoring
PRIORITY 50 = 影响 12 (search results are wrong — over-matching — across
audit, ACL, users and settings; a single `%` defeats a filter) + 波及 10 (five
endpoints and their exports/paging totals) + 可复现 20 (deterministic) + 维护价值 8
(removes the acknowledged duplication).
FIX_CONFIDENCE 90: the escaping is already the project's established pattern
and its behaviour is pinned by the two pre-existing tests, which keep passing
after the migration.
## Tests
```
cd server && mvn -o test
-Dtest='LikePatternsTest,MybatisPlusAuditRepositoryTest,MybatisPlusAclRepositoryTest,MybatisPlusSettingsRepositoryTest,QueryHistoryServiceTest,AiTimelineRepositoryTest,AuthServiceTest,AuditServiceTest'
```
- Green: `Tests run: 139, Failures: 0, Errors: 0, Skipped: 0`.
- Red with the escaping removed (the five sources reverted, tests kept): the
three repository suites fail exactly the four new regressions —
`%topic\_a%` not found, `%svc\_prod%` and `%\%DLQ\%%` not found,
`%prom\_secure%` not found.
- New tests assert the **bound LIKE parameter** through an `ArgumentCaptor`
(e.g. `containsOnly("%topic\\_a%")`), so they do not depend on driver-specific
LIKE semantics; `QueryHistoryServiceTest` and `AiTimelineRepositoryTest` (which
own the pre-existing escaping assertions) pass unchanged after the migration,
pinning `LikePatterns` as behaviourally identical to the copies it replaces.
- A wider sweep of the touched packages (`ops.audit`, `instance.acl`,
`persistence`, `auth`, `common.util`, `instance.message`,
`ops.ai.conversation`): 725 tests, 0 failures; the 6 errors are
`@SpringBootTest` classes failing to load their context with `Communications
link failure` — they need the MySQL datasource CI provisions.
- `mvn -o checkstyle:check` passes.
## Risk
Low. The change only escapes metacharacters that previously had wildcard
meaning; terms without `%`, `_` or `\` produce the same parameter as before.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]