tju-yxq opened a new issue, #5247:
URL: https://github.com/apache/rocketmq-dashboard/issues/5247

   ## Problem
   
   A studio user's administrator role is fixed at creation. When an operator 
earns trust (or a contractor's engagement ends), the only way to change their 
role is to delete the account and recreate it with the other flag — except the 
console has no user deletion either, so in practice the role can never change 
at all. The user management page renders the role as a static tag next to an 
enable/disable switch, and the API surface (`StudioUserController`) offers 
create, status, password and session-revoke endpoints only.
   
   This leaves the deployment's privilege model frozen at whatever was true on 
day one: separating duties (dropping the bootstrap admin's daily-driver account 
to a regular user) or granting an on-call operator temporary admin access 
during an incident both require out-of-band database surgery.
   
   ## Current behavior and reproduction
   
   1. Sign in as an administrator and open **Studio > User Management**.
   2. Locate a regular user. The **权限 / Role** column shows a static `普通用户` tag 
— no control.
   3. Check the API: `POST /api/studio-users` (create with `isAdmin`), `POST 
/{userId}/status` (enabled), `POST /{userId}/password`, `POST 
/{userId}/sessions/revoke` — no role endpoint (`StudioUserController.java`).
   
   `AuthService` similarly has `createUser(username, password, admin)` and 
`setUserEnabled(userId, enabled)` but nothing that writes the `admin` column of 
an existing row.
   
   ## Proposed behavior
   
   - A `POST /api/studio-users/{userId}/role` endpoint taking `{ "admin": 
true|false }`, mirroring the shape of the existing status endpoint.
   - Revoking the role from the **last enabled administrator** is refused with 
the same row-locking guard `setUserEnabled` already uses (409, "The last 
enabled administrator cannot lose the role"), so two concurrent revokes cannot 
strip every administrator at once.
   - Any role change **revokes the user's sessions**: the authenticated session 
snapshots the admin flag, so forcing a re-login is the only way the new role 
takes effect immediately (the same reasoning `changePassword` already applies).
   - The user management page replaces the static role tag with a role switch 
for administrator viewers (readers keep the tag, matching the admin-only 
mutation surface of every other action), guarded by a confirmation dialog that 
states the session-revocation consequence; revoking uses a danger-styled 
confirm.
   - Setting the role a user already has is idempotent (no write, no session 
revocation).
   
   ## Acceptance criteria
   
   - [ ] `POST /api/studio-users/7/role` with `{"admin": true}` updates the 
flag and returns the user; a missing `admin` field is rejected with 400.
   - [ ] Revoking from the last enabled administrator returns 409 and performs 
no write; revoking while another enabled administrator exists succeeds.
   - [ ] Every actual role change revokes that user's sessions; an idempotent 
no-op change touches nothing.
   - [ ] The page's role switch is visible to administrators only, is 
confirmation-gated, and shows grant/revoke success feedback before reloading 
the list.
   - [ ] Regression coverage pins the service guards (grant, last-admin 
rejection, multi-admin revoke, idempotence, session revocation), the endpoint 
contract, and both confirmation flows; the existing status-switch tests keep 
passing (disambiguated from the new role switch).
   
   ## Importance
   
   Must-have for the auth model to be operable. The workaround today is direct 
database access, which most operators cannot do safely (the guard rails — 
last-admin protection, session invalidation — only exist in the service layer). 
Access reviews that find over-privileged accounts currently have no in-product 
remediation at all.
   
   ## Duplicate check
   
   Searched open and closed issues/PRs for `"admin" role change`, `grant 
admin`, `promote user`, and `"user management" admin`. The closest matches are 
#5064 (open, a create-dialog state bug), #2372 (closed, the last-admin-disable 
concurrency guard this builds on) and #2161/#2162 (closed, the original 
persistent user management). None covers changing an existing user's role.
   


-- 
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]

Reply via email to