fix(users): admin can never strip their own admin permission
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Both backend (PATCH /users/{id}) and frontend (Edit User modal) now block
an admin from changing their own primary role away from admin or removing
admin from their own extra_roles, closing off a self-lockout scenario.
This commit is contained in:
@@ -17,6 +17,7 @@ from app.dependencies.auth import require_role, require_any_role_strict
|
||||
|
||||
# Import UnitOfWork from app.domain.unit_of_work
|
||||
from app.domain.unit_of_work import UnitOfWork
|
||||
from app.domain.errors import BusinessRuleViolation
|
||||
|
||||
# Import User from app.models.user
|
||||
from app.models.user import User
|
||||
@@ -269,6 +270,16 @@ def update_user_route(
|
||||
"""Update one or more fields of an existing user. **Requires admin role.**."""
|
||||
# Assign update_data = payload.model_dump(exclude_unset=True)
|
||||
update_data = payload.model_dump(exclude_unset=True)
|
||||
|
||||
# An admin can never strip their own admin permission — otherwise a
|
||||
# careless self-edit (or a compromised session) could lock every admin
|
||||
# out of the platform with no way back in.
|
||||
if user_id == current_user.id and current_user.role == "admin":
|
||||
final_role = update_data.get("role", current_user.role)
|
||||
final_extra_roles = update_data.get("extra_roles", current_user.extra_roles or [])
|
||||
if "admin" not in {final_role, *(final_extra_roles or [])}:
|
||||
raise BusinessRuleViolation("You cannot remove your own admin permission.")
|
||||
|
||||
# Open context manager
|
||||
with UnitOfWork(db) as uow:
|
||||
# Assign user = update_user(db, user_id, **update_data)
|
||||
|
||||
Reference in New Issue
Block a user