diff --git a/hbd/server/http.py b/hbd/server/http.py index 4af214a..8550337 100644 --- a/hbd/server/http.py +++ b/hbd/server/http.py @@ -104,14 +104,8 @@ def _can_own_host(user, host) -> bool: def _mask_config_for_api(config) -> dict: """Return a JSON-serializable config dict with secrets masked.""" - _SERVER_KEYS = [ - "hbd_port", "hbd_host", "ws_port", "wss_port", "hb_port", - "interval", "grace", "base_url", "threshold_renotify_interval", - "logfile", "pidfile", "pickfile", "journal_enabled", "journal_dir", - "journal_max_size", "journal_max_backups", "default_owner", - ] result = {} - result["server"] = {k: config.get(k) for k in _SERVER_KEYS} + result["server"] = {k: config.get(k) for k in configio_mod._SERVER_KEYS} users = {} for username, attrs in (config.get("users") or {}).items(): @@ -1031,38 +1025,42 @@ async def start( if err: return err if user and not user.admin: - return web.json_response({"error": "Admin only"}, status=403) + return web.json_response({"error": "Forbidden"}, status=403) return web.json_response(_mask_config_for_api(config)) + _YAML_EXTRACTORS = { + "notification_channels": lambda d: d.get("notification_channels") or {}, + "thresholds": lambda d: d.get("threshold_configs") or {}, + "hosts": lambda d: d.get("hosts") or {}, + "dns": lambda d: {k: d[k] for k in configio_mod._DNS_KEYS if k in d}, + } + async def api_config_section_get(request): """GET /api/0/config/section/{name} — raw YAML text for a YAML-editor section.""" user, err = _require_auth(request) if err: return err if user and not user.admin: - return web.json_response({"error": "Admin only"}, status=403) + return web.json_response({"error": "Forbidden"}, status=403) if not _config_path: return web.json_response({"error": "Config path not available"}, status=503) name = request.match_info["name"] - _DNS_KEYS = ["nsupdate_bin", "dyndomains", "dyndnshosts", "drophosts"] - _YAML_EXTRACTORS = { - "notification_channels": lambda d: d.get("notification_channels") or {}, - "thresholds": lambda d: d.get("threshold_configs") or {}, - "hosts": lambda d: d.get("hosts") or {}, - "dns": lambda d: {k: d[k] for k in _DNS_KEYS if k in d}, - } if name not in _YAML_EXTRACTORS: return web.json_response({"error": "Unknown section"}, status=404) import io as _io from ruamel.yaml import YAML as _YAML - data = configio_mod.read_roundtrip(_config_path) - section_data = _YAML_EXTRACTORS[name](data) - _sy = _YAML() - _sy.preserve_quotes = True - buf = _io.StringIO() - _sy.dump(section_data, buf) + try: + data = configio_mod.read_roundtrip(_config_path) + section_data = _YAML_EXTRACTORS[name](data) + _sy = _YAML() + _sy.preserve_quotes = True + buf = _io.StringIO() + _sy.dump(section_data, buf) + except Exception as exc: + logger.error("Config section read failed: %s", exc) + return web.json_response({"error": str(exc)}, status=500) return web.json_response({"yaml": buf.getvalue()}) async def api_config_backups_get(request): @@ -1071,7 +1069,7 @@ async def start( if err: return err if user and not user.admin: - return web.json_response({"error": "Admin only"}, status=403) + return web.json_response({"error": "Forbidden"}, status=403) if not _config_path: return web.json_response({"backups": []}) backups = configio_mod.list_backups(_config_path)