assistant-hub / symfony-connector
Connecteur Symfony réutilisable pour Assistant Hub
Package info
github.com/Air1455/assistant-hub-symfony-connector
Type:symfony-bundle
pkg:composer/assistant-hub/symfony-connector
Requires
- php: >=8.2
- ext-json: *
- ext-openssl: *
- ext-pdo: *
- ext-pdo_sqlite: *
- psr/cache: ^3.0
- symfony/cache: ^6.4 || ^7.0
- symfony/config: ^6.4 || ^7.0
- symfony/dependency-injection: ^6.4 || ^7.0
- symfony/framework-bundle: ^6.4 || ^7.0
- symfony/http-client: ^6.4 || ^7.0
- symfony/http-foundation: ^6.4 || ^7.0
- symfony/routing: ^6.4 || ^7.0
- symfony/yaml: ^6.4 || ^7.0
Requires (Dev)
- phpunit/phpunit: ^11.0
README
Bundle Symfony générique à installer dans chaque site relié à Assistant Hub. Il s’exécute côté site et communique exclusivement avec l’API officielle configurée.
Responsabilités fournies
- découverte publique minimale ;
- interface
/connector, session et CSRF ; - jumelage par API à jetons ou par session Symfony existante ;
- Authorization Code + PKCE ;
- transmission du login à l’API officielle ;
- coffre AES-256-GCM et stockage SQLite propre ;
- paires HMAC, horodatage et nonces anti-rejeu ;
- catalogue fermé et préfiltrage par rôles ;
- capacités CRUD configurées avec méthode et chemin borné ;
- point d'extension
CapabilityInterfacepour les workflows métier du site ; - adaptateurs bornés ;
- propositions, confirmations et audit local ;
- réservation atomique et résultat idempotent des écritures confirmées ;
- révocation locale.
Le bundle ne fournit aucune règle métier et ne doit importer aucune entité, repository ou table du site.
Installation
composer require assistant-hub/symfony-connector:^0.1
Activez AssistantHubConnectorBundle, importez config/routes.yaml, puis créez
config/packages/assistant_hub_connector.yaml. Les exemples complets se trouvent
dans examples/config/ et la procédure détaillée dans
docs/implementation-guide.md.
Pour développer le paquet depuis le monorepo Assistant Hub, utilisez un
repository Composer de type path.
Configuration minimale avec une API à jetons
assistant_hub_connector: connector_id: 'example-site' connector_name: 'Example site' storage_path: '%kernel.project_dir%/var/assistant-hub/connector.sqlite' encryption_key: '%env(ASSISTANT_HUB_CONNECTOR_KEY)%' pairing_identity_provider: 'api_token' api_base_url: 'https://api.example.test' allowed_hub_redirect_uris: - 'https://hub.example.test/sites/callback' authentication: login_path: '/auth/login' refresh_path: '/auth/refresh' capabilities: contact_list: id: 'crm.contact.list' version: '1.0' kind: 'read' title: 'Lister les contacts' description: 'Retourne les contacts visibles par le compte connecté.' method: 'GET' path: '/contacts' accept: 'application/json' input_schema: type: object additionalProperties: false
Les identifiants, URLs, méthodes et chemins proviennent exclusivement de cette configuration locale. Le Hub ne peut pas les remplacer.
Pour une application Symfony à pages serveur utilisant déjà form_login, le
connecteur peut réutiliser la session locale pour le consentement sans créer de
JWT ni copier le cookie de session :
assistant_hub_connector: connector_id: 'example-site' connector_name: 'Example site' storage_path: '%kernel.project_dir%/var/assistant-hub/connector.sqlite' encryption_key: '%env(ASSISTANT_HUB_CONNECTOR_KEY)%' pairing_identity_provider: 'symfony_session' allowed_hub_redirect_uris: - 'https://hub.example.test/sites/callback'
Dans ce mode, l’application hôte protège /connector/authorize avec son
firewall habituel et fournit une autorisation locale qui recharge l’utilisateur
et ses droits à chaque appel signé. La paire HMAC reste indépendante de la durée
de la session du navigateur.
Deux niveaux d'extension
Pour un appel API simple, utilisez le YAML. Un chemin peut contenir un segment
{recordId} si ce paramètre est déclaré et requis dans input_schema. Les
segments sont encodés et ne permettent pas de changer l'origine.
Pour un workflow composé, créez dans l'application hôte un service implémentant
CapabilityInterface. Avec l'autoconfiguration Symfony, il rejoint
automatiquement le catalogue fermé. Cette classe peut injecter les services
applicatifs explicites du site ; elle porte alors seule la logique métier, la
revalidation transactionnelle et le schéma de sortie. Le Hub et le package
générique restent inchangés.
Adaptateurs
Un service SiteCapabilityAdapterInterface peut transformer les paramètres validés et normaliser la réponse. Il est automatiquement enregistré avec l'autoconfiguration Symfony. Il ne peut changer ni l’origine, ni la méthode, ni le chemin configuré. Le client générique construit lui-même les en-têtes d’autorisation et d’idempotence.
Écritures confirmées
Pour une capacité write, requiresConfirmation est forcé à true. La proposition est persistée avant confirmation. Lors de l’exécution :
- la confirmation exacte est vérifiée ;
- la proposition passe atomiquement de
pendingàexecuting; - les droits sont réévalués ;
- l’API reçoit une clé
Idempotency-Keystable ; - le résultat passe à
completedet sera restitué lors d’un rejeu ; - un échec passe à
failedet n’est jamais rejoué automatiquement.
Si l’API peut avoir réussi mais que le résultat ne peut être persisté, l’état reste executing pour imposer une réconciliation manuelle. Une capacité d’écriture réelle ne doit être activée que si l’API officielle honore l’idempotence.
Mode démonstration
demo_mode est désactivé par défaut et interdit en production. Il remplace seulement l’authentification de paire et l’autorisation locale pour les exemples sans persistance métier. Le stockage par défaut des propositions reste SQLite.
Validation
composer validate --strict php vendor/bin/phpunit
La recette inter-produits se lance depuis le Hub et charge le starter comme package local sans effectuer de requête réseau :
cd apps/hub vendor\bin\simple-phpunit.bat --bootstrap vendor/autoload.php tests\EndToEnd\LocalProtocolJourneyTest.php
Limites
- en mode
api_token, l'identité doit être incluse dans la réponse de login ; - la révocation distante configurée n'est pas encore exécutée ;
- pas de limitation de débit intégrée ;
- rotation multi-clés et sauvegarde SQLite à définir pour la production ;
- réconciliation des états
executingencore manuelle ; - la sécurité finale dépend aussi de l’API officielle et de son implémentation d’
Idempotency-Key; - la recette générique E2E utilise une API officielle simulée.
Commencer par docs/implementation-guide.md. Voir aussi docs/adapting.md et
docs/protocol.md.