L'invitation API avec le paramètre group_names renvoie une erreur 403 pour un propriétaire de groupe s'il n'est pas administrateur

Résumé

Un utilisateur non administrateur qui est propriétaire d’un groupe Discourse peut réussir à inviter de nouveaux membres avec ce groupe assigné via la boîte de dialogue d’invitation de l’interface web. L’action identique via l’API REST (/invites.json, clé API de portée globale, Api-Username correct) renvoie une erreur 403 invalid_access — mais uniquement lorsque group_names/group_ids est inclus dans la charge utile. Fait crucial, l’attribution du statut Modérateur à l’utilisateur ne corrige pas l’appel API — seule l’attribution d’un statut Administrateur complet le fait, bien que le statut Modérateur soit suffisant pour tous les autres scénarios testés (interface web, invitation API sans groupe).

Environnement

  • Version de Discourse : 2026.7.1
  • Type de clé API : Portée globale, CheriArchives = le nom d’utilisateur exact de l’utilisateur de test

Étapes pour reproduire

  1. Créer un utilisateur non administrateur et non modérateur (<userid>), et le rendre propriétaire du groupe <group_name>.
  2. Interface web, en tant que <userid> : invitation sans groupe → succès. Invitation avec <group_name> assigné → succès.
  3. API, en tant que <userid> (clé de portée globale, Api-Username=<userid>)
    • POST /invites.json sans group_names → succès.
    • POST /invites.json avec group_names=<group_name> (le même groupe dont il est propriétaire) → 403 invalid_access.
  4. Promouvoir <userid> au rang de Modérateur. Répéter l’appel API avec groupe de l’étape 3 → toujours 403 invalid_access.
  5. Promouvoir <userid> au rang d’Administrateur. Répéter l’appel API avec groupe de l’étape 3, même clé, même charge utile → succès.

Comportement attendu

Puisque la simple propriété d’un groupe est une permission suffisante pour qu’un utilisateur non membre du personnel assigne ce groupe lors d’une invitation via l’interface web, l’API — authentifiée en tant que le même utilisateur via Api-Username — devrait respecter la même permission. Au minimum, le statut Modérateur (qui fait partie du personnel) ne devrait pas se comporter de manière identique à celle d’un utilisateur non privilégié ici ; le fait que le Modérateur échoue de la même manière qu’un utilisateur sans rôle, et que seul l’Administrateur réussisse, suggère que le chemin de code de l’API vérifie spécifiquement user.admin? plutôt que la propriété du groupe ou même le statut de personnel général (user.staff?, qui est vrai pour les modérateurs).

Comportement réel

L’API renvoie une erreur 403 pour toute invitation avec groupe, à moins que l’utilisateur agissant ne soit un Administrateur complet. La propriété du groupe (vérifiée comme fonctionnant via l’interface web) et le statut Modérateur/personnel (vérifié via un test de promotion directe) sont tous deux insuffisants pour le chemin de l’API, bien que l’un ou l’autre soit suffisant via l’interface web ou pour le cas de l’API sans groupe.

Question pour l’équipe Discourse

Le chemin de code d’invitation avec groupe authentifié par l’API exige-t-il explicitement user.admin?, plutôt que de vérifier la propriété du groupe ou user.staff? de la même manière que le chemin de l’interface web / authentifié par session ? Si c’est le cas, est-ce intentionnel (restriction spécifique à l’API non documentée) ou s’agit-il d’un bug où la vérification du gardien de l’API diverge de la vérification du gardien de l’interface web pour cette action ?

Je suis disposé à fournir des journaux complets des requêtes/réponses (clé masquée) sur demande.