Administration générale

Ce guide couvre l’administration générale de l’application (moteur principal). —

Table des matières

  1. Tableau de bord admin
  2. Gestion des utilisateurs
  3. Système de rôles
  4. Méthodes d’authentification
  5. Paramètres de l’application
  6. Système de modules
  7. Sauvegarde et restauration
  8. Journalisation et debug
  9. Sécurité

Moteur principal

1. Tableau de bord admin

Accessible via le menu utilisateur > Administration (visible uniquement avec le rôle app_admin).

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

users

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

creUser

ChampObligatoireNotes
IdentifiantOuiUnique, non modifiable après création
E-mailNon
Mot de passeOui (création)Min. 8 caractères, haché en bcrypt
Méthode d’authOuilocal, ldap ou oauth
RôlesNonCheckboxes groupées par module
LangueNonHérite du défaut si vide
ThèmeNonHérite du défaut si vide
ActifOuiUn 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éthodeUsage
$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.

authMethods

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ètreDescription
HôteAdresse du serveur LDAP (ex. ldap.exemple.com)
PortPort (389 pour LDAP, 636 pour LDAPS)
Base DNRacine de recherche (ex. dc=exemple,dc=com)
Bind DNDN du compte de service (ex. cn=admin,dc=...)
Bind PasswordMot de passe du compte de service (chiffré au repos)
User DN PatternPattern de recherche (ex. uid={user},{base_dn})
TLS insecureAccepter les certificats auto-signés

Variables disponibles dans User DN Pattern :

VariableRemplacé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.

settings

Authentification OAuth / OIDC

ParamètreDescription
Client IDIdentifiant de l’application auprès du fournisseur
Client SecretSecret client (chiffré au repos)
Redirect URIURL de callback (ex. https://app.exemple.com/login.php)
Auth URLURL d’autorisation du fournisseur
Token URLURL d’échange de token

Compatible avec tout fournisseur OpenID Connect (Keycloak, Azure AD, Google, etc.).


5. Paramètres de l’application

Apparence

ParamètreDescription
Thème par défautThème applique aux nouveaux utilisateurs et aux visiteurs
Langue par défautLangue appliquee si l’utilisateur n’a pas de préférence

apparence

SMTP (envoi d’e-mails)

ParamètreDescription
Serveur SMTPNom d’hôte
Port25, 465 (SSL) ou 587 (STARTTLS)
ChiffrementAucun, TLS (STARTTLS) ou SSL. Les certificats auto-signés sont acceptés (relais internes).
Authentification SMTPCheckbox. Decocher pour un relais interne anonyme (pas d’identifiants requis).
IdentifiantActif uniquement si la checkbox est cochée
Mot de passeChiffré au repos. Actif uniquement si la checkbox est cochée
Adresse expéditeurAdresse From:
Nom expéditeurNom 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.

SMTP


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

modules

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 :

CasComportement
Module absentAjoute 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 :

  1. l’application passe en mode maintenance (les app_admin gardent

l’accès) ;

  1. la version installée est sauvegardée dans

securite/backups/module_<nom>_<horodatage>.zip — les 3 sauvegardes les plus récentes sont conservées ;

  1. les fichiers sont remplacés ; en cas d’échec, la version précédente

est restaurée automatiquement ;

  1. 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 ;

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

backups

Périmètre

La sauvegarde couvre l’intégralité du répertoire securite/ :

ContenuFichier
Base de données applicativedatabase.sqlite
Clé de chiffrementmaster.key
Wallets Oraclewallets/
Snapshots CPU schedulecpu_schedule_snapshots/
Autres fichiers secretsTout fichier dans securite/
Important : la clé master.key et la base database.sqlite doivent être sauvegardées ensemble. Perdre la clé rend les mots de passe chiffrés irrécupérables.

Créer une sauvegarde

Deux options :

ActionRésultat
Sauvegarder localementCrée metadata_YYYYMMDD_HHMMSS.zip dans securite/backups/
TéléchargerGénéré le ZIP et le propose en téléchargement

Restaurer une sauvegarde

  1. Depuis un fichier : uploadez un fichier ZIP via le formulaire
  2. 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

FichierContenuActif par défaut
log/app.logÉvénements applicatifs (connexions, erreurs)Oui
log/debug.logMessages de debug détaillésNon
log/trace.logTrace complète de chaque requête HTTPNon

Activation

Dans Paramètres > Debug / Trace :

ParamètreDescription
Mode debugActive debug.log — messages détaillés
Mode traceActive trace.log — chaque requête HTTP avec URL, paramètres, headers

debug

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

MesureDétail
Cookie HttpOnlyJavaScript ne peut pas lire le cookie de session
Cookie SameSite=LaxProtection contre les attaques CSRF cross-site
Cookie SecureTransmis uniquement en HTTPS (si applicable)
RégénérationL’ID de session est régénéré toutes les 5 minutes
Durée de vie1 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
 }