fix(topology): secure and unify demo serving
This commit is contained in:
@@ -255,7 +255,7 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const API_BASE = 'http://localhost:5000';
|
||||
const API_BASE = '';
|
||||
let currentData = null;
|
||||
|
||||
// Group node members for composite SVG elements
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from topology_api.app import create_app
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
HTML_PATH = ROOT / "data" / "wiki" / "guanghan_topology_demo.html"
|
||||
CONFIG_PATH = ROOT / "topology_api" / "config.py"
|
||||
|
||||
|
||||
class TopologyApiServingTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
app = create_app()
|
||||
app.config.update(TESTING=True)
|
||||
cls.client = app.test_client()
|
||||
|
||||
def test_app_serves_demo_page_and_health(self) -> None:
|
||||
health = self.client.get("/health")
|
||||
self.assertEqual(health.status_code, 200)
|
||||
self.assertEqual(health.get_json(), {"status": "ok"})
|
||||
|
||||
page = self.client.get("/guanghan_topology_demo.html")
|
||||
self.assertEqual(page.status_code, 200)
|
||||
self.assertIn("广寒基地拓扑结构", page.get_data(as_text=True))
|
||||
page.close()
|
||||
|
||||
def test_page_uses_same_origin_api(self) -> None:
|
||||
html = HTML_PATH.read_text(encoding="utf-8")
|
||||
self.assertNotIn("http://localhost:5000", html)
|
||||
self.assertIn("const API_BASE = ''", html)
|
||||
|
||||
def test_config_has_no_default_password(self) -> None:
|
||||
source = CONFIG_PATH.read_text(encoding="utf-8")
|
||||
self.assertNotRegex(
|
||||
source,
|
||||
r'os\.environ\.get\(\s*["\']PGPASSWORD["\']\s*,',
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+10
-1
@@ -1,10 +1,15 @@
|
||||
# topology_api/app.py
|
||||
from flask import Flask
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Flask, send_from_directory
|
||||
from flask_cors import CORS
|
||||
from topology_api.config import API_HOST, API_PORT, API_DEBUG
|
||||
from topology_api.routes.snapshot import snapshot_bp
|
||||
|
||||
|
||||
WIKI_DIR = Path(__file__).resolve().parents[1] / "data" / "wiki"
|
||||
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
@@ -14,6 +19,10 @@ def create_app():
|
||||
def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
@app.route("/guanghan_topology_demo.html")
|
||||
def topology_demo():
|
||||
return send_from_directory(WIKI_DIR, "guanghan_topology_demo.html")
|
||||
|
||||
return app
|
||||
|
||||
|
||||
|
||||
+12
-5
@@ -1,11 +1,18 @@
|
||||
# topology_api/config.py
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
load_dotenv(PROJECT_ROOT / ".env")
|
||||
|
||||
# PostgreSQL connection (from .env)
|
||||
PGHOST = os.environ.get("PGHOST", "192.168.195.241")
|
||||
PGPORT = os.environ.get("PGPORT", "35432")
|
||||
PGUSER = os.environ.get("PGUSER", "user_armor")
|
||||
PGPASSWORD = os.environ.get("PGPASSWORD", "user_armor_1790990971")
|
||||
PGHOST = os.environ["PGHOST"]
|
||||
PGPORT = os.environ["PGPORT"]
|
||||
PGUSER = os.environ["PGUSER"]
|
||||
PGPASSWORD = os.environ["PGPASSWORD"]
|
||||
TOPO_DATABASE = os.environ.get("TOPO_DATABASE", "ksp_wiki_topology")
|
||||
|
||||
_BASE_DSN = f"postgresql://{PGUSER}:{PGPASSWORD}@{PGHOST}:{PGPORT}"
|
||||
@@ -26,5 +33,5 @@ WRITER_DATABASE_URL = os.environ.get(
|
||||
)
|
||||
|
||||
API_HOST = os.environ.get("TOPOLOGY_API_HOST", "0.0.0.0")
|
||||
API_PORT = int(os.environ.get("TOPOLOGY_API_PORT", "5000"))
|
||||
API_PORT = int(os.environ.get("TOPOLOGY_API_PORT", "8080"))
|
||||
API_DEBUG = os.environ.get("TOPOLOGY_API_DEBUG", "false").lower() == "true"
|
||||
|
||||
Reference in New Issue
Block a user