Automatiser OAuth dans Dolibarr : Étude de cas sans casser l’existant

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-client uniquement dans le plugin via son composer.json. Le plugin détecte les dépendances via autoload.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

  1. Version de Dolibarr ≥ 9.0 (support complet des hooks).
  2. Extension PHP openssl activée. 3. Composer installé sur le serveur de production (ou via Docker).
  3. 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/authorize et /oauth/callback via 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_secret sont 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

  1. Déclencheur : Hook entityaftercreate du module Customer (ou entityafterupdate du module Address) – le plugin s’abonne à la création d’un nouveau client où le champ import_google_contacts = 1 est renseigné. 2. Appel au provider : Le wrapper Provider utilise league/oauth2-client pour 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
}

  1. Mapping :

    • person.names.givenNameFirstName
    • person.emailAddresses.valueEmail
    • person.phones.valuePhone

    La méthode mapper->mapGoogleContactsToDolibarr crée des enregistrements dans la table llx_c_users ou llx_c_addresses via les API internes Dolibarr ($this->createUser(...)).

  2. 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

  1. 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 tables llx_* et activez le mode maintenance temporairement.
  2. Versioning sémantique : Publiez la version du plugin (X.Y.Z). Une mise à jour mineure ne doit jamais changer le schéma de tables.
  3. Feature flags : Ajoutez un paramètre enable_import_google_contacts dans conf du 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écuter INSERT). 6. Gestion centralisée du chiffrement : La clé de chiffrement ($conf->global->OAuthCryptoKey) doit être stockée dans le fichier conf/local.conf uniquement sur les serveurs de production, jamais dans le dépôt Git.
  4. Surveillance : Ajoutez un champ last_sync dans chaque table de token ; le monitoring (ex. Prometheus) peut alerter si expires_at dé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.

Publications similaires