FEAT: Détection automatique des caméras — pool de credentials par site + scan agent #48

Closed
opened 2026-08-11 13:57:51 +02:00 by nonobis · 1 comment
Owner

Feature — à remplir avant de commencer

Source de vérité : docs/MASTER_SPECIFICATION.md (v2.0). Citer les numéros de partie/phase/étape.

🎯 Contexte

Un agent est installé sur un réseau local avec des caméras IP. La détection automatique des caméras ne fonctionne pas : l'utilisateur doit ajouter chaque caméra manuellement (nom, RTSP, credentials), ce qui est inacceptable pour un déploiement multi-caméras. Le besoin : déclarer N couples login/mdp possibles par site (pool de credentials), et les agents détectent automatiquement toutes les caméras compatibles sur leur réseau.

📚 Référence spec

Étape 2 — Phase 13 « API Caméras + ONVIF », section ONVIF Device Discovery (lignes ~1390-1395, 1425-1431, 1459) : POST /api/sites/{siteId}/onvif/discover → scan WS-Discovery sur le sous-réseau du site ; POST /api/cameras/onvif/probe {ip, port, username, password} → interroge avec credentials ; « Découverte ONVIF réseau : scan automatique des caméras ».

✅ Comportement attendu

  1. Pour un site, l'admin déclare x couples login/mdp (pool de credentials chiffrés) utilisables pour interroger les caméras du réseau.
  2. L'agent (qui est sur le réseau des caméras) scanne automatiquement son sous-réseau et détecte toutes les caméras compatibles : probing ONVIF avec authentification (tentative de chaque couple du pool), mDNS/HTTP/ARP/ports en complément.
  3. Les caméras détectées remontent au central ; l'utilisateur confirme (ou auto-ajout configurable) — plus jamais de saisie manuelle d'URL/credentials par caméra.
  4. Les URLs de flux sont construites/testées automatiquement depuis la base de caméras intégrée + credentials du pool.

