67 lines
2.5 KiB
Python
67 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import subprocess
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
META_ROOT = Path(__file__).resolve().parents[1]
|
|
RELEASE_ROOT = META_ROOT / "tools" / "release"
|
|
if str(RELEASE_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(RELEASE_ROOT))
|
|
|
|
from server.app import create_app # noqa: E402
|
|
|
|
|
|
class ReleaseConsoleSecurityTests(unittest.TestCase):
|
|
def test_api_token_is_accepted_only_from_header(self) -> None:
|
|
with TestClient(create_app(workspace_root=META_ROOT, token="test-console-token")) as client:
|
|
query_response = client.get("/api/health?token=test-console-token")
|
|
header_response = client.get(
|
|
"/api/health",
|
|
headers={"X-Release-Console-Token": "test-console-token"},
|
|
)
|
|
|
|
self.assertEqual(query_response.status_code, 401)
|
|
self.assertEqual(header_response.status_code, 200)
|
|
|
|
def test_bootstrap_token_uses_and_clears_url_fragment(self) -> None:
|
|
launcher = (RELEASE_ROOT / "release-console.py").read_text(encoding="utf-8")
|
|
webui = (RELEASE_ROOT / "webui" / "index.html").read_text(encoding="utf-8")
|
|
|
|
self.assertIn("#token={token}", launcher)
|
|
self.assertNotIn("?token={token}", launcher)
|
|
self.assertIn("window.location.hash.slice(1)", webui)
|
|
self.assertIn("history.replaceState", webui)
|
|
|
|
def test_tokenless_embedding_is_read_only(self) -> None:
|
|
with TestClient(create_app(workspace_root=META_ROOT)) as client:
|
|
read_response = client.get("/api/health")
|
|
write_response = client.post("/api/selective-plan", json={})
|
|
|
|
self.assertEqual(200, read_response.status_code)
|
|
self.assertEqual(403, write_response.status_code)
|
|
self.assertIn("read-only", write_response.json()["detail"])
|
|
|
|
def test_launcher_rejects_non_loopback_and_tokenless_modes(self) -> None:
|
|
launcher = RELEASE_ROOT / "release-console.py"
|
|
for arguments in (("--host", "0.0.0.0"), ("--no-token",)):
|
|
with self.subTest(arguments=arguments):
|
|
result = subprocess.run(
|
|
(sys.executable, str(launcher), *arguments),
|
|
cwd=META_ROOT,
|
|
check=False,
|
|
text=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
timeout=10,
|
|
)
|
|
self.assertEqual(2, result.returncode)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|