Alembic construit le moteur directement, sans passer par le fichier ini
build / Garde-fou (pull_request) Successful in 9m29s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (pull_request) Skipped
build / Images Harbor (web, Dockerfile) (pull_request) Skipped
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m44s
build / Garde-fou (push) Successful in 9m31s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m8s

This commit is contained in:
hcornet committed 2026-09-11 08:54:56 +02:00
1 parent 5659c32b66
commit 6c602c97ad
3 files changed
+43 -11

No files matched your search

+5 -1
View File
@@ -36,7 +36,11 @@ Et enfin la revue humaine, qui ne s'automatise pas :
documentée ?
- une valeur venant de l'utilisateur peut-elle contenir un caractère qui casse le format où
on l'insère ? Point-virgule pour le CLAPI, `@` et `:` pour une URL de connexion, guillemet
simple pour le shell. Trois incidents sur ce seul motif.
simple pour le shell, `%` pour un fichier ini lu par configparser. **Quatre** incidents sur
ce seul motif — c'est le premier endroit où regarder.
- une valeur déjà encodée traverse-t-elle un second format qui réinterprète son encodage ?
C'est la variante du piège précédent : `%40` est correct dans une URL, et devient une
interpolation dans un ini.
- ce qui est écrit en base a-t-il traversé `strip_secrets` ?
## Nommage
+6 -10
View File
@@ -11,7 +11,7 @@ import os
import sys
from alembic import context
from sqlalchemy import engine_from_config, pool
from sqlalchemy import create_engine, pool
sys.path.insert(0, os.getcwd())
@@ -19,15 +19,15 @@ from enclume.config import Config
from enclume.db import Base
config = context.config
# Une seule source de verite pour l'URL : celle de l'application, qui sait
# assembler les elements separes et encoder le mot de passe.
config.set_main_option("sqlalchemy.url", Config.SQLALCHEMY_DATABASE_URI)
# L'URL n'est jamais passee par le fichier ini : configparser y verrait des
# interpolations, et un mot de passe encode contient des %.
URL = Config.SQLALCHEMY_DATABASE_URI
target_metadata = Base.metadata
def run_migrations_offline() -> None:
context.configure(
url=config.get_main_option("sqlalchemy.url"),
url=URL,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
@@ -37,11 +37,7 @@ def run_migrations_offline() -> None:
def run_migrations_online() -> None:
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
connectable = create_engine(URL, poolclass=pool.NullPool)
with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)
with context.begin_transaction():
+32
View File
@@ -7,6 +7,7 @@ ici, et la CI reste sans service externe.
from __future__ import annotations
import importlib
import os
from pathlib import Path
import pytest
@@ -388,3 +389,34 @@ def test_les_entetes_du_proxy_sont_honores(app_oidc):
headers={"X-Forwarded-Proto": "https", "X-Forwarded-Host": "enclume.example"},
)
assert vu["url"] == "https://enclume.example/"
def test_alembic_supporte_un_mot_de_passe_encode():
"""Un mot de passe contenant @ devient %40 une fois encode ; Alembic ne doit
pas y voir une interpolation configparser. On lance la vraie commande."""
import subprocess
import sys
environnement = {
**os.environ,
"ENCLUME_DB_HOTE": "hote-inexistant.invalid",
"ENCLUME_DB_MOTDEPASSE": "G00d-P@ssw0rd",
"PATH": os.environ.get("PATH", ""),
}
environnement.pop("ENCLUME_DATABASE_URL", None)
resultat = subprocess.run(
[sys.executable, "-m", "alembic", "upgrade", "head"],
capture_output=True,
text=True,
env=environnement,
timeout=60,
)
sortie = resultat.stdout + resultat.stderr
# Le point verifie : l'URL a ete lue sans etre prise pour un motif
# d'interpolation. L'echec qui suit porte sur la connexion elle-meme.
assert "invalid interpolation" not in sortie, sortie[-800:]
assert any(
marque in sortie
for marque in ("OperationalError", "could not translate", "Name or service not known")
), sortie[-800:]