77 lines
4 KiB
Markdown
77 lines
4 KiB
Markdown
|
|
# ADR 0010 — LTI 1.3 Moodle : une 6ᵉ façon de rejoindre une classe, pas un lancement de lab
|
||
|
|
|
||
|
|
- **Date** : 2026-10-14
|
||
|
|
- **Statut** : accepté
|
||
|
|
|
||
|
|
## Contexte
|
||
|
|
|
||
|
|
CLAUDE.md, section 6 : « Moodle LTI 1.3 (V2) » est listé **avec** les autres
|
||
|
|
façons d'ajouter des élèves (code/QR, import CSV, saisie rapide, invitation
|
||
|
|
e-mail) — pas dans la description de l'espace de lab. Avancé à la demande
|
||
|
|
explicite d'Adam (bloc C terminé, V2 lancée par anticipation).
|
||
|
|
|
||
|
|
## Décisions
|
||
|
|
|
||
|
|
**LTI sert à rejoindre une classe, pas à lancer un lab précis.** Un
|
||
|
|
lancement Moodle authentifie l'élève (OIDC + jeton signé) et le fait
|
||
|
|
atterrir sur son tableau de bord habituel (`eleve.show`) — depuis là, il
|
||
|
|
choisit un lab ou un devoir normalement, par le portail. Construire un
|
||
|
|
lien direct vers un lab précis aurait demandé de router l'admission dans
|
||
|
|
une séance (`SeanceController::admettre`), bien plus complexe, pour un
|
||
|
|
besoin que le CLAUDE.md ne demande pas.
|
||
|
|
|
||
|
|
**L'URL de lancement réutilise `code_classe` existant**
|
||
|
|
(`/lti/lancement/{code_classe}`), pas un nouveau jeton ou une nouvelle
|
||
|
|
table de liaison. Exactement la même donnée que celle déjà affichée pour
|
||
|
|
« Faire rejoindre tes élèves » (code/QR) — LTI est juste une 6ᵉ porte vers
|
||
|
|
la même classe, pas un concept à part.
|
||
|
|
|
||
|
|
**`packbackbooks/lti-1p3-tool` (Apache-2.0)**, recommandé par le CLAUDE.md.
|
||
|
|
Bibliothèque bas niveau (pas de dépendance à un framework) : il faut lui
|
||
|
|
fournir trois implémentations (`ICache`, `ICookie`, `IDatabase`, dans
|
||
|
|
`App\Services\Lti\`) qui s'appuient sur Redis, les cookies et les tables
|
||
|
|
`lti_plateformes`/`lti_deploiements` déjà en place.
|
||
|
|
|
||
|
|
**Élève provisionné automatiquement au premier lancement, retrouvé par
|
||
|
|
`(classe_id, lti_emetteur, lti_sub)` ensuite** — jamais de doublon de
|
||
|
|
compte à chaque connexion. Prénom/nom lus depuis les claims standards
|
||
|
|
(`given_name`/`family_name`, puis `name`, jamais inventés : « Élève » /
|
||
|
|
« Moodle » si Moodle n'envoie rien). Code secret généré au hasard, haché,
|
||
|
|
jamais affiché : cet élève se connecte toujours via Moodle, jamais par
|
||
|
|
identifiant/code comme les autres.
|
||
|
|
|
||
|
|
**Cookie `SameSite=None; Secure` pour le jeton d'état OIDC.** Sans ça, le
|
||
|
|
cookie ne survit jamais au POST final que Moodle envoie depuis son propre
|
||
|
|
domaine — chaque lancement échouerait silencieusement (« Please make sure
|
||
|
|
you have cookies… », message déjà prévu par la bibliothèque pour ce cas
|
||
|
|
précis, qui n'arrive qu'avec un réglage de cookie insuffisant).
|
||
|
|
|
||
|
|
**Sécurité x-pack… non, pas de rapport ici — mais même logique que pour
|
||
|
|
Elasticsearch/Ceph** : une seule clé RSA par plateforme Moodle enregistrée
|
||
|
|
(générée par le portail lui-même à l'enregistrement, `phpseclib4\Crypt\RSA`,
|
||
|
|
jamais collée par Adam), exposée en public via `/lti/cles.json` — c'est le
|
||
|
|
fonctionnement normal du protocole (Moodle doit pouvoir vérifier les jetons
|
||
|
|
que *nous* lui envoyons, si jamais le portail appelle un service LTI plus
|
||
|
|
tard), pas une fuite.
|
||
|
|
|
||
|
|
**Enregistrement manuel, par commande Artisan, jamais une page
|
||
|
|
d'administration.** Une plateforme Moodle se configure une fois par
|
||
|
|
établissement, par Adam, avec des informations lues dans l'administration
|
||
|
|
Moodle — une page web pour ça serait une fonctionnalité sans usage réel
|
||
|
|
(CLAUDE.md, section 8). `lti:enregistrer-plateforme` et
|
||
|
|
`lti:enregistrer-deploiement`, voir `docs/runbooks/lti-moodle.md`.
|
||
|
|
|
||
|
|
## Conséquences
|
||
|
|
|
||
|
|
- Testé avec un jeton LTI réellement signé (RS256, paire de clés générée
|
||
|
|
dans le test), jeu de clés de « Moodle » simulé : lancement validé de
|
||
|
|
bout en bout, élève créé avec le bon prénom/nom, deuxième lancement du
|
||
|
|
même élève ne crée pas de deuxième compte. Pas de vrai Moodle disponible
|
||
|
|
pour vérifier en conditions réelles — à refaire dès qu'Adam a un Moodle
|
||
|
|
de test.
|
||
|
|
- En dette : pas de web service LTI (AGS pour les notes, NRPS pour la
|
||
|
|
liste des inscrits, Deep Linking) — seul le lancement de ressource est
|
||
|
|
géré, comme décidé ci-dessus. Les classes de la bibliothèque pour ces
|
||
|
|
services existent déjà (`LtiAssignmentsGradesService` etc.) si le besoin
|
||
|
|
devient réel.
|