FlowDeck CI / lint (push) Failing after 9s
FlowDeck CI / lint (pull_request) Failing after 4s
FlowDeck CI / test (pull_request) Failing after 1s
FlowDeck CI / docker (pull_request) Skipped
FlowDeck CI / test (push) Failing after 29m57s
FlowDeck CI / docker (push) Skipped
- static/js/recherche.js re-vendangé depuis commons v0.2.1 (source
canonique ui/recherche/) : source ShaarIt (bases, onglet,
normaliseur — lien profond {base}shaare/<shorturl>).
- Gabarit + route /recherche : data-base-shaarit (bases.shaarit),
onglet et section « ShaarIt — bookmarks ».
- recherche_cors : origines ShaarIt prod/dev + clé sœur shaarit.
- Tests : recherche.test.js 83 assertions (5 sections, normaliseur
ShaarIt), onglets Python et allowlist (12 origines) à jour.
107 lines
4.0 KiB
Python
107 lines
4.0 KiB
Python
"""Tests de la recherche fédérée Flowdeck (fusion #68).
|
|
|
|
Fonctions pures de app/middleware/recherche_cors.py uniquement :
|
|
aucune base, aucun serveur.
|
|
"""
|
|
|
|
from app.middleware.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("flowdeck-dev.dracodev.net") is True
|
|
assert is_dev_host("flowdeck.dracodev.net") is False
|
|
assert is_dev_host("x-dev.dracodev.net.evil") is False
|
|
assert is_dev_host("flowdeck-dev.dracodev.net:8443") is True
|
|
assert is_prod_host("flowdeck.dracodev.net") is True
|
|
assert is_prod_host("flowdeck-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("{{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="flowdeck-dev.dracodev.net"
|
|
)
|
|
assert "https://og.dracodev.net" in sister_origins(
|
|
{}, request_host="flowdeck.dracodev.net"
|
|
)
|
|
assert "https://og-dev.dracodev.net" in sister_origins(
|
|
{}, request_host="flowdeck.dracodev.net"
|
|
)
|
|
assert "https://og.dracodev.net" in sister_origins(
|
|
{}, request_host="flowdeck-dev.dracodev.net"
|
|
)
|
|
|
|
|
|
def test_cors_headers():
|
|
headers = cors_headers_for("https://og-dev.dracodev.net", RESOLVED_DEV)
|
|
assert headers["Access-Control-Allow-Origin"] == "https://og-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://kanbante-dev.dracodev.net", RESOLVED_DEV)
|
|
assert headers["Access-Control-Allow-Methods"] == "GET, OPTIONS"
|
|
assert preflight_headers("https://evil.example", RESOLVED_DEV) is None
|