API-Einladung mit group_names-Parameter liefert 403 für Gruppeninhaber, es sei denn, sie sind Admin

Zusammenfassung

Ein Nicht-Admin-Benutzer, der Inhaber einer Discourse-Gruppe ist, kann über den Web-UI-Einladungsdialog erfolgreich neue Mitglieder mit dieser Gruppe einladen. Die identische Aktion über die REST-API (/invites.json, Global-Scope-API-Schlüssel, korrektes Api-Username) liefert einen 403-Fehler invalid_access – aber nur, wenn group_names/group_ids in der Nutzlast enthalten ist. Dies tritt unabhängig davon auf, ob group_names als einfacher String (z. B. "group_names": "my-group") oder als Array (z. B. "group_names": ["my-group"]) übergeben wird – beide Formate erzeugen den identischen 403-Fehler.

Entscheidend ist, dass die Erteilung des Moderator-Status den API-Aufruf nicht behebt – nur die Erteilung der vollen Admin-Rechte funktioniert, obwohl Moderator für alle anderen getesteten Szenarien (Web-UI, API-Einladung ohne Gruppe) ausreicht.

Umgebung

  • Discourse-Version: [einfügen – Seite Admin → Upgrade]
  • API-Schlüsseltyp: Globaler Scope, Api-Username = der exakte Benutzername des Testbenutzers

Schritte zur Nachbildung

  1. Erstelle einen Nicht-Admin-, Nicht-Moderator-Benutzer (<userid>), der Inhaber der Gruppe <group_name> ist.
  2. Web-UI, als <userid>: Einladung ohne Gruppe → erfolgreich. Einladung mit zugewiesener <group_name> → erfolgreich.
  3. API, als <userid> (Global-Scope-Schlüssel, Api-Username=<userid>):
    • POST /invites.json ohne group_names → erfolgreich.
    • POST /invites.json mit group_names="<group_name>" (String-Format) → 403 invalid_access.
    • POST /invites.json mit group_names=["<group_name>"] (Array-Format) → 403 invalid_access (identischer Fehler, beide Formate getestet).
  4. Erhöhe <userid> zum Moderator. Wiederhole die gruppenspezifischen API-Aufrufe aus Schritt 3 (beide Formate) → weiterhin 403 invalid_access.
  5. Erhöhe <userid> zum Admin. Wiederhole die gruppenspezifischen API-Aufrufe aus Schritt 3, gleicher Schlüssel, gleiche Nutzlasten → erfolgreich.

Erwartetes Verhalten

Da die Gruppeneigentümerschaft allein ausreicht, damit ein Nicht-Staff-Benutzer über die Web-UI diese Gruppe bei der Einladung zuweist, sollte die API – authentifiziert als derselbe Benutzer über Api-Username – dieselbe Berechtigung anerkennen. Mindestens sollte Moderator (der zum Staff gehört) hier nicht identisch mit einem nicht privilegierten Benutzer agieren; die Tatsache, dass Moderator identisch mit der Rolle „keine Berechtigung“ fehlschlägt und nur Admin erfolgreich ist, deutet darauf hin, dass der API-Code-Pfad spezifisch user.admin? prüft, anstatt die Gruppeneigentümerschaft oder sogar den allgemeinen Staff-Status (user.staff?, was für Moderatoren wahr ist) zu prüfen.

Tatsächliches Verhalten

Die API liefert bei jeder gruppenspezifischen Einladung (String- oder Array-Parameterformat) einen 403-Fehler, es sei denn, der handelnde Benutzer ist ein vollwertiger Admin. Gruppeneigentümerschaft (funktioniert über die Web-UI verifiziert) und Moderator-/Staff-Status (durch direkten Erhöhungstest verifiziert) sind für den API-Pfad beide unzureichend, obwohl eines davon über die Web-UI oder für den API-Fall ohne Gruppe ausreichen würde.

Frage an das Discourse-Team

Erfordert der über die API authentifizierte Code-Pfad für Einladungen mit Gruppe explizit user.admin?, anstatt die Gruppeneigentümerschaft oder user.staff? zu prüfen, wie es der Web-UI-/Session-authentifizierte Pfad tut? Wenn ja, ist dies beabsichtigt (undokumentierte, API-spezifische Einschränkung) oder ein Bug, bei dem die API-Guardian-Prüfung von der Web-Guardian-Prüfung für diese Aktion abweicht?

Ich kann auf Anfrage vollständige Request/Response-Protokolle (Schlüssel unkenntlich gemacht) bereitstellen.