Admin: allow changing your own quota

The self-protection guard refused every change to the admin's own account.
It now only refuses blocking and deleting yourself; a quota change is fine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 15:39:33 +01:00
co-authored by Claude Opus 5.5
parent a4581ab199
commit 77e9c25353
2 changed files with 25 additions and 6 deletions
+11 -6
View File
@@ -3,8 +3,9 @@
The backend seam for the admin panel: the registration gate — the first account
on a fresh install becomes the administrator and closes signup behind itself,
and this is how that gets reopened — the default quota, and managing users
(search, per-user quota, block, delete). An administrator cannot block or delete
their own account, so the instance can never lock out its last admin that way.
(search, per-user quota, block, delete). An administrator can change their own
quota but cannot block or delete their own account, so the instance can never
lock out its last admin that way.
"""
from __future__ import annotations
@@ -280,12 +281,15 @@ def _user_out(user: User, used_bytes: int, accounts: list[str]) -> AdminUserOut:
)
async def _target(db: AsyncSession, admin: User, user_id: uuid.UUID) -> User:
"""The user an admin action is aimed at; never the admin themselves."""
async def _target(
db: AsyncSession, admin: User, user_id: uuid.UUID, *, allow_self: bool = False
) -> User:
"""The user an admin action is aimed at. Blocking and deleting are never
allowed on the admin themselves; a quota change is (``allow_self``)."""
user = await db.scalar(select(User).where(User.id == user_id))
if user is None:
raise_api_error(404, "not_found", "user not found")
if user.id == admin.id:
if user.id == admin.id and not allow_self:
raise_api_error(409, "cannot_modify_self", "you cannot do this to your own account")
return user
@@ -303,7 +307,8 @@ async def patch_user(
user_id: uuid.UUID, body: AdminUserPatch, admin: CurrentAdmin, db: DbSession
) -> AdminUserOut:
"""Change a user's quota and/or block or unblock them."""
user = await _target(db, admin, user_id)
# Your own quota is fine to change; blocking yourself is not.
user = await _target(db, admin, user_id, allow_self=body.blocked is None)
if body.quota_bytes is not None:
user.quota_bytes = body.quota_bytes
if body.blocked is not None: