mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-13 06:06:38 +00:00
Funkwhale stores its theme in global preferences, so
files/python/design_preferences.py sets the instance name, primary,
accent and background color, ui__custom_css from
templates/custom.css.j2 and the logo and banner as own uploads. It only
writes while ui__custom_css is empty or starts with the role's marker;
custom CSS an administrator wrote reports FOREIGN and stays untouched,
and design off takes back only the role's own values. tasks/main.yml
flushes the compose handlers and includes tasks/01_manager.yml, and
templates/compose.yml.j2 names the api container so container exec can
reach it.
tasks/01_manager.yml probes the administrator with
files/python/admin_state.py (MISSING, DRIFT or OK for active, staff,
superuser and password), creates it with fw users create --superuser
or realigns password and rights with fw users set, the password always
through the task environment. The account is platform_administrator:
meta/users.yml and the ADMIN_* lines of templates/playwright.env.j2 are
identical to feature/store-i18n (3c72c2002a), so the host
administrator's sudo password never becomes a Funkwhale password and
the later merge keeps these hunks clean. store-i18n provisions no
Funkwhale administrator at all.
templates/design.js.j2 follows Funkwhale's own theme switch, and
files/playwright/test-design.js checks the tokens in both modes, the
instance theming with palette, custom CSS and pod name, the start page
hero and sign-in card, the signed-in interface, a theme picked in
Funkwhale, logo, favicon and title, the platform administrator's sign-in
with administration rights and a visitor's refused sign-up, and captures
the gallery. Unit tests cover
both scripts. TODO.md records the Typesense key in the sidecar's argv
and the icons the front fetches from api.iconify.design.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import io
|
|
import os
|
|
import runpy
|
|
import sys
|
|
import unittest
|
|
from contextlib import redirect_stdout
|
|
from types import ModuleType
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from . import PROJECT_ROOT
|
|
|
|
SCRIPT_PATH = PROJECT_ROOT / "roles/web-app-funkwhale/files/python/admin_state.py"
|
|
|
|
ENV = {"FUNKWHALE_ADMIN_USERNAME": "alice", "FUNKWHALE_ADMIN_PASSWORD": "s3cret"}
|
|
|
|
|
|
def _fake_modules(user: MagicMock | None) -> dict[str, ModuleType]:
|
|
models = ModuleType("funkwhale_api.users.models")
|
|
models.User = MagicMock(name="User")
|
|
models.User.objects.filter.return_value.first.return_value = user
|
|
users = ModuleType("funkwhale_api.users")
|
|
users.models = models
|
|
api = ModuleType("funkwhale_api")
|
|
api.users = users
|
|
return {
|
|
"funkwhale_api": api,
|
|
"funkwhale_api.users": users,
|
|
"funkwhale_api.users.models": models,
|
|
}
|
|
|
|
|
|
def _user(*, active=True, staff=True, superuser=True, password_ok=True) -> MagicMock:
|
|
user = MagicMock(
|
|
name="user", is_active=active, is_staff=staff, is_superuser=superuser
|
|
)
|
|
user.check_password.return_value = password_ok
|
|
return user
|
|
|
|
|
|
class TestAdminState(unittest.TestCase):
|
|
def _run(self, user: MagicMock | None) -> str:
|
|
buf = io.StringIO()
|
|
with (
|
|
patch.dict(os.environ, ENV, clear=True),
|
|
patch.dict(sys.modules, _fake_modules(user)),
|
|
redirect_stdout(buf),
|
|
):
|
|
runpy.run_path(str(SCRIPT_PATH), run_name="__main__")
|
|
return buf.getvalue().strip()
|
|
|
|
def test_reports_a_missing_administrator(self) -> None:
|
|
self.assertEqual(self._run(None), "FUNKWHALE_ADMIN=MISSING")
|
|
|
|
def test_reports_ok_for_an_active_superuser_with_the_current_password(self) -> None:
|
|
user = _user()
|
|
self.assertEqual(self._run(user), "FUNKWHALE_ADMIN=OK")
|
|
user.check_password.assert_called_once_with("s3cret")
|
|
|
|
def test_reports_drift_on_a_rotated_password(self) -> None:
|
|
self.assertEqual(self._run(_user(password_ok=False)), "FUNKWHALE_ADMIN=DRIFT")
|
|
|
|
def test_reports_drift_on_missing_rights_or_an_inactive_account(self) -> None:
|
|
for user in (_user(staff=False), _user(superuser=False), _user(active=False)):
|
|
self.assertEqual(self._run(user), "FUNKWHALE_ADMIN=DRIFT")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|