Remove legacy bridge and expose auth session endpoint

This commit is contained in:
2025-10-22 20:18:09 -06:00
parent da4cb501e0
commit e1e63ec346
7 changed files with 185 additions and 212 deletions

View File

@@ -2,11 +2,8 @@
from __future__ import annotations
import importlib
import logging
import os
from pathlib import Path
from typing import Any, Iterable, Optional
from typing import Optional
from flask import Flask, request, send_from_directory
from flask_cors import CORS
@@ -103,135 +100,4 @@ def create_app(
return app
def attach_legacy_bridge(
app: Flask,
settings: EngineSettings,
*,
logger: Optional[logging.Logger] = None,
) -> None:
"""Attach the legacy Flask application as a fallback dispatcher.
Borealis ships a mature API surface inside ``Data/Server/server.py``. The
Engine will eventually supersede it, but during the migration the React
frontend still expects the historical endpoints to exist. This helper
attempts to load the legacy application and wires it as a fallback WSGI
dispatcher so any route the Engine does not yet implement transparently
defers to the proven implementation.
"""
log = logger or logging.getLogger("borealis.engine.legacy")
if not _legacy_bridge_enabled():
log.info("legacy-bridge-disabled")
return
legacy = _load_legacy_app(settings, app, log)
if legacy is None:
log.warning("legacy-bridge-unavailable")
return
app.config["ENGINE_LEGACY_BRIDGE_ACTIVE"] = True
app.wsgi_app = _FallbackDispatcher(app.wsgi_app, legacy.wsgi_app) # type: ignore[assignment]
app.extensions["legacy_flask_app"] = legacy
log.info("legacy-bridge-active")
def _legacy_bridge_enabled() -> bool:
raw = os.getenv("BOREALIS_ENGINE_ENABLE_LEGACY_BRIDGE", "1")
return raw.strip().lower() in {"1", "true", "yes", "on"}
def _load_legacy_app(
settings: EngineSettings,
engine_app: Flask,
logger: logging.Logger,
) -> Optional[Flask]:
try:
legacy_module = importlib.import_module("Data.Server.server")
except Exception as exc: # pragma: no cover - defensive
logger.exception("legacy-import-failed", exc_info=exc)
return None
legacy_app = getattr(legacy_module, "app", None)
if not isinstance(legacy_app, Flask):
logger.error("legacy-app-missing")
return None
# Align runtime configuration so both applications share database and
# session state.
try:
setattr(legacy_module, "DB_PATH", str(settings.database_path))
except Exception: # pragma: no cover - defensive
logger.warning("legacy-db-path-sync-failed", extra={"path": str(settings.database_path)})
_synchronise_session_config(engine_app, legacy_app)
return legacy_app
def _synchronise_session_config(engine_app: Flask, legacy_app: Flask) -> None:
legacy_app.secret_key = engine_app.config.get("SECRET_KEY", legacy_app.secret_key)
for key in (
"SESSION_COOKIE_HTTPONLY",
"SESSION_COOKIE_SECURE",
"SESSION_COOKIE_SAMESITE",
"SESSION_COOKIE_DOMAIN",
):
value = engine_app.config.get(key)
if value is not None:
legacy_app.config[key] = value
class _FallbackDispatcher:
"""WSGI dispatcher that retries a secondary app when the primary 404s."""
__slots__ = ("_primary", "_fallback", "_retry_statuses")
def __init__(
self,
primary: Any,
fallback: Any,
*,
retry_statuses: Iterable[int] = (404,),
) -> None:
self._primary = primary
self._fallback = fallback
self._retry_statuses = {int(status) for status in retry_statuses}
def __call__(self, environ: dict[str, Any], start_response: Any) -> Iterable[bytes]:
captured_body: list[bytes] = []
captured_status: dict[str, Any] = {}
def _capture_start_response(status: str, headers: list[tuple[str, str]], exc_info: Any = None):
captured_status["status"] = status
captured_status["headers"] = headers
captured_status["exc_info"] = exc_info
def _write(data: bytes) -> None:
captured_body.append(data)
return _write
primary_iterable = self._primary(environ, _capture_start_response)
try:
for chunk in primary_iterable:
captured_body.append(chunk)
finally:
close = getattr(primary_iterable, "close", None)
if callable(close):
close()
status_line = str(captured_status.get("status") or "500 Internal Server Error")
try:
status_code = int(status_line.split()[0])
except Exception: # pragma: no cover - defensive
status_code = 500
if status_code not in self._retry_statuses:
start_response(status_line, captured_status.get("headers", []), captured_status.get("exc_info"))
return captured_body
return self._fallback(environ, start_response)
__all__ = ["attach_legacy_bridge", "create_app"]
__all__ = ["create_app"]