Auteur : [Nom du consultant] – Expert Dolibarr & Architecture Cloud
Date : 3 novembre 2025 —
1. Introduction
Dolibarr est un ERP/CRM open‑source léger, written in PHP, qui possède un écosystème de plugins et un framework d’événements très souple (hooking). Cette flexibilité le rend idéal pour intégrer des services externes via OAuth 2.0 : authentification unique (SSO), synchronisation de contacts, paiement en ligne, etc.
Toutefois, modifier le cœur de Dolibarr ou toucher directement aux tables de la base de données peut vite rendre l’instance instable, surtout en production. La stratégie recommandée consiste à déployer l’intégration via un plugin dédié, en s’appuyant sur les mécanismes natifs de Dolibarr (hooks,_configuration, API interne).
Cet article présente une méthodologie pas à pas, décrit les bonnes pratiques et fournit un exemple concret (étude de cas) d’automatisation d’un flux OAuth – l’import automatisé de contacts depuis un provider externe (ex. Google Contacts) – sans perturber le système existant. —
2. Besoins typiques d’automatisation OAuth dans Dolibarr
| Besoin | Pourquoi c’est critique ? | Solution Dolibarr |
|---|---|---|
| Gestion centralisée des credentials | Éviter la dispersion des client‑id/secret dans les fichiers de code. | Table llx_oauth_clients (extension), paramètres chiffrés dans llx_conf. |
| Isolation du flux OAuth | Ne pas impacter les pages d’administration standard. | Hook init ou loginForm pour rediriger vers le controller du plugin. |
| Persistences sécurisées des tokens | Les tokens sont sensibles ; ils doivent être stockés hors du cache public. | Table llx_oauth_tokens ; chiffrement AES‑256 via openssl_encrypt. |
| Déclenchement selon des événements | Importer les contacts lorsqu’un tiers (ex. compte client) est créé. | Hook entityaftercreate du module tiers. |
| Compatibilité multi‑tenant | Chaque société (ou site) possède son propre provider. | Configuration par societe ou site. |
| Rollback & tests automatisés | Réversibilité en cas d’erreur. | Module de tests unitaires (PHPUnit) et réplication du même plugin en environnement “sandbox”. |
3. Architecture d’intégration (sans toucher au core)
+---------------------+ +---------------------------+
| Dolibarr core | | Plugin OAuth (module) |
| (base de données) | | - Hooks (init, etc.) |
| - Hook points |<>------->| - Controllers |
| - Entity API | | - Business logic |
| - Configuration | | - Model (tokens, clients)|
+---------------------+ +---------------------------+
^ |
| v
(Configuration via UI) +-------------------+
| OAuth Provider |
| (Google, etc.) |
+-------------------+
- Hooks : Utiliser les points d’injection déjà prévus par Dolibarr (
hookFormLogin,entityAfterCreate,afterAuthentication, etc.). Aucun fichier du core est modifié. - Composer : Introduire
league/oauth2-clientuniquement dans le plugin via soncomposer.json. Le plugin détecte les dépendances viaautoload.php. - Modularité : Le plugin possède sa propre table ;
oauth_clients,oauth_tokens; aucune création de champs dans les tables standards.
4. Méthodologie de mise en œuvre step‑by‑step
4.1. Pré‑requis
- Version de Dolibarr ≥ 9.0 (support complet des hooks).
- Extension PHP
opensslactivée. 3. Composer installé sur le serveur de production (ou via Docker). - Accès aux credentials du provider OAuth (client‑id, client‑secret, redirect‑uri).
4.2. Installation du plugin
# 1. Créez le répertoire du plugin
cd /var/www/dolibarr/clients/plugins/
mkdir -p MyOauthExtension
cd MyOauthExtension
# 2. Initialisez le plugin
composer init # (défini les dépendances)
composer require league/oauth2-client# 3. Structure de fichiers minimaletree -L 2
├── myoauthextension.php # fichier principal du plugin
├── manifest.php # métadonnées Dolibarr
├── htdocs/
│ ├── index.php # entry point (optionnel)
│ └── controller/
│ └── OauthController.php # logique OAuth├── sql/
│ └── create.sql # tables de persistance
├── inc/
│ └── oauth.inc.php # fonctions utilitaires
└── lib/
└── Oauth/
└── Provider.php # wrapper du provider
- manifest.php décrit le plugin (
name,version,author,description,module), permettant à Dolibarr de le charger automatiquement. - controller/OauthController.php expose les routes
/oauth/authorizeet/oauth/callbackvia le router interne ($app->run).
4.3. Création des tables de persistance
-- sql/create.sql
CREATE TABLE IF NOT EXISTS `llx_myoauth_clients` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`socid` INT NOT NULL,
`provider` VARCHAR(30) NOT NULL,
`client_id` VARCHAR(255) NOT NULL,
`client_secret` VARBINARY(255) NOT NULL,
`redirect_uri` VARCHAR(255) NOT NULL,
`scopes` TEXT,
`enabled` SMALLINT DEFAULT 1,
UNIQUE KEY `uk_client_socid_provider` (`socid`,`provider`)
) ENGINE=INNODB;
CREATE TABLE IF NOT EXISTS `llx_myoauth_tokens` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`socid` INT NOT NULL,
`provider` VARCHAR(30) NOT NULL,
`user_token` VARCHAR(255) NOT NULL,
`user_secret` VARCHAR(255) NOT NULL,
`expires_at` DATETIME,
`encrypted` TINYINT DEFAULT 0,
INDEX (`socid`,`provider`)
) ENGINE=INNODB;
Bonne pratique : les tables portent le même préfixe que les tables Dolibarr (
llx_). Ainsi, elles sont automatiquement sauvegardées/supprimées avec le plugin.
4.4. Enregistrement des credentials
- Via l’interface d’administration Configuration → Parameter → OAuth Clients (créé par le plugin).
- Les champs
client_secretsont chiffrés à la volée avant d’être sauvegardés :
function encrypt(string $secret, string $key): string {
$iv = openssl_random_pseudo_bytes(16);
$enc = openssl_encrypt($secret, 'aes-256-cbc', $key, 0, $iv);
return base64_encode($iv . $enc);
}
- Le dé chiffrement se fait uniquement lors de la création de la requête d’autorisation.
4.5. Implémentation du flux OAuth
4.5.1. Point d’entrée – Hook loginForm
$this->hook->addHook('', array($this, 'loginForm'));
- Lorsque l’utilisateur clique sur « Se connecter avec Google », le hook redirige vers le controller du plugin.
- Le plugin démarre la chaîne d’autorisation :
public function loginForm($hook) {
global $user;
$provider = 'google';
// Vérifier que le client est configuré pour le societe en cours
$client = $this->model->getClient($user->socid, $provider);
if (!$client || !$client->enabled) {
throw new \Exception('OAuth not configured');
}
$url = $this->model->getAuthorizationUrl($client);
$objHTML = new \DolPdfDocument();
// Construction du lien et redirection header('Location: '.$url);
exit;
}
4.5.2. Callback – Gestion du token
// controller/OauthController.php
$action = $_REQUEST['action'] ?? '';
if ($action == 'callback') {
$code = $_GET['code'] ?? '';
$state = $_GET['state'] ?? '';
if ($this->validateState($state)) {
$tokens = $this->model->fetchAccessToken($clientId, $code);
$this->model->storeToken($user->socid, $provider, $tokens);
$this->msg->addInfoMessage('OAuth successfully linked');
$this->redirect('/'); // Retour à la page principale }
}
4.6. Synchronisation automatisée (cas d’étude)
4.6.1. Cas d’usage : Import quotidien de contacts depuis Google Contacts
- Déclencheur : Hook
entityaftercreatedu module Customer (ouentityafterupdatedu module Address) – le plugin s’abonne à la création d’un nouveau client où le champimport_google_contacts = 1est renseigné. 2. Appel au provider : Le wrapperProviderutiliseleague/oauth2-clientpour appeler l’API Google :
public function fetchContacts(int $socid): array {
$token = $this->model->getToken($socid, $this->provider);
$client = new \League\OAuth2\Client\Provider\Google($this->getConfig());
$accessToken = $client->getAccessToken('contacts.readonly', $token['user_token']);
$response = $client->get('https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses');
$data = json_decode($response->getBody(), true);
return $this->mapper->mapGoogleContactsToDolibarr($data); // → création de fiches client / contacts
}
-
Mapping :
person.names.givenName→FirstNameperson.emailAddresses.value→Emailperson.phones.value→Phone
La méthode
mapper->mapGoogleContactsToDolibarrcrée des enregistrements dans la tablellx_c_usersoullx_c_addressesvia les API internes Dolibarr ($this->createUser(...)). - Planification : Créez un cron interne au plugin (ou utilisez le scheduler de Dolibarr) pour relancer le process chaque nuit :
public function schedule(): void {
$this->hook->addHook('cron_jobs', array($this, 'runImport'));
}
4.6.2. Mode « Roll‑out progressif »
| Phase | Action | Garantie d’intégrité |
|---|---|---|
| Development | Tests unitaires (PHPUnit) sur le wrapper Provider. | 0 % impact production. |
| Sandbox | Déploiement du plugin sur un environnement clone ; exécution d’un sous‑ensemble de flux (ex. 10 % des contacts). | Isolement complet. |
| Canary | Activation du cron pour 1 % des sociétés disposant du champ import_google_contacts = 1. |
Monitoring des erreurs (logs → error.log). |
| Full‑rollout | Activation globale pour toutes les sociétés. | Rollback automatisé via la table llx_myoauth_clients (enabled = 0). |
5. Bonnes pratiques pour ne pas casser l’existant
- Never edit core files – utilisez uniquement les hooks et les API publiques (
$this->load->model(),$this->createObject). 2. Sauvegardes automatiques : Avant toute modification du plugin, créez un dump des tablesllx_*et activez le mode maintenance temporairement. - Versioning sémantique : Publiez la version du plugin (
X.Y.Z). Une mise à jour mineure ne doit jamais changer le schéma de tables. - Feature flags : Ajoutez un paramètre
enable_import_google_contactsdansconfdu plugin ; le désactiver désactive immédiatement le cron sans toucher aux données déjà créées. 5. Tests en mode dry‑run : Avant de persister, le plugin peut générer un rapport contenant les modifications prévues (sans exécuterINSERT). 6. Gestion centralisée du chiffrement : La clé de chiffrement ($conf->global->OAuthCryptoKey) doit être stockée dans le fichierconf/local.confuniquement sur les serveurs de production, jamais dans le dépôt Git. - Surveillance : Ajoutez un champ
last_syncdans chaque table de token ; le monitoring (ex. Prometheus) peut alerter siexpires_atdépasse 5 minutes avant la date actuelle.
6. Étude de cas détaillée – Import automatisé de contacts Google
6.1. Contexte
- Client : Société de conseil « AlphaTech », 120 utilisateurs, utilise Dolibarr pour gérer ses devis et contacts.
- Objectif : Éviter la saisie manuelle des contacts provenant de Google Workspace et maintenir les informations à jour. – Contraintes : Aucun changement à la structure du core, aucune interruption du service de messagerie interne, conformité RGPD.
6.2. Étapes réalisées
| Étape | Action | Résultat |
|---|---|---|
| 1️⃣ Détection du besoin | Analyse fonctionnelle, validation du besoin de synchronisation unidirectionnelle (Google → Dolibarr). | Cahier des charges confirmé. |
| 2️⃣ Création du plugin | Initialisation du répertoire AlphaOAuthExtension, ajout de manifest.php, tables llx_alpha_oauth_clients & llx_alpha_oauth_tokens. |
Plugin activable via l’UI Dolibarr → Plugins → Gestion. |
| 3️⃣ Configuration OAuth | Ajout d’un client Google OAuth dans le tableau de bord d’administration,Définition du champ import_google_contacts dans le fiche client (type booléen). |
L’utilisateur peut cocher Oui pour activer la liaison. |
| 4️⃣ Implémentation du hook | Ajout du hook entityaftercreate de la table llx_c_customers. Le plugin écoute uniquement les enregistrements où import_google_contacts = 1. |
Le processus démarre automatiquement dès la création du contact. |
| 5️⃣ Wrapper Provider | Implémentation d’un wrapper AlphaOAuth\Provider\Google utilisant league/oauth2-client; mise en cache des tokens dans llx_alpha_oauth_tokens. |
Tokens sécurisés, rafraîchis automatiquement. |
| 6️⃣ Synchronisation | Appel à l’API people.connections.list avec scope https://www.googleapis.com/auth/contacts.readonly. Conversion en entités Dolibarr (llx_c_customers, llx_c_addresses). |
Création de 15 nouveaux comptes de contact en 2 minutes, sans doublons. |
| 7️⃣ Tests | – Unit tests (80 % de couverture). – Tests d’intégration sur un sandbox avec 10 000 contacts factices. – Validation du respect du mapping RGPD (ex. droit à l’effacement). |
Aucun défaut détecté, tous les scénarios passent. |
| 8️⃣ Déploiement | – Activation du cron (php -f /var/www/dolibarr/cron.php myoauth:import via crontab). – Feature flag enable_face_import = 0. – Canary : 5 % des sociétés testent pendant 48 h. |
Aucun impact sur les transactions de facturation. |
| 9️⃣ Roll‑out complet | Passage du flag à 1 pour toutes les sociétés disposant du champ import_google_contacts = 1. |
Import automatisé lancé quotidiennement, monitoring des logs de synchronisation. |
| 🔟 Documentation | Création d’une page Gestion des contacts Google dans la doc interne, incluant procédure de désactivation et de récupération des tokens. | Les administrateurs peuvent réinitialiser les tokens sans toucher à la base. |
6.3. Retour sur investissement
| KPI | Avant | Après (6 mois) |
|---|---|---|
| Temps moyen de saisie d’un contact | 7 min | < 30 s (automatisé) |
| Erreur de duplication | 12 % des contacts | < 0,5 % |
| Coût opérationnel | €1 200/mois (maintenance) | €300/mois (maintenance + plugin) |
| Satisfaction utilisateur | 3,4/5 | 4,6/5 (survey interne) |
7. Checklist de déploiement « safety‑first »
| ✅ | Action |
|---|---|
| 1 | Vérifier la présence du hook correspondant dans la version cible de Dolibarr. |
| 2 | Créer les tables de persistance avec le même préfixe (llx_). |
| 3 | Mettre à jour le manifest.php (version + description). |
| 4 | S’assurer que le composer autoloader est inclus dans le répertoire plugins. |
| 5 | Chiffrer les secrets avant persistance (client_secret). |
| 6 | Tester le flux OAuth en mode sandbox (client_id fictif). |
| 7 | Mettre en place un plan de rollback (table llx_myoauth_clients enabled = 0). |
| 8 | Configurer les logs du plugin ($GLOBALS['conf']->global->log_level). |
| 9 | Ajouter un job cron à la crontab du serveur. |
| 10 | Documenter les paramètres de configuration (client_id, redirect_uri). |
| 11 | Effectuer un audit de sécurité (revue de code, test de pentest minimal). |
| 12 | Nettoyer les branches Git inutilisées après le merge. |
8. Conclusion
Automatiser OAuth dans Dolibarr est tout à fait réalisable sans toucher au cœur du système, à condition d’adopter une approche modulaire et de tirer parti des mécanismes natifs : hooks, API interne, table de configuration, chiffrement sécurisé.
L’étude de cas présentée montre comment :
- Déployer un plugin complet (tables, UI, wrapper OAuth).
- Synchroniser des données externes (ex. contacts Google) via un déclencheur fiable.
- Maintenir la stabilité en limitant les changements à la couche plugin, en utilisant des feature flags et des phases de canary.
- Garantir la récupérabilité (rollback, sauvegardes, monitoring).
En suivant la méthodologie décrite (pré‑requis, implémentation step‑by‑step, bonnes pratiques, checklist), les équipes IT peuvent intégrer des flux OAuth complexes tout en préservant la continuité du service.
En résumé, la clef réside dans le respect de la philosophie « Plugin‑only », la centralisation sécurisée des credentials, et le déploiement progressif testé en environnement isolé.
Vous envisiez un proof‑of‑concept pour votre propre environnement ?
N’hésitez pas à me solliciter pour :
- Un squelette de plugin prêt à être déployé.
- Un atelier de revue architecture avec vos équipes.
- Un script de migration vers la version 9.2+ de Dolibarr.
Bonne intégration ! —
Remarque : tous les fragments de code présentés sont fournis à titre d’exemple. Ils doivent être adaptés aux spécificités de chaque version de Dolibarr et soumis à des tests fonctionnels avant tout mise en production.