CORS recherche : autoriser la console Spark (agent prod+dev) #43
+11
-2
@@ -10,7 +10,10 @@ testables sans base ni serveur.
|
|||||||
tous projets du workspace) et la regroupe par dépôt.
|
tous projets du workspace) et la regroupe par dépôt.
|
||||||
- La CORS bornée n'autorise que ``GET /api/search``, et seulement
|
- La CORS bornée n'autorise que ``GET /api/search``, et seulement
|
||||||
pour les origines sœurs officielles **prod ET dev, listées
|
pour les origines sœurs officielles **prod ET dev, listées
|
||||||
explicitement** (``PROD_ORIGINS | DEV_ORIGINS``), **plus** les
|
explicitement** (``PROD_ORIGINS | DEV_ORIGINS``), **plus les
|
||||||
|
origines de la console Spark** (``AGENT_ORIGINS`` : agent prod ET
|
||||||
|
dev — fédération de la recherche depuis la console, 2026-10-28),
|
||||||
|
**plus** les
|
||||||
origines résolues par ``app.config`` — jamais ``*``. Correctif
|
origines résolues par ``app.config`` — jamais ``*``. Correctif
|
||||||
2026-10-28 (fusion #68/#69, matrice constatée par Bruno) :
|
2026-10-28 (fusion #68/#69, matrice constatée par Bruno) :
|
||||||
l'ancienne allowlist ne contenait que l'environnement résolu
|
l'ancienne allowlist ne contenait que l'environnement résolu
|
||||||
@@ -44,6 +47,12 @@ DEV_ORIGINS = frozenset({
|
|||||||
"https://kanbante-dev.dracodev.net",
|
"https://kanbante-dev.dracodev.net",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
AGENT_ORIGINS = frozenset({
|
||||||
|
"https://agent.dracodev.net",
|
||||||
|
"https://agent-dev.dracodev.net",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
# Clés du dictionnaire rendu par render() (app/main.py).
|
# Clés du dictionnaire rendu par render() (app/main.py).
|
||||||
_SOEUR_KEYS = ("obsigate", "flowdeck", "tiktak", "kanbante")
|
_SOEUR_KEYS = ("obsigate", "flowdeck", "tiktak", "kanbante")
|
||||||
|
|
||||||
@@ -105,7 +114,7 @@ def sister_origins(
|
|||||||
# Correctif 2026-10-28 : prod ET dev toujours, quelle que soit
|
# Correctif 2026-10-28 : prod ET dev toujours, quelle que soit
|
||||||
# la résolution — ``resolved`` n'ajoute que des origines de
|
# la résolution — ``resolved`` n'ajoute que des origines de
|
||||||
# configuration sans jamais retirer une origine officielle.
|
# configuration sans jamais retirer une origine officielle.
|
||||||
return frozenset(origins) | PROD_ORIGINS | DEV_ORIGINS
|
return frozenset(origins) | PROD_ORIGINS | DEV_ORIGINS | AGENT_ORIGINS
|
||||||
|
|
||||||
|
|
||||||
def cors_headers_for(
|
def cors_headers_for(
|
||||||
|
|||||||
+16
-1
@@ -34,7 +34,7 @@ def test_origin_of():
|
|||||||
|
|
||||||
|
|
||||||
def test_sister_origins_dev():
|
def test_sister_origins_dev():
|
||||||
# Correctif 2026-10-28 : 8 origines officielles, prod ET dev,
|
# Correctif 2026-10-28 : 10 origines officielles (8 sœurs + 2 agent), prod ET dev,
|
||||||
# quelle que soit la résolution.
|
# quelle que soit la résolution.
|
||||||
assert sister_origins(RESOLVED_DEV) == {
|
assert sister_origins(RESOLVED_DEV) == {
|
||||||
"https://og.dracodev.net",
|
"https://og.dracodev.net",
|
||||||
@@ -45,9 +45,24 @@ def test_sister_origins_dev():
|
|||||||
"https://flowdeck-dev.dracodev.net",
|
"https://flowdeck-dev.dracodev.net",
|
||||||
"https://tiktak-dev.dracodev.net",
|
"https://tiktak-dev.dracodev.net",
|
||||||
"https://kanbante-dev.dracodev.net",
|
"https://kanbante-dev.dracodev.net",
|
||||||
|
"https://agent.dracodev.net",
|
||||||
|
"https://agent-dev.dracodev.net",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_cors_headers_agent_console_autorise():
|
||||||
|
# Fédération depuis la console (2026-10-28) : les origines agent
|
||||||
|
# prod ET dev passent, avec credentials ; un tiers reste refusé.
|
||||||
|
for origine in ("https://agent.dracodev.net",
|
||||||
|
"https://agent-dev.dracodev.net"):
|
||||||
|
headers = cors_headers_for(origine, RESOLVED_DEV)
|
||||||
|
assert headers is not None
|
||||||
|
assert headers["Access-Control-Allow-Origin"] == origine
|
||||||
|
assert headers["Access-Control-Allow-Credentials"] == "true"
|
||||||
|
assert cors_headers_for("https://agent.dracodev.net.evil.example",
|
||||||
|
RESOLVED_DEV) is None
|
||||||
|
|
||||||
def test_cors_headers():
|
def test_cors_headers():
|
||||||
headers = cors_headers_for("https://tiktak-dev.dracodev.net", RESOLVED_DEV)
|
headers = cors_headers_for("https://tiktak-dev.dracodev.net", RESOLVED_DEV)
|
||||||
assert headers["Access-Control-Allow-Origin"] == "https://tiktak-dev.dracodev.net"
|
assert headers["Access-Control-Allow-Origin"] == "https://tiktak-dev.dracodev.net"
|
||||||
|
|||||||
Reference in New Issue
Block a user