vendredi 25 septembre 2026

À propos

Contact

Sécurité

Capacités personnalisées WordPress : créer un rôle sur mesure sans tout casser

Créer un rôle « éditeur de produits » avec des capacités précises plutôt que d'accorder administrator par facilité. Recette pas à pas et pièges des capacités mal héritées.

Par Clément Hadrot • 17 juin 2021 • 5 min de lecture • Aucun commentaire
Capacités personnalisées WordPress : créer un rôle sur mesure sans tout casser

Un client vendant du mobilier sur mesure via WooCommerce nous demande de créer un accès pour ses deux commerciaux, chargés de mettre à jour les fiches produits (descriptions, prix, stock) sans toucher au reste du site. La solution la plus rapide, et la plus mauvaise, consisterait à leur attribuer le rôle administrator « pour ne pas avoir de problème de droits ». C’est pourtant ce que fait la majorité des sites que nous reprenons en maintenance : un rôle unique surdimensionné, distribué par facilité, jamais revu ensuite.

La bonne approche demande quelques minutes de plus mais élimine une classe entière de risques : si le compte d’un commercial est un jour compromis (mot de passe réutilisé, poste infecté), l’attaquant n’hérite que des capacités strictement nécessaires à la gestion des produits, jamais de la possibilité d’installer une extension, de modifier un thème ou de créer un autre compte administrateur.

Choisir les capacités plutôt que le rôle

WordPress distingue deux notions souvent confondues : le rôle (une étiquette, comme editor ou administrator) et la capacité (une permission précise, comme edit_posts ou manage_options). Un rôle n’est en réalité qu’un ensemble nommé de capacités. Vérifier les droits d’un utilisateur avec current_user_can( 'manage_options' ) est donc toujours préférable à current_user_can( 'administrator' ), qui teste en réalité une capacité fantôme peu fiable plutôt qu’une permission réelle.

Pour notre rôle « éditeur de produits », les besoins réels se limitent à :

  • Voir et modifier les produits WooCommerce (type de contenu product).
  • Gérer les termes de taxonomie associés (catégories et étiquettes de produit).
  • Téléverser des images pour illustrer les fiches.
  • Consulter (sans modifier) les commandes, pour vérifier un stock réservé.

Rien ne justifie l’accès aux réglages du site, aux extensions, aux thèmes, ni aux comptes d’autres utilisateurs.

Créer le rôle avec add_role

L'essentiel à retenir : administrator par facilité est le réflexe à bannir ; Un rôle hérite implicitement de ses capacités listées, pas d'un autre rôle ; Toujours prévoir la désinstallation du rôle créé
add_action( 'init', 'moncpt_creer_role_editeur_produits' );

function moncpt_creer_role_editeur_produits() {
    // On ne recrée pas le rôle s'il existe déjà : add_role() échouerait
    // silencieusement, mais on évite aussi de réinitialiser les capacités
    // à chaque chargement, coûteux et inutile.
    if ( get_role( 'editeur_produits' ) ) {
        return;
    }

    add_role(
        'editeur_produits',
        __( 'Éditeur de produits', 'moncpt' ),
        array(
            'read'                   => true,
            'edit_products'          => true,
            'edit_published_products'=> true,
            'upload_files'           => true,
            'assign_product_terms'   => true,
        )
    );
}

Ce code doit s’exécuter une seule fois, typiquement dans register_activation_hook() plutôt qu’à chaque chargement sur init — l’exemple ci-dessus inclut une vérification d’existence précisément pour limiter les écritures répétées en base, mais l’activation reste l’endroit le plus propre pour cette création.

Les capacités edit_products, edit_published_products et assign_product_terms ne sont pas génériques : elles correspondent au type de contenu personnalisé product défini par WooCommerce avec des capability_type spécifiques. Pour un type de contenu personnalisé maison, les noms de capacités suivent le même principe et se définissent via l’argument capabilities de register_post_type().

Le piège de l’héritage mal compris

Erreur fréquente : croire qu’un rôle personnalisé « hérite » automatiquement des capacités d’un rôle existant si son nom y ressemble, ou que les capacités se cumulent entre rôles attribués simultanément d’une façon intuitive. En réalité, chaque capacité listée dans add_role() doit être explicite ; il n’existe aucune notion de rôle parent en WordPress. Un développeur pressé recopie parfois les capacités de editor presque intégralement « pour être sûr que ça marche », puis retire une à une celles qui semblent gênantes — une méthode qui laisse invariablement des capacités oubliées, comme edit_others_posts ou delete_others_pages, sans lien avec le besoin réel.

La bonne méthode part du besoin fonctionnel vers la capacité, jamais l’inverse. Pour vérifier ce qu’un rôle contient réellement une fois créé, WP-CLI évite toute ambiguïté :

wp role list --fields=name,role
wp cap list editeur_produits

Vérifier côté code, pas seulement côté rôle

Une fois le rôle créé, chaque écran ou action réservée aux éditeurs de produits doit vérifier la capacité précise, jamais le nom du rôle en dur :

// À proscrire : fragile si le rôle est renommé ou si un utilisateur cumule plusieurs rôles
if ( in_array( 'editeur_produits', wp_get_current_user()->roles, true ) ) { /* ... */ }

// À privilégier : robuste et cohérent avec le reste de WordPress
if ( current_user_can( 'edit_products' ) ) { /* ... */ }

Sur ce projet, réduire le rôle à six capacités précises plutôt que d’accorder administrator a aussi eu un effet inattendu et bienvenu : les deux commerciaux ne voyaient plus dans leur tableau de bord que les écrans utiles à leur travail, ce qui a réduit les questions de support autant que le risque.

Prévoir la désinstallation

Un rôle personnalisé créé par une extension doit être retiré proprement si l’extension est désinstallée, faute de quoi il reste indéfiniment en base, avec des capacités qui ne correspondent plus à rien :

register_uninstall_hook( __FILE__, 'moncpt_nettoyer_role_editeur_produits' );

function moncpt_nettoyer_role_editeur_produits() {
    remove_role( 'editeur_produits' );
}

Pour aller plus loin

Cette recette ne couvre pas le fonctionnement général de current_user_can() face aux capacités méta (comme edit_post appliquée à un article précis via le filtre map_meta_cap), déjà traité séparément. Retenez le principe directeur : partir des tâches réellement confiées à un utilisateur, les traduire en capacités précises, et ne jamais accorder par défaut ce qui n’a pas été explicitement justifié.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi