VirtualDylan opened a new issue, #44865:
URL: https://github.com/apache/superset/issues/44865

   ### Bug description
   
   A user who has updated their own profile through `PUT /api/v1/me/` (name or 
password) can no longer be deleted. The delete fails until some other user 
edits them.
   
   **To reproduce** (clean 6.1.0, Postgres metadata database, default config):
   
   1. As an admin, create a user with any role (Gamma is enough).
   2. Log in as that user and change the first name: `PUT /api/v1/me/` with 
`{"first_name": "Changed"}`. It answers 200.
   3. As the admin, delete the user from **Settings → List Users**, or `DELETE 
/api/v1/security/users/<id>`.
   
   **Expected:** the user is deleted.
   
   **Actual:** the API answers 422:
   
   ```json
   {"message": "Database exception occurred: Circular dependency detected. 
(DeleteState(<User at 0x...>))"}
   ```
   
   The user list shows only "There was an issue deleting <username>". The 
server log has `sqlalchemy.exc.CircularDependencyError`.
   
   The same happens to an admin who edits their own row with `PUT 
/api/v1/security/users/<own id>`. A user who has logged in but never edited 
themselves deletes fine.
   
   **Workaround:** have an admin make any edit to the user (deactivating them, 
for example), then delete. The delete then answers 200.
   
   **Cause, as far as I can tell:**
   
   - `CurrentUserRestApi.pre_update` (`superset/views/users/api.py`) sets 
`item.changed_by_fk = g.user.id`, so after a self-edit the row's 
`changed_by_fk` is its own `id`. The `PUT` on `/api/v1/me/` arrived in 6.0.0 
(#33620).
   - Flask-AppBuilder's `User` model 
(`flask_appbuilder/security/sqla/models.py`) declares `created_by` and 
`changed_by` as self-referential relationships without `post_update=True`. 
SQLAlchemy's unit of work cannot order the delete of a row whose foreign key 
points at itself, and raises `CircularDependencyError`.
   - An admin edit cures it because FAB's `UserApi.pre_update` moves 
`changed_by_fk` to the admin.
   
   4.1.1 does not show it for self-service: resetting your own password there 
never writes `changed_by_fk`.
   
   Possible fixes: leave `changed_by_fk` alone (or null it) when a user edits 
themselves, null a self-referencing `changed_by_fk` in 
`SupersetUserApi.pre_delete`, or add `post_update=True` to the two 
relationships in Flask-AppBuilder.
   
   ### Screenshots/recordings
   
   _No response_
   
   ### Superset version
   
   6.1.0
   
   ### Python version
   
   3.11
   
   ### Node version
   
   Not applicable
   
   ### Browser
   
   Chrome
   
   ### Additional context
   
   - Image: `apache/superset:6.1.0-py311`, plus `psycopg2-binary`. 
Flask-AppBuilder 5.0.2, SQLAlchemy 1.4.54, Postgres 16 metadata database.
   - The `User` relationships are the same on Flask-AppBuilder master, and 
`master` here still has the `changed_by_fk = g.user.id` line, so I expect it 
reproduces there too. I have not run master.
   - I searched this repo and Flask-AppBuilder for "Circular dependency 
detected", `CircularDependencyError` and `changed_by_fk` and found no existing 
report. A 2022 comment on #13345 mentions the same exception without a cause.
   
   ### Checklist
   
   - [ ] I have searched Superset docs and Slack and didn't find a solution to 
my problem.
   - [x] I have searched the GitHub issue tracker and didn't find a similar bug 
report.
   - [ ] I have checked Superset's logs for errors and if I found a relevant 
Python stacktrace, I included it here as text in the "additional context" 
section.
   


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

Reply via email to