Skip to content

enhance: serialize user update methods - #1042

Open
eternal-flame-AD wants to merge 1 commit into
masterfrom
api-user-txn
Open

eternal-flame-AD wants to merge 1 commit into
masterfrom
api-user-txn

Conversation

@eternal-flame-AD

Copy link
Copy Markdown
Member

Serializes user update actions to prevent race conditions leading to unexpected results.

I removed the 'Test_UpdateUserByID_EmptyPassword_Expect400' test as it seemed to be a mistake - it should return 200, it returned 400 in the test because there wasn't a second admin.

@eternal-flame-AD
eternal-flame-AD requested a review from a team as a code owner September 2, 2026 09:00
@codecov

codecov Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.38889% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.79%. Comparing base (c21a7de) to head (6445b84).
⚠️ Report is 13 commits behind head on master.

Files with missing lines Patch % Lines
api/user.go 74.41% 6 Missing and 5 partials ⚠️
database/database.go 75.00% 1 Missing and 1 partial ⚠️
database/user.go 60.00% 1 Missing and 1 partial ⚠️
api/oidc.go 0.00% 0 Missing and 1 partial ⚠️
plugin/manager.go 90.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1042      +/-   ##
==========================================
+ Coverage   75.77%   75.79%   +0.02%     
==========================================
  Files          66       66              
  Lines        3620     3644      +24     
==========================================
+ Hits         2743     2762      +19     
- Misses        666      669       +3     
- Partials      211      213       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread api/user.go Outdated
Comment thread api/user.go Outdated
Comment thread api/user.go Outdated
Comment thread api/user.go
Comment thread api/user.go Outdated
@eternal-flame-AD
eternal-flame-AD force-pushed the api-user-txn branch 5 times, most recently from d486c1b to 6e4f37c Compare September 6, 2026 14:06
Comment thread api/user.go Outdated
ctx.AbortWithError(400, errCannotDeleteLastAdmin)
return errCannotDeleteLastAdmin
}
return a.UserChangeNotifier.fireUserDeleted(id)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be moved outside of the transaction and be only invoked when the deleted succeeded. Otherwise the transaction could fail, and we've already deleted all plugin related resources.

@eternal-flame-AD eternal-flame-AD Sep 7, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, this looks about right to me? If we failed to clean up all resources the transaction should be rolled back so they can try again.

There is the possibility of a partial cleanup I guess but I think it's more intuitive to keep the user record itself intact instead of completely deleting the user record despite leaving residual dependencies not deleted.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry missed the notification; I mean it more the other way around, the deletion from the plugin manager succeeds, but the committing of the transaction fails.

Then the users isn't deleted, but the plugin state is already cleaned up.

@eternal-flame-AD eternal-flame-AD Sep 26, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this leakage as I described above. I think this is an acceptable tradeoff for now compared to revamping the entire user notify callback design. We can go back to this if this becomes a real issue, I think the easiiest solution to this issue is simply add an soft deletion/account lockout feature rather than trying to delete everything in one atomic action (which is practically impossible when we also have application images, etc).

From my point of view, a user clicking "delete user" and "confirm" will understand the practicality of such actions (plugin state will be deleted). If the user cannot be deleted for whatever reason after all they can just try again.

@jmattheis jmattheis Sep 27, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, that it can stay this way.

I just tried to delete this on a running instance with a enabled plugin. It seems like the request is just timing out. It could be a connection pool lock. THe transactions owns the connection but inside fireUserDeleted/plugin.Manager#RemoveUser another database call is done, which doesn't use the txdb.

Image

Afterwards the server doesn't accept requests anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants