Manage platform admins and feature flags from the control panel

Features tab: create/edit flags, flip global switches, and toggle a flag per
club from the club detail page. Where `everyone` is set the per-club toggle is
replaced by a badge, because a toggle there would have no effect and so would
lie about what is on.

Admins tab: grant, promote, demote and revoke platform access. Gated on
is_superuser, not is_staff -- the panel itself is staff-accessible, so letting
staff grant is_superuser would collapse the two levels into one and stop
is_superuser being a boundary we can later hang anything on.

Two guardrails, enforced in the service so they hold regardless of caller:
you cannot strip your own access (you would lose the panel mid-click), and the
last superuser can never be demoted (the platform would be locked out of
itself). Granted users get an unusable password and must enrol 2FA before they
can sign in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 16:42:23 +02:00
parent fed24bfee3
commit 268cbe1e06
14 changed files with 3913 additions and 29 deletions

View File

@@ -25,3 +25,16 @@ class PlatformStaffRequiredMixin(UserPassesTestMixin):
def test_func(self):
user = self.request.user
return user.is_staff or user.is_superuser
class PlatformSuperuserRequiredMixin(PlatformStaffRequiredMixin):
"""Superusers only.
Managing platform admins is the one thing staff may not do. The panel is
gated on ``is_staff or is_superuser``, so if a staff member could grant
themselves ``is_superuser`` the two would collapse into the same thing and
``is_superuser`` would stop being a security boundary.
"""
def test_func(self):
return self.request.user.is_superuser