fix(config): refuser file:// et userinfo dans le contrat d'endpoint

Retire le schéma file du contrat ExternalEndpoint (CalDAV, Pronote iCal, Blog RSS) : seuls https et le loopback http CalDAV explicite restent acceptés. Rejette les URLs contenant userinfo. Ajoute hide_input_in_errors aux Settings. Réécrit les fixtures file:// en https mocké et ajoute une matrice de tests paramétrée du contrat.

Refs #63
This commit is contained in:
2026-09-13 15:30:00 +02:00
parent d1371cabbb
commit 177286b528
5 changed files with 329 additions and 61 deletions
+6 -5
View File
@@ -54,7 +54,7 @@ def fixture_mock_settings() -> Settings:
return Settings(
pronote=PronoteSettings(
url="https://pronote.example.com",
ical_url=SecretStr("file:///fake/ical.ics"),
ical_url=SecretStr("https://ical.example.test/ical.ics"),
agenda_source="auto",
homework_source="auto",
username="testuser",
@@ -287,7 +287,8 @@ def test_fetch_agenda_ical_mode_failure(mock_fetcher: PronoteFetcher) -> None:
patch("pronote_sync.sources.pronote.fallback.parse_ical") as m_parse_ical,
):
m_fetch_ical.side_effect = OSError(
"Impossible de lire le fichier iCal file:///fake/ical.ics : iCal unreachable"
"Échec de la récupération du flux iCal https://ical.example.test/ical.ics : "
"iCal unreachable"
)
m_parse_ical.side_effect = OSError("iCal parse error")
@@ -296,7 +297,7 @@ def test_fetch_agenda_ical_mode_failure(mock_fetcher: PronoteFetcher) -> None:
assert "Impossible de récupérer l'agenda : la source ical a échoué" in str(exc_info.value)
# Vérifie que le message ne contient pas de secret
assert "file:///fake/ical.ics" not in str(exc_info.value)
assert "https://ical.example.test/ical.ics" not in str(exc_info.value)
def test_fetch_agenda_pronotepy_mode_failure(mock_fetcher: PronoteFetcher) -> None:
@@ -538,8 +539,8 @@ def test_no_secrets_in_error_messages(
patch("pronote_sync.sources.pronote.fallback.parse_ical") as m_parse_ical,
):
error_msg = (
"Impossible de lire le fichier iCal file:///ical?icalsecurise=SECRET_TOKEN_123 : "
"[Errno 2] No such file or directory"
"Échec de la récupération du flux iCal https://ical.example.test/ical.ics"
"?icalsecurise=SECRET_TOKEN_123 : [Errno 2] No such file or directory"
)
m_fetch_ical.side_effect = OSError(error_msg)
m_parse_ical.side_effect = OSError("parse error")