fix(security): prevent removing the last active admin
Admins could remove the admin group from, deactivate, or delete the last active admin, locking the system out of all administration. Add a count_active_admins() repo method and a _is_last_active_admin() guard, and block all three operations when they would leave zero active admins. Refs: porchlight-yq7 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e54764cda9
commit
aedb451128
5 changed files with 110 additions and 0 deletions
|
|
@ -237,3 +237,14 @@ async def test_roundtrip_preserves_all_fields(user_repo: SQLiteUserRepository) -
|
|||
assert sorted(fetched.groups) == ["admin", "users"]
|
||||
assert fetched.created_at == user.created_at
|
||||
assert fetched.updated_at == user.updated_at
|
||||
|
||||
|
||||
async def test_count_active_admins(user_repo: SQLiteUserRepository) -> None:
|
||||
await user_repo.create(_make_user(userid="a1", username="admin1", groups=["admin", "users"]))
|
||||
await user_repo.create(_make_user(userid="a2", username="admin2", groups=["admin"]))
|
||||
# Inactive admin must not count.
|
||||
await user_repo.create(_make_user(userid="a3", username="admin3", groups=["admin"], active=False))
|
||||
# Non-admin must not count.
|
||||
await user_repo.create(_make_user(userid="u1", username="user1", groups=["users"]))
|
||||
|
||||
assert await user_repo.count_active_admins() == 2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue