Prevent last admin from deleting themselves#792
Conversation
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
Updates the CLI delete command to use UserManager.delete_user() instead of direct session manipulation, ensuring consistent admin protection between CLI and API endpoints. Changes: - Refactored delete command to call UserManager.delete_user() - Added HTTPException handling for validation errors - Updated all delete tests to mock UserManager instead of session - Added test_delete_last_admin_blocked for admin protection - Removed unnecessary try/except that immediately re-raised The CLI now correctly prevents deletion of the last admin user, matching the behavior of the API endpoint.
89fd9a9 to
15ce45f
Compare
There was a problem hiding this comment.
Pull request overview
This PR implements admin deletion protection to prevent the last admin user from deleting themselves, which would lock out the system from administrative access.
Key Changes:
- Added logic to
UserManager.delete_user()that counts admin users and blocks deletion when the user is an admin, only 1 admin exists, and the current user is deleting themselves - Updated API endpoint and CLI command to pass
current_user_idparameter for self-deletion detection - Added comprehensive test coverage with 7 new tests across unit, integration, and CLI test suites
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
app/managers/user.py |
Added admin count check and CANT_DELETE_LAST_ADMIN error; updated delete_user() signature to accept current_user_id |
app/resources/user.py |
Modified delete endpoint to pass request.state.user.id as current user to deletion logic |
app/commands/user.py |
Refactored CLI delete command to use UserManager.delete_user() instead of direct session manipulation; passes user_id twice to simulate self-deletion |
tests/unit/test_user_manager.py |
Added 3 unit tests for last admin protection scenarios and updated existing tests for new method signature |
tests/integration/test_user_routes.py |
Added 3 integration tests verifying API endpoint behavior for admin deletion scenarios |
tests/cli/test_cli_user_command.py |
Updated CLI delete tests to mock UserManager.delete_user() and added test for last admin protection |
tests/unit/test_jwt_auth.py |
Updated test to use new delete_user() signature with two parameters |
tests/unit/test_api_key_auth.py |
Updated test to use new delete_user() signature with two parameters |
docs/usage/user-control.md |
Added warning section explaining admin deletion protection |
docs/reference/api.md |
Documented 400 error response and admin protection behavior in delete endpoint |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
docs: clarify admin deletion protection Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Explicitly set unique emails for all tests that create multiple users to prevent Faker from potentially generating duplicate emails. Fixed tests: - 2-user creation tests (5 tests) - Loop-based 3-user creation tests (4 tests) This eliminates potential flakiness from unique email constraint violations.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Remove unnecessary current_user_id parameter from delete_user. The protection now simply prevents deletion of the last admin user, regardless of who is performing the deletion. This is simpler, more defensive, and works identically for both API and CLI contexts. Changes: - UserManager.delete_user now takes only (user_id, session) - Removed self-deletion check - not needed - Protection triggers when admin_count <= 1 (period) - API endpoint no longer needs Request parameter - CLI implementation simplified (no duplicate user_id) - Updated all tests to match new signature - Updated test docstrings to reflect simplified logic This addresses the over-engineering of the self-deletion check and provides stronger protection against accidental system lockout.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Implements admin deletion protection to prevent the last admin user from deleting themselves, avoiding system lockout.
Changes
Implementation Details
CANT_DELETE_LAST_ADMINerror messageUserManager.delete_user()to count admins and block deletion when:UserManager.delete_user()instead of direct session manipulationTest Coverage
Edge Cases Covered