Приглашение через API с параметром group_names возвращает 403 для владельца группы, если он не админ

Резюме

Пользователь, не являющийся администратором, но являющийся владельцем группы Discourse, может успешно приглашать новых участников с назначением этой группы через диалоговое окно приглашений в веб-интерфейсе. Точно такое же действие через REST API (/invites.json, ключ API с глобальной областью действия, правильный Api-Username) возвращает ошибку 403 invalid_access — но только в том случае, если в теле запроса включены group_names/group_ids. Принципиально важно, что предоставление пользователю статуса Модератора не решает проблему с вызовом API — это делает только предоставление полного статуса Администратора, хотя для всех остальных протестированных сценариев (веб-интерфейс, приглашение через API без привязки к группе) статуса Модератора достаточно.

Окружение

  • Версия Discourse: 2026.7.1
  • Тип ключа API: Глобальная область действия, CheriArchives = точное имя пользователя для тестирования

Шаги для воспроизведения

  1. Создайте пользователя, не являющегося ни администратором, ни модератором (<userid>), и сделайте его владельцем группы <group_name>.
  2. В веб-интерфейсе, от имени <userid>: приглашение без группы → успешно. Приглашение с назначением <group_name> → успешно.
  3. Через API, от имени <userid> (ключ с глобальной областью действия, Api-Username=<userid>):
    • POST /invites.json без group_names → успешно.
    • POST /invites.json с group_names=<group_name> (та же группа, владельцем которой он является) → 403 invalid_access.
  4. Повысьте <userid> до Модератора. Повторите вызов API с группой из шага 3 → по-прежнему 403 invalid_access.
  5. Повысьте <userid> до Администратора. Повторите вызов API с группой из шага 3, с тем же ключом и тем же телом запроса → успешно.

Ожидаемое поведение

Поскольку владение группой само по себе является достаточным разрешением для пользователя, не являющегося персоналом, чтобы назначить эту группу при приглашении через веб-интерфейс, API — аутентифицированное как тот же пользователь через Api-Username — должно уважать то же самое разрешение. Как минимум, Модератор (который является персоналом) не должен вести себя идентично непривилегированному пользователю в данном случае; тот факт, что Модератор терпит неудачу так же, как и пользователь без роли, а успех достигается только с Администратором, указывает на то, что код API проверяет конкретно user.admin?, а не владение группой или даже общий статус персонала (user.staff?, который истинен для модераторов).

Фактическое поведение

API возвращает ошибку 403 для любого приглашения с привязкой к группе, если действующий пользователь не является полным Администратором. Владение группой (подтверждено работающим через веб-интерфейс) и статус Модератора/персонала (подтверждено прямым тестом повышения) оба недостаточны для пути API, несмотря на то, что любой из них достаточен через веб-интерфейс или для случая API без привязки к группе.

Вопрос команде Discourse

Требует ли код приглашения с группой, аутентифицированного через API, явного user.admin?, вместо проверки владения группой или user.staff?, как это делает путь веб-интерфейса / аутентифицированный сессией? Если да, то является ли это намеренным (недокументированным ограничением, специфичным для API) или это ошибка, при которой проверка защиты API расходится с проверкой защиты веб-интерфейса для этого действия?

Готов предоставить полные журналы запросов/ответов (ключ скрыт) по запросу.