Additional VNC WebUI Changes

This commit is contained in:
2026-02-06 05:52:59 -07:00
parent 0d40ca6edb
commit a218f594a3
6 changed files with 283 additions and 24 deletions

View File

@@ -4,16 +4,19 @@
#
# API Endpoints (if applicable):
# - GET /api/server/time (Operator Session) - Returns the server clock in multiple formats.
# - GET /api/server/certificates/root (Operator Session) - Downloads the Borealis root CA certificate.
# ======================================================
from __future__ import annotations
from datetime import datetime, timezone
from typing import TYPE_CHECKING, Any, Dict
from pathlib import Path
from typing import TYPE_CHECKING, Any, Dict, Optional
from flask import Blueprint, Flask, jsonify
from flask import Blueprint, Flask, jsonify, send_file
from ...auth import RequestAuthContext
from ....security import certificates
if TYPE_CHECKING: # pragma: no cover - typing aide
from .. import EngineServiceAdapters
@@ -33,6 +36,29 @@ def _serialize_time(now_local: datetime, now_utc: datetime) -> Dict[str, Any]:
}
def _resolve_root_ca_path(adapters: "EngineServiceAdapters") -> Optional[Path]:
candidates = []
try:
candidates.append(certificates.engine_certificates_root() / "borealis-root-ca.pem")
except Exception:
pass
cert_path = getattr(adapters.context, "tls_cert_path", None)
if cert_path:
try:
candidates.append(Path(str(cert_path)).expanduser().resolve().parent / "borealis-root-ca.pem")
except Exception:
candidates.append(Path(str(cert_path)).parent / "borealis-root-ca.pem")
for candidate in candidates:
try:
if candidate and candidate.is_file():
return candidate
except Exception:
continue
return None
def register_info(app: Flask, adapters: "EngineServiceAdapters") -> None:
"""Expose server telemetry endpoints used by the admin interface."""
@@ -54,4 +80,20 @@ def register_info(app: Flask, adapters: "EngineServiceAdapters") -> None:
payload = _serialize_time(now_local, now_utc)
return jsonify(payload)
@blueprint.route("/api/server/certificates/root", methods=["GET"])
def server_root_ca() -> Any:
_, error = auth.require_user()
if error:
return jsonify(error[0]), error[1]
path = _resolve_root_ca_path(adapters)
if not path:
return jsonify({"error": "root_ca_missing"}), 404
return send_file(
str(path),
mimetype="application/x-pem-file",
as_attachment=True,
download_name="borealis-root-ca.pem",
max_age=0,
)
app.register_blueprint(blueprint)

View File

@@ -152,15 +152,19 @@ class VncProxyServer:
self._ready.set()
await server.wait_closed()
async def _handle_client(self, websocket, path: str) -> None:
parsed = urlsplit(path)
async def _handle_client(self, websocket, path: Optional[str] = None) -> None:
raw_path = path or getattr(websocket, "path", "") or ""
parsed = urlsplit(raw_path)
if parsed.path != VNC_WS_PATH:
self.logger.warning("VNC proxy rejected request with invalid path: %s", raw_path)
await websocket.close(code=1008, reason="invalid_path")
return
query = parse_qs(parsed.query or "")
token = (query.get("token") or [""])[0]
session = self.registry.consume(token)
if not session:
token_hint = token[:8] if token else "-"
self.logger.warning("VNC proxy rejected session (token=%s)", token_hint)
await websocket.close(code=1008, reason="invalid_session")
return