Files
ObsiGate/tests/test_recherche_cors.py
T
Spark 606d59f483
CI / lint (pull_request) Successful in 1m25s
CI / security (pull_request) Successful in 20s
CI / test (pull_request) Successful in 4m4s
CI / build (pull_request) Failing after 10m20s
CI / e2e (pull_request) Skipped
ObsiGate 2.83.2 : recherche fédérée — ShaarIt, 5e source de « Rechercher partout »
- frontend/js/recherche.js re-vendangé verbatim depuis commons
  v0.2.1 (source canonique ui/recherche/) : source ShaarIt (bases,
  onglet, normaliseur — lien profond {base}shaare/<shorturl>).
- frontend/recherche.html : data-base-shaarit (jeton URL_SHAARIT),
  onglet et section « ShaarIt — bookmarks ».
- backend/recherche_cors.py : origines ShaarIt prod/dev + clé
  sœur ; backend/main.py : origine ShaarIt dans le connect-src
  CSP de la page /recherche.
- Version synchronisée par scripts/bump_version.py --set 2.83.2
  (VERSION, package.json, desktop, README, ROADMAP, CHANGELOG).
- Tests : recherche.test.mjs 67 assertions (5 sources),
  test_recherche_cors allowlist 12 origines ; suite backend
  complète 1916 passés / 0 échec, ruff et mypy verts.
2026-11-04 17:23:38 +00:00

104 lines
3.9 KiB
Python

"""Tests de la recherche fédérée ObsiGate (fusion #68).
Fonctions pures de backend/recherche_cors.py uniquement : aucune base,
aucun serveur.
"""
from backend.recherche_cors import (
cors_headers_for,
is_dev_host,
is_prod_host,
origin_of,
preflight_headers,
sister_origins,
)
RESOLVED_DEV = {
"obsigate": "https://og-dev.dracodev.net",
"flowdeck": "https://flowdeck-dev.dracodev.net",
"tiktak": "https://tiktak-dev.dracodev.net",
"kanbante": "https://kanbante-dev.dracodev.net",
"agent": "https://agent-dev.dracodev.net",
"gitea": "https://git.dracodev.net",
}
def test_is_dev_host():
assert is_dev_host("og-dev.dracodev.net") is True
assert is_dev_host("og.dracodev.net") is False
assert is_dev_host("x-dev.dracodev.net.evil") is False
assert is_prod_host("og.dracodev.net") is True
assert is_prod_host("og-dev.dracodev.net") is False
def test_origin_of():
assert origin_of("https://og-dev.dracodev.net") == "https://og-dev.dracodev.net"
assert origin_of("https://og-dev.dracodev.net/chemin") == "https://og-dev.dracodev.net"
assert origin_of("{{URL_OBSIGATE}}") is None
def test_sister_origins_dev():
# Correctif 2026-10-28 : origines officielles prod ET dev, quelle
# que soit la résolution ; ShaarIt ajoutée par la fédération
# v0.2.1 (12 origines : 10 sœurs + 2 agent).
assert sister_origins(RESOLVED_DEV) == {
"https://og.dracodev.net",
"https://flowdeck.dracodev.net",
"https://tiktak.dracodev.net",
"https://kanbante.dracodev.net",
"https://shaarit.dracodev.net",
"https://og-dev.dracodev.net",
"https://flowdeck-dev.dracodev.net",
"https://tiktak-dev.dracodev.net",
"https://kanbante-dev.dracodev.net",
"https://shaarit-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_sister_origins_ajoute_env_de_la_requete():
# Correctif 2026-10-28 : configuration muette, quel que soit
# l'hôte de la requête, prod ET dev passent — l'hôte ne
# restreint plus l'allowlist.
assert "https://og-dev.dracodev.net" in sister_origins(
{}, request_host="og-dev.dracodev.net"
)
assert "https://og-dev.dracodev.net" in sister_origins(
{}, request_host="og.dracodev.net"
)
assert "https://og.dracodev.net" in sister_origins(
{}, request_host="og-dev.dracodev.net"
)
def test_cors_headers():
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-Credentials"] == "true"
assert cors_headers_for("https://evil.example", RESOLVED_DEV) is None
assert cors_headers_for("https://og-dev.dracodev.net.evil.example",
RESOLVED_DEV) is None
# Autre environnement autorisé (correctif 2026-10-28).
assert cors_headers_for("https://og.dracodev.net",
RESOLVED_DEV) is not None
def test_preflight_headers():
headers = preflight_headers("https://flowdeck-dev.dracodev.net", RESOLVED_DEV)
assert headers["Access-Control-Allow-Methods"] == "GET, OPTIONS"
assert preflight_headers("https://evil.example", RESOLVED_DEV) is None