diff --git a/app_new/__init__.py b/app_new/__init__.py index 098ecb7..43cf9d7 100644 --- a/app_new/__init__.py +++ b/app_new/__init__.py @@ -62,6 +62,12 @@ def create_app(config_name='default'): config_class = config_dict[config_name] app.config.from_object(config_class) config_class.init_app(app) + + # Affiché notamment dans le setup wizard afin d'identifier sans ambiguïté + # le code réellement exécuté par un conteneur, même avant installation. + from .core.build_info import get_build_commit + app.config['GIT_COMMIT'] = get_build_commit() + app.context_processor(lambda: {'build_commit': app.config['GIT_COMMIT']}) # Initialisation des extensions db.init_app(app) diff --git a/app_new/core/build_info.py b/app_new/core/build_info.py new file mode 100644 index 0000000..8005dc2 --- /dev/null +++ b/app_new/core/build_info.py @@ -0,0 +1,33 @@ +"""Informations sur le build actuellement exécuté.""" + +import os +import subprocess +from pathlib import Path + + +def get_build_commit(): + """Retourne l'identifiant du commit déployé. + + En production, le dépôt Git n'est pas forcément présent dans l'image : + les variables d'environnement sont donc prioritaires. Le fallback Git + permet de conserver un affichage utile en développement. + """ + for variable in ("GIT_COMMIT", "COMMIT_SHA", "SOURCE_VERSION"): + value = (os.environ.get(variable) or "").strip() + if value: + return value + + repository = Path(__file__).resolve().parents[2] + try: + result = subprocess.run( + ["git", "rev-parse", "HEAD"], + cwd=repository, + check=True, + capture_output=True, + text=True, + timeout=1, + ) + except (OSError, subprocess.SubprocessError): + return "inconnu" + commit = result.stdout.strip() + return commit or "inconnu" diff --git a/app_new/templates/setup_wizard/index.html b/app_new/templates/setup_wizard/index.html index 196f692..d373e82 100644 --- a/app_new/templates/setup_wizard/index.html +++ b/app_new/templates/setup_wizard/index.html @@ -6,6 +6,7 @@

Configuration initiale GMAO

+
Commit déployé : {{ build_commit }}
diff --git a/app_new/templates/setup_wizard/setup_complete.html b/app_new/templates/setup_wizard/setup_complete.html index a837134..51edb31 100644 --- a/app_new/templates/setup_wizard/setup_complete.html +++ b/app_new/templates/setup_wizard/setup_complete.html @@ -10,6 +10,7 @@

Configuration terminée

Le système GMAO a déjà été configuré.

+

Commit déployé : {{ build_commit }}

Accueil @@ -18,4 +19,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/tests/integration/test_auth_setup.py b/tests/integration/test_auth_setup.py index b2a7077..dc927b8 100644 --- a/tests/integration/test_auth_setup.py +++ b/tests/integration/test_auth_setup.py @@ -1,6 +1,33 @@ from pathlib import Path +def test_build_commit_prefers_deployment_environment(monkeypatch): + from app_new.core.build_info import get_build_commit + + monkeypatch.setenv('GIT_COMMIT', 'commit-deploye-test') + monkeypatch.setenv('COMMIT_SHA', 'autre-commit') + assert get_build_commit() == 'commit-deploye-test' + + +def test_setup_pages_display_build_commit(client, monkeypatch, tmp_path): + from app_new.core.routes import setup_wizard + + monkeypatch.setattr(setup_wizard, 'DATA_DIR', str(tmp_path)) + monkeypatch.setenv('GIT_COMMIT', 'commit-visible-test') + client.application.config['GIT_COMMIT'] = 'commit-visible-test' + token = 'test-setup-token-with-at-least-32-characters' + + response = client.get(f'/setup-wizard/?token={token}') + assert response.status_code == 302 + response = client.get('/setup-wizard/') + assert b'commit-visible-test' in response.data + + Path(tmp_path, '.setup_complete').write_text('complete', encoding='utf-8') + response = client.get('/setup-wizard/') + assert response.status_code == 200 + assert b'commit-visible-test' in response.data + + def test_login_page_does_not_disclose_demo_passwords(client): response = client.get('/auth/login') assert response.status_code == 200