apache / apache/rocketmq-dashboard

[Studio][Bug] Clearing an instance admin credential reference has no effect

Open
#4,273 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.4k
Forks
683
Avg merge
2d 14h
Merged PRs (30d)
58

Description

## 1. Symptom

An instance's admin credential reference cannot be removed. In the instance edit dialog (`web/src/pages/instance/index.tsx`, "Admin Credential Ref" field) clearing the value and saving returns HTTP 200 and the edited row looks updated, but `rmq_instance.admin_credential_ref` still holds the previous reference, so it reappears on the next list load.

## 2. Root cause

`server/src/main/java/org/apache/rocketmq/studio/instance/InstanceService.java:602-604`

```java
if (!cloudInstance && instance.getAdminCredentialRef() != null) {
updated.setAdminCredentialRef(normalizeCredentialRef(instance.getAdminCredentialRef()));
}
```

`normalizeCredentialRef` (`InstanceService.java:561-563`) maps a blank submission to `null`, so a blank reference is an explicit clear and a non-null `updated` field is written as null. But `updated` (a copy of the stored instance, `:580`) goes out through `instanceRepository.save(updated)` (`:607`), and `MybatisPlusInstanceRepository.save` writes the update with `instanceMapper.updateById(entity)` (`MybatisPlusInstanceRepository.java:122`).

MyBatis-Plus `updateById` omits null entity fields (`FieldStrategy.NOT_NULL`, no `update-strategy` override in `application.yml`), so the null reference never reaches the SET clause: the column keeps its previous value while the service returns a VO whose reference is null. This is the same mechanism that was already fixed for the ACL user/rule columns in #3342, and for a cleared `white_remote_address` before that.

The repository is also the only place that can fix it correctly: the service cannot express "clear this column" through the plain entity-based `save`, and the update path is the repository's own concern (`InstanceRepository.save` is called only from `InstanceService` at `:223` (insert) and `:607` (update)).

## 3. Impact

- A security-relevant piece of instance configuration is write-once: an operator can set or change the external admin credential reference but cannot remove it, even though the API accepts the clear.
- The response contradicts the database: the API returns `adminCredentialRef: null` while MySQL still stores the reference, and the UI replaces its row with that response without refetching (the edit handler uses the returned instance, `web/src/pages/instance/index.tsx:447-455`), so the wrong value is displayed until the next manual reload.
- Any client of `POST /api/instances/update` (or the equivalent instance-update endpoint) hits the same silent no-op.

## 4. Reproduction

1. Create an Apache-type instance with `adminCredentialRef = "production-admin"`.
2. Update it with `adminCredentialRef = ""` (the edit dialog sends the cleared input verbatim).
3. Effect: HTTP 200, response `adminCredentialRef` is null.
4. `SELECT admin_credential_ref FROM rmq_instance WHERE id = ` still returns `production-admin`.

## 5. Expected behaviour

- A blank reference clears the column (NULL), matching `normalizeCredentialRef`'s intent.
- An omitted reference (`null` in the request) keeps the stored value.
- The returned instance reflects the persisted state.
- Cloud instances stay unchanged: the field is only assignable for Apache instances (`InstanceService.java:602`), and the fix must not touch the insert path.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the update path in server/src/main/java/org/apache/rocketmq/studio/instance/InstanceService.java around lines 561-607, then inspect MybatisPlusInstanceRepository.java around line 122 and the mapper update behavior. Verify that a blank reference persists NULL while an omitted reference preserves the value, without changing cloud instances or the insert path.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.