From e3aad01bafcda0ddabeded3331a9add6bfb6f7fa Mon Sep 17 00:00:00 2001 From: Chris Amow Date: Mon, 10 Aug 2026 04:50:12 -0500 Subject: [PATCH] Guard that the OAuth callback stays reachable under CHART_AUTH_TOKEN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The callback is registered with the provider and has to answer an unauthenticated browser redirect. It is exempt by construction — a separate router without the token dependency — but nothing held that in place, and the failure would only appear in production, where the token is the one setting that differs from local, at the last step of a login flow. Co-Authored-By: Claude Opus 5 --- tests/test_auth.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_auth.py b/tests/test_auth.py index 4b3c935..c79f230 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -5,6 +5,7 @@ from starlette.websockets import WebSocketDisconnect from app.api.meta import router as meta_router from app.api.routes import router as api_router +from app.api.schwab_auth import router as schwab_auth_router from app.api.ws import router as ws_router from app.config import Settings from app.runtime import Runtime @@ -19,6 +20,7 @@ def client(tmp_path): ) app = FastAPI() app.include_router(meta_router) + app.include_router(schwab_auth_router) app.include_router(api_router) app.include_router(ws_router) app.state.runtime = Runtime(settings) @@ -31,6 +33,29 @@ def test_open_when_no_token_configured(client): assert client("").get("/api/bars").status_code == 200 +def test_oauth_callback_stays_open_when_a_token_is_set(): + # The provider redirects a browser here and cannot attach the chart token. + # A 401 would break the login flow at its last step, on production only, + # where CHART_AUTH_TOKEN is the one thing that differs from local. + from fastapi import FastAPI as _FastAPI + from app.config import Settings as _Settings + from app.runtime import Runtime as _Runtime + import tempfile, pathlib as _pathlib + + with tempfile.TemporaryDirectory() as tmp: + app = _FastAPI() + app.include_router(meta_router) + app.include_router(schwab_auth_router) + app.include_router(api_router) + app.state.runtime = _Runtime( + _Settings(chart_auth_token="s3cret", + manual_lines_path=_pathlib.Path(tmp) / "manual_lines.json") + ) + probe = TestClient(app) + assert probe.get("/api/qt").status_code == 200 + assert probe.get("/api/status").status_code == 401 + + def test_rejects_missing_token(client): assert client("s3cret").get("/api/bars").status_code == 401