The Archive page's GET /calls/search failed its CORS preflight (OPTIONS -> 405, no Access-Control-* headers). Allow the app origin(s) explicitly for the standard methods and the authorization/content-type headers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tbknwttzou4s46PAykmtix
56 lines
2.2 KiB
Python
56 lines
2.2 KiB
Python
"""
|
|
CORS must never end up as "any origin, WITH credentials".
|
|
|
|
Starlette does not reject `allow_origins=["*"]` combined with
|
|
`allow_credentials=True`. It reflects the caller's Origin back in
|
|
Access-Control-Allow-Origin and still sends
|
|
Access-Control-Allow-Credentials: true, so the effective policy is the
|
|
opposite of what a wildcard usually means. main.py never enables
|
|
credentials at all (auth is a Bearer header, not a cookie), which makes
|
|
that pair unrepresentable; these tests hold it to that.
|
|
|
|
The policy lives in a pure function so it can be exercised directly --
|
|
reloading app.main to vary settings drags every router back through import
|
|
and is not worth the fragility.
|
|
"""
|
|
from starlette.middleware.cors import CORSMiddleware
|
|
|
|
from app.config import settings
|
|
from app.main import app, cors_allows_credentials
|
|
|
|
|
|
def test_wildcard_alone_disables_credentials():
|
|
assert cors_allows_credentials(["*"]) is False
|
|
|
|
|
|
def test_wildcard_among_real_origins_still_disables_credentials():
|
|
# A list that merely CONTAINS "*" is as permissive as ["*"] alone --
|
|
# Starlette treats any wildcard entry as allow-all.
|
|
assert cors_allows_credentials(["https://app.example.com", "*"]) is False
|
|
|
|
|
|
def test_credentials_never_enabled_even_for_named_origins():
|
|
# Auth here is a Bearer header, not a cookie, so credentialed CORS is
|
|
# never needed. The predicate is hard-off regardless of the origin list.
|
|
assert cors_allows_credentials(["https://app.example.com"]) is False
|
|
assert cors_allows_credentials([]) is False
|
|
|
|
|
|
def test_the_app_actually_mounted_that_policy():
|
|
"""Guards the wiring, not just the helper: a future edit to main.py that
|
|
hardcodes allow_credentials=True again fails here."""
|
|
opts = next(
|
|
(mw.kwargs for mw in app.user_middleware if mw.cls is CORSMiddleware), None
|
|
)
|
|
assert opts is not None, "CORSMiddleware is not mounted at all"
|
|
assert opts["allow_credentials"] is False
|
|
assert opts["allow_credentials"] is cors_allows_credentials(settings.cors_origins)
|
|
|
|
|
|
def test_health_exposes_a_build_stamp():
|
|
"""CI compares this against the commit it just deployed; a deploy that
|
|
leaves the previous container running is otherwise invisible."""
|
|
from app.main import _GIT_SHA
|
|
|
|
assert isinstance(_GIT_SHA, str) and _GIT_SHA
|