DOCS/kanban/done/620-appairage-d-une-nouvelle-tablette-403-depuis-mars.md
Thomas Fransolet 6221978526 Docs en attente : canal VR et contenu immersif livrés, SectionForm, roadmap
Cartes 600, 610 et 620 closes (back-office XR, ressource 360, appairage tablette),
250 et 320 retirées du planifié, 015 et 330 à jour ; STATUS, roadmap, test-plan,
todo-features et plans VR / frontière immersif alignés ; kanban.html regénéré.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011VxSQeGQYUvPmSEoGdnidA
2026-09-15 20:06:34 +02:00

15 lines
2.7 KiB
Markdown

---
title: L'appairage d'une nouvelle tablette répondait 403 depuis mars
---
<p><strong>Trouvé et corrigé le 12/09</strong>, en écrivant l'appairage du casque : il butait sur le même mur.</p>
<p><code>DeviceController</code> porte <code>[Authorize(InstanceAdmin)]</code> <strong>sur la classe</strong>, et <code>Create</code> n'avait aucune exception. Or une clé d'API ne porte que <code>AppRead</code> et <code>Viewer</code> (<code>ApiKeyAuthenticationHandler</code>), et <code>tablet-app</code> <strong>ne s'authentifie jamais autrement</strong> — aucun appel d'authentification dans tout le repo. <code>POST /api/device</code> répondait donc <strong>403 à toute tablette</strong>.</p>
<p><strong>Depuis quand</strong> : commit <code>a452f4a</code> du <strong>13/03/2026</strong>, dont le message dit lui-même « need to be tested ». <strong>Pourquoi personne ne l'a vu</strong> : une tablette déjà appairée ne rappelle jamais <code>Create</code>. Le parc existant continuait de fonctionner ; seul un <em>nouvel</em> appareil échouait — c'est-à-dire exactement ce qu'on ne fait pas tous les jours.</p>
<p><strong>Correctif</strong> : <code>Create</code> passe en <code>[AllowAnonymous]</code> + <code>[RequireAppKey]</code>, le filtre posé le même jour pour les routes de contenu. Le cloisonnement, lui, était déjà écrit juste en dessous — une clé ne peut créer un appareil que dans <strong>son</strong> instance.</p>
🔴 <strong>Et ce n'était pas que l'appairage.</strong> En auditant les clients le 12/09, deux autres maillons du même mur :</p>
<ul>
<li><code>GET /api/Device/{id}/detail</code> était fermé aux clés lui aussi — or c'est le <strong>premier appel d'une tablette qui démarre</strong> (<code>tablet-app/lib/main.dart:46</code>) : celui qui lui dit quelle configuration afficher. Une tablette <em>déjà appairée</em> ne retrouvait donc plus son contenu au redémarrage. Ouvert de la même façon.</li>
<li><code>tablet-app/lib/main.dart:38</code> reconstruisait son client <strong>sans clé</strong><code>Client(host)</code> au lieu de <code>Client(host, apiKey: …)</code> — alors que la clé <em>est</em> persistée en base locale (<code>TabletAppContext.toMap</code>). Une ligne, et tous les appels d'après partaient anonymes.</li>
</ul>
<p>Les deux se tenaient : la route refusait les clés, et l'app n'en envoyait pas. Corrigés ensemble.</p>
<p>⚠️ <strong>À vérifier sur le terrain</strong> : appairer une <em>vraie</em> nouvelle tablette, <strong>et redémarrer une tablette déjà appairée</strong>. Le correctif est couvert par les tests, mais les tests appellent le contrôleur directement — <strong>aucun filtre d'autorisation ne s'y exécute</strong>, donc ils ne prouvent rien sur l'accès lui-même.</p>