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

2.7 KiB

title
title
L'appairage d'une nouvelle tablette répondait 403 depuis mars

Trouvé et corrigé le 12/09, en écrivant l'appairage du casque : il butait sur le même mur.

DeviceController porte [Authorize(InstanceAdmin)] sur la classe, et Create n'avait aucune exception. Or une clé d'API ne porte que AppRead et Viewer (ApiKeyAuthenticationHandler), et tablet-app ne s'authentifie jamais autrement — aucun appel d'authentification dans tout le repo. POST /api/device répondait donc 403 à toute tablette.

Depuis quand : commit a452f4a du 13/03/2026, dont le message dit lui-même « need to be tested ». Pourquoi personne ne l'a vu : une tablette déjà appairée ne rappelle jamais Create. Le parc existant continuait de fonctionner ; seul un nouvel appareil échouait — c'est-à-dire exactement ce qu'on ne fait pas tous les jours.

Correctif : Create passe en [AllowAnonymous] + [RequireAppKey], 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 son instance.

🔴 Et ce n'était pas que l'appairage. En auditant les clients le 12/09, deux autres maillons du même mur :

  • GET /api/Device/{id}/detail était fermé aux clés lui aussi — or c'est le premier appel d'une tablette qui démarre (tablet-app/lib/main.dart:46) : celui qui lui dit quelle configuration afficher. Une tablette déjà appairée ne retrouvait donc plus son contenu au redémarrage. Ouvert de la même façon.
  • tablet-app/lib/main.dart:38 reconstruisait son client sans cléClient(host) au lieu de Client(host, apiKey: …) — alors que la clé est persistée en base locale (TabletAppContext.toMap). Une ligne, et tous les appels d'après partaient anonymes.

Les deux se tenaient : la route refusait les clés, et l'app n'en envoyait pas. Corrigés ensemble.

⚠️ À vérifier sur le terrain : appairer une vraie nouvelle tablette, et redémarrer une tablette déjà appairée. Le correctif est couvert par les tests, mais les tests appellent le contrôleur directement — aucun filtre d'autorisation ne s'y exécute, donc ils ne prouvent rien sur l'accès lui-même.