Aller au contenu

Session 28 — Audit guards d'accès + revue code scripts-ui & jmeter-ui + correctifs

Durée

~3h


Contexte

Session d'audit et de correction post-Sessions 26–27.

Trois axes de travail :

  1. Audit complet des 6 fichiers modifiés en sessions 26–27 (guards d'accès, admin-users.html, backend Java) pour valider la conformité à la spec.
  2. Revue de code approfondie de scripts-ui/src/server.js et jmeter-ui/src/server.js : documentation, anomalies fonctionnelles, cohérence des commentaires.
  3. Correctifs des anomalies identifiées + ajout du plugin CodeMirror manquant.

Tâche 1 — Audit guards d'accès (Sessions 26–27)

Fichiers audités

Fichier Résultat
scripts-ui/src/server.js ✅ Guard canAccessScripts correct, HTTP 403, isSuperAdmin exempté
jmeter-ui/src/server.js ✅ Guard canAccessJmeter correct, PERFSHOP_API_INTERNAL vérifié au démarrage
chaos-admin/public/login.html data = await r.json() avant r.ok, guard canAccessChaos, 6 droits en sessionStorage
admin/index.html ✅ Guard canAccessAdmin dans doLogin(), auto-reconnect supprimé intentionnellement
monitoring/public/admin/index.html ✅ Guard canAccessMonitoring + bloc finally présent (faux positif d'audit)
chaos-admin/public/admin-users.html ✅ Modal modal-rights, pré-remplissage, saveRights(), délégation événements

Tâche 2 — Chaos Sécurité S11

Vérification que le token SQLi reste fonctionnel malgré les nouveaux guards :

  • AdminPortalControllerAdminController.addValidToken() appelé après bypass SQLi ✅
  • VALID_ADMIN_TOKENS (ConcurrentHashMap) partagé entre les controllers ✅
  • AdminAuth.isAdmin() délègue à AdminController.isValidAdminToken()
  • Mécanisme pédagogique intact : le token S11 bypasse les guards frontend et fonctionne directement via X-Admin-Token sur Spring Boot ✅

Tâche 3 — AdminController (droits V31)

  • login() retourne canAccessJmeter et canAccessScripts
  • createAccount() + updateRights() lisent les 5 droits ✅
  • adminToDto() inclut les 2 nouveaux droits ✅
  • AdminUserService.bootstrapSuperAdmin() force canAccessJmeter = true et canAccessScripts = true

Tâche 2 — Revue de code scripts-ui & jmeter-ui

Anomalies identifiées et corrigées

# Fichier Sévérité Anomalie Correction
1 scripts-ui 🔴 Bug /api/move — DELETE source non capturé → duplication silencieuse si DELETE échoue deleteR capturé + check !deleteR.ok → HTTP 502 + partial:true + log
2 scripts-ui 🟠 Fix /api/syncsuccess:false retourné avec HTTP 200 si SYNC_OK absent HTTP 502 si !ok, HTTP 200 uniquement si SYNC_OK présent
3 jmeter-ui 🟡 Dead code loadRunState() — commentaire running-recovered obsolète (jamais implémenté) Commentaire corrigé — explication du vrai comportement (bloc app.listen())

Documentation ajoutée

scripts-ui/src/server.js : - Header JSDoc : politique de rétention disque (pas de purge automatique des runs) - forgejoEncodePath() : JSDoc expliquant le split/join et pourquoi encodeURIComponent('/') briserait l'URL - forgejoContentsURL() : JSDoc @param/@returns - dockerExec() : JSDoc Detach:false, démultiplexage stream 8 octets, @param/@returns - isValidFilename() / isValidPath() / isValidDirname() : JSDoc enrichis - /api/move : commentaire des 3 étapes + avertissement transaction non atomique - /api/sync : contrat HTTP documenté - /api/runner-status : bandeau PUBLIC explicite avec justification

jmeter-ui/src/server.js : - dockerExec() : JSDoc Detach:true vs Detach:false (scripts-ui), délai détection 10s, renvoi vers /api/logs - PUBLIC_PATHS : justification des 3 chemins exemptés - /api/jmeter/status : bandeau PUBLIC + données agrégées uniquement - parseJmx() : JSDoc stratégie regex, structure de sortie, limite connue - applyJmxModel() : JSDoc comportement timers mixtes (timerIdx/ctIdx indépendants par type)


Tâche 3 — Fix CodeMirror defineSimpleMode

Symptôme

Uncaught TypeError: CodeMirror.defineSimpleMode is not a function
    at (index):17:12

Cause

CodeMirror.defineSimpleMode est défini dans le plugin addon/mode/simple.js, absent du dossier vendor/. Ce plugin n'est pas inclus dans codemirror.min.js.

Correction

Ajout de simple.min.js (CodeMirror 5.65.16, licence MIT) dans vendor/ et référencement dans index.html entre python.min.js et le bloc <script> inline :

<script src="/vendor/codemirror.min.js"></script>
<script src="/vendor/python.min.js"></script>
<script src="/vendor/simple.min.js"></script>   <!-- ajouté -->
<script>
  CodeMirror.defineSimpleMode("robotframework", { ... });
</script>

Ordre de chargement correct : core → mode Python → plugin simple → mode Robot Framework.


Fichiers modifiés

scripts-ui/src/server.js                 (fix /api/move + /api/sync + documentation)
jmeter-ui/src/server.js                  (fix dead code + documentation)
scripts-ui/public/vendor/simple.min.js   (nouveau — plugin CodeMirror defineSimpleMode)
scripts-ui/public/index.html             (ajout <script src="/vendor/simple.min.js">)
mkdocs/docs/vibe-coding/session-28.md   (ce fichier)
mkdocs/docs/vibe-coding/session-index.md (session 28 ajoutée)
mkdocs/mkdocs.yml                        (session 28 dans la nav)

Déploiement NAS

# Scripts UI — server.js + simple.min.js + index.html modifiés
docker compose restart perfshop-scripts-ui

# JMeter UI — server.js modifié
docker compose restart perfshop-jmeter-ui

Erreurs documentées

Aucune erreur fonctionnelle introduite. Un fichier simple.min.js généré manuellement contenait une erreur de syntaxe (SyntaxError ligne 4) — remplacé par le fichier officiel téléchargé depuis le package npm codemirror@5.65.16.