Ce guide couvre l’administration générale de l’application (moteur principal). —
Table des matières
- Tableau de bord admin
- Gestion des utilisateurs
- Système de rôles
- Méthodes d’authentification
- Paramètres de l’application
- Système de modules
- Sauvegarde et restauration
- Journalisation et debug
- Sécurité
Moteur principal
1. Tableau de bord admin
Accessible via le menu utilisateur > Administration (visible uniquement avec le rôle app_admin).

Le panneau d’administration est organisé en sections dans la barre latérale gauche :
graph TD A[Administration] --> B[Tableau de bord] A --> C[Utilisateurs] A --> D[Parametres] A --> E[Maintenance] A --> F[Modules] C --> C1[Liste des utilisateurs] C --> C2[Creer un utilisateur] D --> D1[Apparence] D --> D2[Debug / Trace] D --> D3[Methodes d'authentification] D --> D4[SMTP] E --> E1[Sauvegarde et restauration] E --> E2[Mise a jour] F --> F1[Gestion des modules]
2. Gestion des utilisateurs
Accès : app_admin uniquement.
Liste des utilisateurs

Tableau de tous les comptes avec :
- Identifiant, e-mail
- Méthode d’authentification (local / LDAP / OAuth)
- Rôles attribués
- Statut (actif / inactif)
- Dernière connexion
- Actions : modifier, supprimer
Création d’un utilisateur

| Champ | Obligatoire | Notes |
|---|---|---|
| Identifiant | Oui | Unique, non modifiable après création |
| Non | ||
| Mot de passe | Oui (création) | Min. 8 caractères, haché en bcrypt |
| Méthode d’auth | Oui | local, ldap ou oauth |
| Rôles | Non | Checkboxes groupées par module |
| Langue | Non | Hérite du défaut si vide |
| Thème | Non | Hérite du défaut si vide |
| Actif | Oui | Un compte inactif ne peut pas se connecter |
Modification d’un utilisateur
Même formulaire que la création, avec les règles suivantes :
- L’identifiant est en lecture seule
- Le mot de passe est optionnel (vide = conserver l’existant)
- Protection : vous ne pouvez pas retirer votre propre rôle
app_admin ni supprimer votre propre compte
Comptes créés automatiquement (LDAP/OAuth)
Lors d’une première connexion LDAP ou OAuth, un compte est créé automatiquement sans aucun rôle. L’administrateur doit attribuer les rôles manuellement.
3. Système de rôles
Architecture multi-rôles
Chaque utilisateur peut avoir 0 à N rôles. Les rôles sont de deux types :
graph LR subgraph "Roles systeme" A[app_admin<br>Super-administrateur] end subgraph "Roles de module" B[oracle_admin] C[oracle_user] D[module_admin] E[module_user] end A -.->|"acces implicite<br>a tout"| B A -.-> C A -.-> D A -.-> E
app_admin est un super-rôle implicite : tous les contrôlés de rôle (hasRole, hasAnyRole, canAccess, canAccessAsAdmin) renvoient vrai si l’utilisateur le possède.
Rôles déclarés par les modules
Chaque module déclare ses propres rôles dans son descripteur. Convention :
<module>_admin: accès complet au module (configuration + consultation)<module>_user: consultation uniquement
Les rôles sont automatiquement synchronisés dans la table roles au démarrage de l’application (idempotent).
Vérification des rôles dans le code
| Méthode | Usage |
|---|---|
$auth->hasRole('oracle_admin') | Vérifie un rôle spécifique |
$auth->hasAnyRole('oracle_admin', 'oracle_user') | Vérifie au moins un rôle |
$auth->requireRole('oracle_admin') | Bloque avec HTTP 403 si le rôle manque |
4. Méthodes d’authentification
Vue d’ensemble
La configuration des méthodes se fait dans Paramètres > Méthodes d’authentification.

Chaque méthode peut être activée/désactivée indépendamment. Plusieurs méthodes peuvent coexister.
Authentification locale
Aucune configuration requise. Les comptes et mots de passe sont stockés dans la base SQLite de l’application. Les mots de passe sont hachés en bcrypt.
Authentification LDAP
| Paramètre | Description |
|---|---|
| Hôte | Adresse du serveur LDAP (ex. ldap.exemple.com) |
| Port | Port (389 pour LDAP, 636 pour LDAPS) |
| Base DN | Racine de recherche (ex. dc=exemple,dc=com) |
| Bind DN | DN du compte de service (ex. cn=admin,dc=...) |
| Bind Password | Mot de passe du compte de service (chiffré au repos) |
| User DN Pattern | Pattern de recherche (ex. uid={user},{base_dn}) |
| TLS insecure | Accepter les certificats auto-signés |
Variables disponibles dans User DN Pattern :
| Variable | Remplacée par |
|---|---|
{user} | Identifiant saisi |
{base_dn} | Valeur du champ Base DN |
{domain} | Domaine extrait des DC= du Base DN |
Un bouton Tester la connexion permet de valider la configuration.

Authentification OAuth / OIDC
| Paramètre | Description |
|---|---|
| Client ID | Identifiant de l’application auprès du fournisseur |
| Client Secret | Secret client (chiffré au repos) |
| Redirect URI | URL de callback (ex. https://app.exemple.com/login.php) |
| Auth URL | URL d’autorisation du fournisseur |
| Token URL | URL d’échange de token |
Compatible avec tout fournisseur OpenID Connect (Keycloak, Azure AD, Google, etc.).
5. Paramètres de l’application
Apparence
| Paramètre | Description |
|---|---|
| Thème par défaut | Thème applique aux nouveaux utilisateurs et aux visiteurs |
| Langue par défaut | Langue appliquee si l’utilisateur n’a pas de préférence |

SMTP (envoi d’e-mails)
| Paramètre | Description |
|---|---|
| Serveur SMTP | Nom d’hôte |
| Port | 25, 465 (SSL) ou 587 (STARTTLS) |
| Chiffrement | Aucun, TLS (STARTTLS) ou SSL. Les certificats auto-signés sont acceptés (relais internes). |
| Authentification SMTP | Checkbox. Decocher pour un relais interne anonyme (pas d’identifiants requis). |
| Identifiant | Actif uniquement si la checkbox est cochée |
| Mot de passe | Chiffré au repos. Actif uniquement si la checkbox est cochée |
| Adresse expéditeur | Adresse From: |
| Nom expéditeur | Nom affiche |
Le bouton Envoyer un test envoie un vrai e-mail HTML (avec le logo de l’application) à l’adresse saisie. Le log complet de la conversation SMTP (commandes et réponses) s’affiche pour faciliter le diagnostic.

6. Système de modules
Principe
Chaque module est un dossier dans mon-appli/modules/<nom>/ contenant un descripteur module.php. La découverte est automatique au démarrage.
sequenceDiagram participant B as Bootstrap participant M as Module Registry participant DB as Base SQLite B->>M: glob(modules/*/module.php) loop Chaque module M->>DB: INSERT OR IGNORE module M->>DB: INSERT OR IGNORE roles du module end Note over M: Modules decouverts mais pas forcement actifs
Activation / Désactivation

Sur la page Gestion des modules, chaque module est représenté par une carte avec :
- Nom, version, description, icône
- Badge vert (actif) ou rouge (inactif)
- Rôles déclarés
- Dépendances
- Bouton Activer/Désactiver
Règles de dépendance :
- Un module ne peut être active que si tous les modules dont il dépend
(depends_on) sont déjà actifs
- Un module ne peut être désactive que si aucun module actif ne dépend de
lui
Hook d’activation : certains modules exécutent un script de vérification avant activation (ex. vérifier qu’une configuration préalable est en place). En cas d’échec, l’activation est refusée avec un message d’erreur et une redirection vers la page de configuration du module.
Activation groupée (PostgreSQL) : si le module postgresql est inactif, un bouton « Activer PostgreSQL et ses dépendances » apparaît dans l’en-tête de la page. Il active le module postgresql ainsi que tous les modules dont il dépend (depends_on, suivi transitivement), dans l’ordre imposé par les dépendances. Les hooks d’activation et le provisioning de chaque module sont exécutés normalement ; en cas d’échec d’un module, les autres activations se poursuivent et un message récapitule les modules actives et les échecs (avec leur raison). Contrairement à l’activation unitaire, il n’y a pas de redirection vers la page de configuration du module en échec.
Ajout et mise à jour d’un module
En bas de la page Gestion des modules, le formulaire « Ajouter ou mettre à jour un module » accepté une archive ZIP contenant un unique dossier de module, avec son module.php à la racine de ce dossier (format produit par *Developer -> Export d’un module*). Le nom du dossier et la clé name du descripteur doivent coïncider, sinon l’archive est refusée.
Le traitement dépend de l’existence du module :
| Cas | Comportement |
|---|---|
| Module absent | Ajoute désactive. Activez-le ensuite. |
| Module déjà installé | Mis à jour en place, sans désactivation préalable. |
Lors d’une mise à jour, seuls les fichiers du module sont remplacés. Sont conservés : son état actif/inactif, ses rôles et leurs affectations aux utilisateurs, sa configuration et ses tables de données. C’est la différence essentielle avec la suppression, qui elle efface rôles, affectations et configuration.
Déroulé d’une mise à jour :
- l’application passe en mode maintenance (les
app_admingardent
l’accès) ;
- la version installée est sauvegardée dans
securite/backups/module_<nom>_<horodatage>.zip — les 3 sauvegardes les plus récentes sont conservées ;
- les fichiers sont remplacés ; en cas d’échec, la version précédente
est restaurée automatiquement ;
- si le module est actif et déclare un hook d’activation, celui-ci est
rejoué (point d’accroche des migrations de schéma d’une nouvelle version) ; son échec est signale sans désactiver le module ;
- le mode maintenance est levé.
La sauvegarde produite est elle-même une archive de module valide : pour revenir à la version précédente, il suffit de la retéléverser par ce même formulaire.
Si le remplacement échoue et que la restauration échoue aussi, le mode maintenance reste actif volontairement : restaurez la sauvegarde indiquée dans le message d’erreur, puis levez la maintenance depuis *Administration -> Mise à jour*.
Suppression d’un module
Réservée aux modules désactivés. Elle retire le dossier du module puis nettoie la base : ligne modules, rôles du module (et donc leurs affectations aux utilisateurs, en cascade) et fichier de configuration. Les tables de données du module ne sont pas supprimées. Pour livrer une nouvelle version d’un module, utilisez la mise à jour et non le couple suppression + réinstallation.
Configuration de module
Chaque module peut stocker sa configuration dans un fichier JSON securite/modules/<nom>.json (anciennement le champ modules.config, migré automatiquement au démarrage). L’accès se fait via :
$moduleRegistry->getConfig('oracle') // lecture
$moduleRegistry->updateConfig('oracle', [...]) // ecriture
7. Sauvegarde et restauration
Accès : app_admin uniquement.

Périmètre
La sauvegarde couvre l’intégralité du répertoire securite/ :
| Contenu | Fichier |
|---|---|
| Base de données applicative | database.sqlite |
| Clé de chiffrement | master.key |
| Wallets Oracle | wallets/ |
| Snapshots CPU schedule | cpu_schedule_snapshots/ |
| Autres fichiers secrets | Tout fichier dans securite/ |
Important : la clémaster.keyet la basedatabase.sqlitedoivent être sauvegardées ensemble. Perdre la clé rend les mots de passe chiffrés irrécupérables.
Créer une sauvegarde
Deux options :
| Action | Résultat |
|---|---|
| Sauvegarder localement | Crée metadata_YYYYMMDD_HHMMSS.zip dans securite/backups/ |
| Télécharger | Généré le ZIP et le propose en téléchargement |
Restaurer une sauvegarde
- Depuis un fichier : uploadez un fichier ZIP via le formulaire
- Depuis une sauvegarde locale : sélectionnez dans la liste
La restauration :
- Crée automatiquement une sauvegarde pré-restauration
(pre_restore_YYYYMMDD_HHMMSS.zip) avant d’écraser les fichiers
- Extrait fichier par fichier avec rapport de succès/échec
- Restaure les permissions de
master.key(mode 0600)
Attention : la restauration remplace la base de données. Après restauration, les comptes, rôles et configurations reviennent à l’état de la sauvegarde.
Gestion des sauvegardes locales
Le tableau liste les ZIP dans securite/backups/ avec :
- Nom du fichier, taille, date
- Boutons : Restaurer, Supprimer
8. Journalisation et debug
Fichiers de log
| Fichier | Contenu | Actif par défaut |
|---|---|---|
log/app.log | Événements applicatifs (connexions, erreurs) | Oui |
log/debug.log | Messages de debug détaillés | Non |
log/trace.log | Trace complète de chaque requête HTTP | Non |
Activation
Dans Paramètres > Debug / Trace :
| Paramètre | Description |
|---|---|
| Mode debug | Active debug.log — messages détaillés |
| Mode trace | Active trace.log — chaque requête HTTP avec URL, paramètres, headers |

Performance : le mode trace généré un volume important de logs. Ne l’activer que temporairement pour diagnostiquer un problème.
9. Sécurité
Chiffrement au repos
Les secrets (mots de passe LDAP, OAuth, Oracle, wallet CMDB) sont chiffrés avec libsodium (XSalsa20-Poly1305 AEAD).
graph LR A[Mot de passe\nen clair] -->|Crypto::encrypt| B["enc_v1:base64(nonce||ciphertext)"] B -->|Crypto::decrypt| C[Mot de passe\nen clair] D[securite/master.key\n32 octets] --> A D --> B
- Clé maître :
securite/master.key(32 octets, auto-générée,
mode 0600)
- Format : préfixe
enc_v1:suivi du nonce et du ciphertext en
base64
- Idempotence :
Crypto::encrypt()ne re-chiffré pas une valeur
déjà chiffrée ; une chaîne vide reste vide
Protection CSRF
Chaque formulaire POST inclut un jeton CSRF (csrf_token) vérifie côté serveur via hash_equals().
Protection de session
| Mesure | Détail |
|---|---|
| Cookie HttpOnly | JavaScript ne peut pas lire le cookie de session |
| Cookie SameSite=Lax | Protection contre les attaques CSRF cross-site |
| Cookie Secure | Transmis uniquement en HTTPS (si applicable) |
| Régénération | L’ID de session est régénéré toutes les 5 minutes |
| Durée de vie | 1 heure (configurable via SESSION_LIFETIME) |
Requêtes preparees
Toutes les requêtes SQL passent par des paramètres liés (bind). Aucune concaténation de données utilisateur dans les requêtes.
Annexes
Arborescence des fichiers importants
securite/
database.sqlite Base applicative (SQLite)
master.key Cle de chiffrement (mode 0600)
backups/ Sauvegardes ZIP
wallets/<id>/ Wallets Oracle Cloud
cpu_schedule_snapshots/ Snapshots du planning CPU
remediation_oracle.json Taches de remediation planifiees
cmdb.sqlite Cache CMDB local
log/
app.log Journal applicatif
debug.log Debug (si active)
trace.log Trace HTTP (si activee)
mon-appli/
bootstrap.php Point d'entree commun
login.php Authentification
index.php Tableau de bord
admin/ Pages d'administration
modules/oracle/ Module Oracle
i18n/ Fichiers de traduction
assets/ CSS, JS, images
includes/ En-tete, pied de page, navigation
Schéma de la base de données (tables principales)
erDiagram
users ||--o{ user_roles : "possede"
roles ||--o{ user_roles : "attribue a"
users {
int id PK
text username UK
text email
text password_hash
text auth_method
text language
text theme
int active
datetime last_login
}
roles {
int id PK
text name UK
text label
text module
int is_system
}
user_roles {
int user_id FK
int role_id FK
datetime granted_at
}
auth_config {
text method PK
int enabled
text config
}
settings {
text key PK
text value
}
modules {
text name PK
text label
int active
text config
}