From afef15b955a9cdac8388dd23b2d6c94c0732cad0 Mon Sep 17 00:00:00 2001 From: Brian Krabach Date: Wed, 1 Apr 2026 10:07:55 -0700 Subject: [PATCH] feat: add load_federation_key() with env var override --- muxplex/settings.py | 11 ++++++++++ muxplex/tests/test_settings.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/muxplex/settings.py b/muxplex/settings.py index 34a1f3d..43c5ece 100644 --- a/muxplex/settings.py +++ b/muxplex/settings.py @@ -6,10 +6,12 @@ Settings are stored at ~/.config/muxplex/settings.json. import copy import json +import os import socket from pathlib import Path SETTINGS_PATH = Path.home() / ".config" / "muxplex" / "settings.json" +FEDERATION_KEY_PATH = Path.home() / ".config" / "muxplex" / "federation_key" DEFAULT_SETTINGS: dict = { "host": "127.0.0.1", @@ -75,3 +77,12 @@ def patch_settings(patch: dict) -> dict: current[key] = patch[key] save_settings(current) return current + + +def load_federation_key() -> str: + env_path = os.environ.get("MUXPLEX_FEDERATION_KEY_FILE") + path = Path(env_path) if env_path else FEDERATION_KEY_PATH + try: + return path.read_text().strip() + except FileNotFoundError: + return "" diff --git a/muxplex/tests/test_settings.py b/muxplex/tests/test_settings.py index 1239b28..204dac7 100644 --- a/muxplex/tests/test_settings.py +++ b/muxplex/tests/test_settings.py @@ -4,12 +4,14 @@ Tests for muxplex/settings.py — server-side settings management. """ import json +from pathlib import Path import pytest import muxplex.settings as settings_mod from muxplex.settings import ( DEFAULT_SETTINGS, + load_federation_key, load_settings, patch_settings, save_settings, @@ -415,3 +417,41 @@ def test_old_settings_file_without_serve_keys_loads_correctly(redirect_settings_ assert result["session_ttl"] == 604800, ( f"session_ttl must default to 604800 for old settings files, got: {result['session_ttl']!r}" ) + + +# ============================================================ +# load_federation_key tests (task-2) +# ============================================================ + + +def test_load_federation_key_returns_empty_when_no_file(tmp_path, monkeypatch): + """load_federation_key() returns empty string when the key file does not exist.""" + missing_path = tmp_path / "no_such_federation_key" + monkeypatch.setattr(settings_mod, "FEDERATION_KEY_PATH", missing_path) + monkeypatch.delenv("MUXPLEX_FEDERATION_KEY_FILE", raising=False) + + result = load_federation_key() + + assert result == "" + + +def test_load_federation_key_reads_existing_file(tmp_path, monkeypatch): + """load_federation_key() reads and strips the contents of the key file.""" + key_file = tmp_path / "federation_key" + key_file.write_text(" my-secret-key\n ") + monkeypatch.setattr(settings_mod, "FEDERATION_KEY_PATH", key_file) + monkeypatch.delenv("MUXPLEX_FEDERATION_KEY_FILE", raising=False) + + result = load_federation_key() + + assert result == "my-secret-key" + + +def test_load_federation_key_uses_default_path(monkeypatch): + """load_federation_key() uses ~/.config/muxplex/federation_key when env var is not set.""" + from muxplex.settings import FEDERATION_KEY_PATH + + monkeypatch.delenv("MUXPLEX_FEDERATION_KEY_FILE", raising=False) + # The default path should be used; we just verify no env override changes behaviour + # When the default file doesn't exist, returns empty string + assert FEDERATION_KEY_PATH == Path.home() / ".config" / "muxplex" / "federation_key"