ajoute le dossier WebDAV de l'élève (bloc C)

Dossier personnel de l'élève monté comme lecteur réseau : rclone
sert le dossier local, l'authentification est déléguée au portail
via auth_request Nginx (mêmes identifiants que la connexion), sans
nouveau système de comptes. Nettoyé par la purge RGPD comme les
autres données d'élève.

Corrige au passage un vrai bug d'isolation trouvé en testant avec
deux comptes jetables : rewrite injectait la variable posée par
auth_request_set, mais rewrite s'exécute dans une phase Nginx
antérieure à cette variable, donc toujours vide - un élève pouvait
lire le fichier d'un autre en devinant son nom. Corrigé par une
location à regex nommée + proxy_pass. Détails : ADR 0008.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-14 13:04:40 +02:00
parent cdf79d2823
commit e549f03e1b
19 changed files with 553 additions and 8 deletions

View file

@ -1199,3 +1199,55 @@ Deux leçons distinctes : d'abord, ne jamais faire confiance à la documentation
**Suite**
Prochain chantier du bloc C, annoncé par Adam : WebDAV, puis ElasticSearch.
## 2026-10-14 — WebDAV de l'élève (bloc C)
Deuxième chantier du bloc C : dossier personnel de l'élève, monté comme
lecteur réseau. Deux bugs réels trouvés et corrigés en vérifiant en vrai sur
le serveur, détaillés dans [ADR 0008](adr/0008-webdav-eleve-auth-request.md).
**Fait**
- `rclone serve webdav` (20 Mo de RAM) sert le dossier local de chaque élève (`storage/app/webdav/<id>/`), accessible en `https://syllabuslab.fr/webdav/` avec les identifiants de connexion habituels.
- L'authentification est déléguée au portail via `auth_request` de Nginx (`WebdavAuthController`, sous-requête interne, jamais appelable depuis l'extérieur) — pas de nouveau système de comptes.
- Page « Mes fichiers » (menu du compte, élève seulement) : explique comment monter le lecteur sous Windows/macOS/Linux.
- Dossier WebDAV de l'élève supprimé automatiquement lors de la purge RGPD d'une classe archivée (comme pour le stockage S3 des devoirs).
**Bug grave trouvé en testant en réel (pas en local)**
Première version : un `rewrite` injectait le sous-dossier de l'élève
(posé par `auth_request_set` après vérification des identifiants) dans le
chemin transmis à rclone. Testé avec deux comptes élèves jetables : le
fichier déposé par le premier atterrissait à la racine du dossier WebDAV
commun, et **le second élève pouvait le lire en devinant juste son nom** —
un élève aurait pu accéder aux fichiers d'un autre. Cause : `rewrite`
s'exécute dans une phase Nginx antérieure à celle où `auth_request_set` pose
sa variable, qui était donc toujours vide au moment du `rewrite`, même
écrite après dans le fichier. Corrigé avec une `location` à regex nommée et
`proxy_pass` construisant l'URL directement (phase plus tardive, la
variable y est déjà posée) — revérifié avec trois comptes élèves jetables,
isolation stricte confirmée (404 propre, jamais le contenu d'un autre),
comptes supprimés ensuite.
Deuxième bug, plus bénin : le cache de répertoires de rclone (distinct du
cache de contenu de fichier, déjà désactivé) ne voyait pas un dossier élève
tout juste créé par Laravel — 404 pendant que le cache n'avait pas encore
rafraîchi sa liste. Corrigé en réduisant ce cache à 1 seconde (volume
d'élèves trop faible pour que ça coûte quoi que ce soit).
**Comprendre**
Aucun test Pest n'aurait pu voir ni l'un ni l'autre bug : les tests
appellent `WebdavAuthController` directement, sans jamais passer par Nginx
ni par rclone — la pile complète (Nginx → auth_request → PHP-FPM → rclone →
disque) n'existe qu'en production. Pour ce genre de chantier (plusieurs
briques d'infra qui communiquent entre elles), la vérification en réel avec
de vraies requêtes HTTP sur deux comptes différents n'est pas une étape de
confort après coup : c'est la seule façon de voir ce bug-là. La leçon
« rewrite s'exécute avant auth_request_set » est aussi le genre de piège
d'ordre des phases Nginx qui ne saute pas aux yeux en relisant le fichier
de haut en bas — une bonne question à savoir expliquer en entretien SRE.
**Suite**
Prochain chantier du bloc C : ElasticSearch.