Le WordPress d'aujourd'hui, décodé pour les développeurs

Sécurité

Modéliser des niveaux de permission avec un enum PHP 8.1 plutôt qu’avec des capacités en chaîne

Une hiérarchie de permissions personnalisée écrite en chaînes de caractères tolère des fautes de frappe silencieuses. Un enum backé par une chaîne les transforme en erreurs détectables.

Par WordPress Développement • 27 avril 2022 • 4 min de lecture • Aucun commentaire
Modéliser des niveaux de permission avec un enum PHP 8.1 plutôt qu'avec des capacités en chaîne

« niveau_permission » égale « editeur_junior » dans une base de données, et « editeur_junoir » dans le code qui vérifie cette valeur quelques lignes plus loin : ce genre de faute de frappe, invisible tant que personne ne teste précisément ce niveau de permission, illustre la fragilité d’une hiérarchie personnalisée modélisée uniquement par des chaînes de caractères libres.

Le contexte : une hiérarchie de permissions au-delà des rôles WordPress

Les rôles et capacités natifs de WordPress couvrent une grande partie des besoins courants, mais une application métier construite sur WordPress introduit parfois une hiérarchie de permissions plus fine que celle exposée par current_user_can(), par exemple pour distinguer plusieurs niveaux d’accès à un espace de documents internes, indépendamment du rôle WordPress de l’utilisateur. Cette hiérarchie interne est souvent modélisée par une simple chaîne stockée en métadonnée utilisateur.

Le problème d’une chaîne de caractères libre

function verifier_acces(string $niveau_permission, string $document): bool
{
    return match ($niveau_permission) {
        'lecture_seule'   => est_document_public($document),
        'editeur_junior'  => est_document_public($document) || est_document_equipe($document),
        'editeur_senior'  => true,
        default           => false,
    };
}

Rien n’empêche, ailleurs dans le code, d’écrire ou de stocker une valeur légèrement différente : 'Editeur_Junior' avec une majuscule, ou 'editeur-junior' avec un trait d’union. Ces variantes tombent silencieusement dans la branche default, refusant l’accès sans qu’aucune erreur ne signale la cause réelle du problème, à savoir une incohérence de nommage plutôt qu’un véritable refus de permission.

L'essentiel à retenir : Une chaîne de caractères libre tolère toute faute de frappe sans avertissement ; Un enum backé restreint les valeurs possibles dès la déclaration de type ; Les rôles WordPress natifs restent gérés séparément, sans enum

La modélisation avec un enum backé

PHP 8.1 introduit les enums, y compris une variante backée par une valeur scalaire, qui restreint les valeurs possibles d’un type à un ensemble fermé et connu au moment de l’écriture du code :

enum NiveauPermission: string
{
    case LectureSeule = 'lecture_seule';
    case EditeurJunior = 'editeur_junior';
    case EditeurSenior = 'editeur_senior';

    public static function depuisChaine(string $valeur): self
    {
        return self::from($valeur);
    }
}

function verifier_acces(NiveauPermission $niveau, string $document): bool
{
    return match ($niveau) {
        NiveauPermission::LectureSeule  => est_document_public($document),
        NiveauPermission::EditeurJunior => est_document_public($document) || est_document_equipe($document),
        NiveauPermission::EditeurSenior => true,
    };
}

La méthode statique NiveauPermission::from(), fournie nativement par les enums backés, lève une erreur ValueError si la chaîne fournie ne correspond à aucun cas déclaré, au lieu de tomber silencieusement dans un comportement par défaut. Une faute de frappe lors de la lecture d’une métadonnée utilisateur devient ainsi une erreur immédiate et explicite, plutôt qu’un refus d’accès dont la cause reste à deviner.

Ce que cette modélisation ne remplace pas

Les rôles et capacités natifs de WordPress, gérés via WP_Role et current_user_can(), restent le mécanisme approprié pour tout ce qui touche à l’administration standard du site : gestion des contenus, des utilisateurs, des réglages. L’enum de permissions personnalisé décrit ici s’ajoute à cette couche pour un besoin métier spécifique, sans jamais s’y substituer.

Points de vigilance lors de la migration

  • Les valeurs stockées en base de données restent des chaînes de caractères : la conversion vers l’enum via from() doit intervenir à la lecture, pas au niveau du schéma de stockage lui-même.
  • Envelopper l’appel à from() dans un bloc try/catch lors de la lecture de données existantes évite qu’une valeur historique incompatible ne provoque une erreur fatale non gérée en production.
  • Documenter chaque cas de l’enum avec un commentaire précisant le périmètre exact qu’il couvre, pour éviter qu’un nouveau développeur ajoute un cas redondant avec un existant.

En résumé

Un enum backé par PHP 8.1 transforme une hiérarchie de permissions modélisée en chaînes de caractères libres en un ensemble fermé de valeurs vérifiées à la lecture. Les fautes de frappe et incohérences de nommage, auparavant absorbées silencieusement par une branche par défaut, deviennent des erreurs explicites et détectables bien avant qu’un utilisateur ne se heurte à un refus d’accès inexpliqué.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi