codeant-ai-for-open-source[bot] commented on code in PR #40178:
URL: https://github.com/apache/superset/pull/40178#discussion_r3251707075
##########
superset/security/manager.py:
##########
@@ -174,6 +178,38 @@ def post_update(self, item: Model) -> None:
def post_delete(self, item: Model) -> None:
_log_audit_event("RoleDeleted", {"role_name": item.name, "role_id":
item.id})
+ @expose("/<int:role_id>/users", methods=["PUT"])
+ @protect()
+ @safe
+ def update_role_users(self, role_id: int) -> Any:
+ """Override to deduplicate user IDs and handle missing users
gracefully."""
+ try:
+ item = self.update_role_user_schema.load(request.json)
+ role = self.datamodel.get(role_id)
+ if not role:
+ return self.response_404()
+
+ user_ids = list(set(item["user_ids"]))
+ users = (
+ current_app.appbuilder.session.query(User)
+ .filter(User.id.in_(user_ids))
+ .all()
+ )
+ role.user = users
+ self.datamodel.edit(role)
+ return self.response(
+ 200,
+ **{
+ API_RESULT_RES_KEY: self.update_role_user_schema.dump(
+ item, many=False
+ )
+ },
+ )
Review Comment:
**Suggestion:** The endpoint now mutates the incoming `user_ids`
(deduplicating and potentially dropping IDs not found in the DB) but still
returns a payload serialized from the original `item`, so the response can
report users that were not actually persisted. Return the saved user IDs (or
the updated role state) instead of echoing the pre-query request object to
avoid response/data mismatch. [api mismatch]
<details>
<summary><b>Severity Level:</b> Major ⚠️</summary>
```mdx
- ⚠️ Role users endpoint response misrepresents persisted role-user
assignments.
- ⚠️ External API clients may cache incorrect role membership state.
- ⚠️ Troubleshooting role assignment issues becomes harder for
administrators.
```
</details>
<details>
<summary><b>Steps of Reproduction ✅ </b></summary>
```mdx
1. Run Superset with this PR so that `SupersetRoleApi` is registered as a
FAB API
blueprint (see `superset/security/manager.py:160-165` and `register_views` at
`superset/security/manager.py:3636-3666`).
2. Ensure you have a valid role `R` and at least one existing user `U` (any
admin-created
role and user are sufficient; the role edit UI uses this API via
`updateRoleUsers` in
`superset-frontend/src/features/roles/utils.ts:11-15`).
3. Using an HTTP client authenticated as an admin, call `PUT
/api/v1/security/roles/R/users` (endpoint exposed by `update_role_users` at
`superset/security/manager.py:181-207`) with JSON body `{"user_ids": [U,
9999999]}` where
`9999999` does not correspond to any `User.id` in the database.
4. In `update_role_users` (`superset/security/manager.py:187-199`), the code
deduplicates
into `user_ids = list(set(item["user_ids"]))` and queries `User` with
`.filter(User.id.in_(user_ids)).all()`, so only real users (e.g., `U`) are
loaded and
persisted via `role.user = users` and `self.datamodel.edit(role)`, but the
200 response is
built with `self.update_role_user_schema.dump(item, many=False)` where
`item["user_ids"]`
still contains `[U, 9999999]`, so the response body reports user IDs that
were not
actually saved.
5. Confirm the mismatch by querying role membership via the users API used
by the UI: `GET
/api/v1/security/users/?q=(filters:!((col:roles,opr:rel_m_m,value:R)))`
(same pattern as
`fetchPaginatedData` in
`superset-frontend/src/features/roles/RoleListEditModal.tsx:126-145`); the
results list
only user `U` as a member of role `R`, while the prior PUT response claimed
`[U,
9999999]`, demonstrating the response/data inconsistency.
```
</details>
[Fix in
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset%2Fsecurity%2Fmanager.py%0A%2A%2ALine%3A%2A%2A%20192%3A207%0A%2A%2AComment%3A%2A%2A%0A%09%2AApi%20Mismatch%3A%20The%20endpoint%20now%20mutates%20the%20incoming%20%60user_ids%60%20%28deduplicating%20and%20potentially%20dropping%20IDs%20not%20found%20in%20the%20DB%29%20but%20still%20returns%20a%20payload%20serialized%20from%20the%20original%20%60item%60%2C%20so%20the%20response%20can%20report%20users%20that%20were%20not%20actually%20persisted.%20Return%20the%20saved%20user%20IDs%20%28or%20the%20updated%20role%20state%29%20instead%20of%20echoing%20the%20pre-query%20request%20object%20to%20avoid%20response%2Fdata%20mismatch.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20con
cise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
| [Fix in VSCode
Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset%2Fsecurity%2Fmanager.py%0A%2A%2ALine%3A%2A%2A%20192%3A207%0A%2A%2AComment%3A%2A%2A%0A%09%2AApi%20Mismatch%3A%20The%20endpoint%20now%20mutates%20the%20incoming%20%60user_ids%60%20%28deduplicating%20and%20potentially%20dropping%20IDs%20not%20found%20in%20the%20DB%29%20but%20still%20returns%20a%20payload%20serialized%20from%20the%20original%20%60item%60%2C%20so%20the%20response%20can%20report%20users%20that%20were%20not%20actually%20persisted.%20Return%20the%20saved%20user%20I
Ds%20%28or%20the%20updated%20role%20state%29%20instead%20of%20echoing%20the%20pre-query%20request%20object%20to%20avoid%20response%2Fdata%20mismatch.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset/security/manager.py
**Line:** 192:207
**Comment:**
*Api Mismatch: The endpoint now mutates the incoming `user_ids`
(deduplicating and potentially dropping IDs not found in the DB) but still
returns a payload serialized from the original `item`, so the response can
report users that were not actually persisted. Return the saved user IDs (or
the updated role state) instead of echoing the pre-query request object to
avoid response/data mismatch.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask
user if the user wants to fix the rest of the comments as well. if said yes,
then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40178&comment_hash=4ae0732817db40a63ddaff2c2fc083d1fac97ab8de728a8cecd585e8e507a94f&reaction=like'>👍</a>
| <a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40178&comment_hash=4ae0732817db40a63ddaff2c2fc083d1fac97ab8de728a8cecd585e8e507a94f&reaction=dislike'>👎</a>
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]