🔍 État actuel

  • DiscoveryController (/api/discovery/*) existe : probe IP, scan subnet (CIDR fourni par le client), search DB, build-urls, test-streams, confirm, check. Aucune UI ne l'expose → la création de caméra reste 100 % manuelle.
  • CameraDiscoveryService : scan complet côté central (Heimdall.Web) — si le central n'est pas sur le réseau caméras, le scan ne voit rien.
  • OnvifProbeService : WS-Discovery unicast + GetDeviceInformation sans aucune authentification → la plupart des caméras protégées ne répondent pas / renvoient une erreur SOAP → non classées comme caméras.
  • CameraCredentials : 1:1 avec une Camera (pas de pool par site). Entité Site sans credentials.
  • Agent (Heimdall.Agent) : aucune logique de découverte.
  • Tests existants : handlers Application + Infrastructure (probes, scan, confirm) + Integration DiscoveryControllerTests.

🧩 Découpage proposé

  1. Modèle : entité SiteCredential (SiteId, Label, Username, Password chiffrée via ICredentialProtector) + migration EF + config.
  2. API central : CRUD credentials du site (/api/sites/{id}/credentials) ; endpoints discovery conformes spec (/api/sites/{siteId}/onvif/discover, /api/cameras/onvif/probe avec username/password).
  3. Probe authentifié : OnvifProbeService + GetDeviceInformation avec WS-UsernameToken (ONVIF) en utilisant chaque couple du pool.
  4. Agent discovery : service de scan réseau local (réutilise probes ARP/ports/mDNS/HTTP/ONVIF), récupère le pool de credentials du site via le central, remonte les résultats (CameraDiscoveryResult + POST depuis l'agent).
  5. UI : gestion des credentials par site (SitesPage) + page/wizard « Caméras détectées » (grille, statut probe, confirm en un clic).
  6. Tests : domain/application/infrastructure/agent + integration.

🧪 Critères d'acceptation

  • Déclaration de N couples login/mdp par site via UI/API, chiffrés en DB
  • Probe ONVIF authentifié : une caméra protégée répond quand un couple du pool est valide
  • L'agent scanne son sous-réseau et remonte les caméras détectées au central
  • Confirmation d'une découverte → Camera créée sans saisie manuelle d'URL/credentials
  • make test vert

📁 Fichiers concernés (estimés)

  • src/Heimdall.Domain/Entities/SiteCredential.cs (nouveau), Site.cs
  • src/Heimdall.Infrastructure/Services/Discovery/* (OnvifProbeService, CameraDiscoveryService)
  • src/Heimdall.Agent/Services/* (nouveau service discovery)
  • src/Heimdall.Web/Controllers/DiscoveryController.cs, pages Blazor (SitesPage, nouvelles pages)
  • tests/*
## Feature — à remplir avant de commencer > Source de vérité : `docs/MASTER_SPECIFICATION.md` (v2.0). Citer les numéros de partie/phase/étape. ### 🎯 Contexte Un agent est installé sur un réseau local avec des caméras IP. La **détection automatique des caméras ne fonctionne pas** : l'utilisateur doit ajouter chaque caméra manuellement (nom, RTSP, credentials), ce qui est inacceptable pour un déploiement multi-caméras. Le besoin : déclarer **N couples login/mdp possibles par site** (pool de credentials), et les **agents détectent automatiquement toutes les caméras compatibles** sur leur réseau. ### 📚 Référence spec Étape 2 — Phase 13 « API Caméras + ONVIF », section **ONVIF Device Discovery** (lignes ~1390-1395, 1425-1431, 1459) : `POST /api/sites/{siteId}/onvif/discover` → scan WS-Discovery sur le sous-réseau du site ; `POST /api/cameras/onvif/probe {ip, port, username, password}` → interroge avec credentials ; « Découverte ONVIF réseau : scan automatique des caméras ». ### ✅ Comportement attendu 1. Pour un site, l'admin déclare **x couples login/mdp** (pool de credentials chiffrés) utilisables pour interroger les caméras du réseau. 2. L'**agent** (qui est sur le réseau des caméras) scanne automatiquement son sous-réseau et **détecte toutes les caméras compatibles** : probing ONVIF **avec authentification** (tentative de chaque couple du pool), mDNS/HTTP/ARP/ports en complément. 3. Les caméras détectées remontent au central ; l'utilisateur **confirme** (ou auto-ajout configurable) — plus jamais de saisie manuelle d'URL/credentials par caméra. 4. Les URLs de flux sont construites/testées automatiquement depuis la base de caméras intégrée + credentials du pool. ### 🔍 État actuel - `DiscoveryController` (`/api/discovery/*`) existe : probe IP, scan subnet (CIDR fourni par le client), search DB, build-urls, test-streams, confirm, check. **Aucune UI ne l'expose** → la création de caméra reste 100 % manuelle. - `CameraDiscoveryService` : scan complet côté **central** (Heimdall.Web) — si le central n'est pas sur le réseau caméras, le scan ne voit rien. - `OnvifProbeService` : WS-Discovery unicast + `GetDeviceInformation` **sans aucune authentification** → la plupart des caméras protégées ne répondent pas / renvoient une erreur SOAP → non classées comme caméras. - `CameraCredentials` : 1:1 avec une Camera (pas de pool par site). Entité `Site` sans credentials. - Agent (`Heimdall.Agent`) : **aucune logique de découverte**. - Tests existants : handlers Application + Infrastructure (probes, scan, confirm) + Integration `DiscoveryControllerTests`. ### 🧩 Découpage proposé 1. **Modèle** : entité `SiteCredential` (SiteId, Label, Username, Password chiffrée via `ICredentialProtector`) + migration EF + config. 2. **API central** : CRUD credentials du site (`/api/sites/{id}/credentials`) ; endpoints discovery conformes spec (`/api/sites/{siteId}/onvif/discover`, `/api/cameras/onvif/probe` avec username/password). 3. **Probe authentifié** : `OnvifProbeService` + `GetDeviceInformation` avec WS-UsernameToken (ONVIF) en utilisant chaque couple du pool. 4. **Agent discovery** : service de scan réseau local (réutilise probes ARP/ports/mDNS/HTTP/ONVIF), récupère le pool de credentials du site via le central, remonte les résultats (`CameraDiscoveryResult` + POST depuis l'agent). 5. **UI** : gestion des credentials par site (SitesPage) + page/wizard « Caméras détectées » (grille, statut probe, confirm en un clic). 6. **Tests** : domain/application/infrastructure/agent + integration. ### 🧪 Critères d'acceptation - [ ] Déclaration de N couples login/mdp par site via UI/API, chiffrés en DB - [ ] Probe ONVIF authentifié : une caméra protégée répond quand un couple du pool est valide - [ ] L'agent scanne son sous-réseau et remonte les caméras détectées au central - [ ] Confirmation d'une découverte → Camera créée sans saisie manuelle d'URL/credentials - [ ] `make test` vert ### 📁 Fichiers concernés (estimés) - `src/Heimdall.Domain/Entities/SiteCredential.cs` (nouveau), `Site.cs` - `src/Heimdall.Infrastructure/Services/Discovery/*` (OnvifProbeService, CameraDiscoveryService) - `src/Heimdall.Agent/Services/*` (nouveau service discovery) - `src/Heimdall.Web/Controllers/DiscoveryController.cs`, pages Blazor (SitesPage, nouvelles pages) - `tests/*`
Author
Owner

Clôturé par 9c7295d (branche feat/camera-discovery-agent).

Ce qui a été fait :

  • L'enrichissement ONVIF authentifié est déplacé côté agent : le pool de credentials du site est exposé via GET /api/settings/agent/{id} dans une enveloppe AES-256-GCM (clé dérivée du hash SHA-256 de l'API key de l'agent) — déchiffrable uniquement côté agent.
  • NetworkCameraScanner tente GetDeviceInformation avec chaque couple du pool (PasswordDigest puis PasswordText) et remonte des devices déjà identifiés (fabricant/modèle ONVIF + label du credential utilisé).
  • Le central ne fait plus d'appels réseau ONVIF pour les découvertes soumises : il persiste et marque le credential utilisé (LastUsedAt).
  • SettingsController.GetEffectiveConfig accepte désormais l'API key agent (vérification par site) — auparavant l'agent recevait 403 sur cet endpoint.
  • SitesController broadcast ConfigReload après add/delete credential pour que les agents re-fetch leur pool.
  • Tests : Application 346, Agent 108, Infrastructure 143 (hors Testcontainers), Web.Tests 213 — nouveaux bUnit DiscoveriesPage (5) et SiteDetail credentials (4).
Clôturé par `9c7295d` (branche `feat/camera-discovery-agent`). **Ce qui a été fait :** - L'enrichissement ONVIF authentifié est déplacé côté **agent** : le pool de credentials du site est exposé via `GET /api/settings/agent/{id}` dans une enveloppe AES-256-GCM (clé dérivée du hash SHA-256 de l'API key de l'agent) — déchiffrable uniquement côté agent. - `NetworkCameraScanner` tente `GetDeviceInformation` avec chaque couple du pool (PasswordDigest puis PasswordText) et remonte des devices déjà identifiés (fabricant/modèle ONVIF + label du credential utilisé). - Le central ne fait plus d'appels réseau ONVIF pour les découvertes soumises : il persiste et marque le credential utilisé (`LastUsedAt`). - `SettingsController.GetEffectiveConfig` accepte désormais l'API key agent (vérification par site) — auparavant l'agent recevait 403 sur cet endpoint. - `SitesController` broadcast `ConfigReload` après add/delete credential pour que les agents re-fetch leur pool. - Tests : Application 346, Agent 108, Infrastructure 143 (hors Testcontainers), Web.Tests 213 — nouveaux bUnit DiscoveriesPage (5) et SiteDetail credentials (4).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nonobis/Heimdall#48
No description provided.