Резюме
Пользователь, не являющийся администратором, но имеющий роль владельца (owner) группы Discourse, может успешно приглашать новых участников с назначением этой группы через диалоговое окно приглашений в веб-интерфейсе. Точно такое же действие через REST API (/invites.json, API-ключ с глобальным доступом, правильный заголовок Api-Username) возвращает ошибку 403 invalid_access — но только если в теле запроса присутствуют параметры group_names/group_ids. Это происходит независимо от того, передается ли group_names в виде простой строки (например, "group_names": "my-group") или в виде массива (например, "group_names": ["my-group"]) — оба формата приводят к идентичной ошибке 403.
Критически важно, что назначение пользователю статуса Модератора не исправляет вызов API — работает только назначение полного статуса Администратора, хотя для всех остальных протестированных сценариев (веб-интерфейс, приглашение через API без привязки к группе) статуса Модератора достаточно.
Окружение
- Версия Discourse: [указать — страница
Admin → Upgrade] - Тип API-ключа: Глобальный доступ,
Api-Username= точное имя пользователя тестового аккаунта
Шаги для воспроизведения
- Создайте пользователя, не являющегося ни администратором, ни модератором (
<userid>), и сделайте его владельцем группы<group_name>. - В веб-интерфейсе, от имени
<userid>: приглашение без группы → успешно. Приглашение с назначением<group_name>→ успешно. - Через API, от имени
<userid>(ключ с глобальным доступом,Api-Username=<userid>):POST /invites.jsonбезgroup_names→ успешно.POST /invites.jsonсgroup_names="<group_name>"(формат строки) → 403invalid_access.POST /invites.jsonсgroup_names=["<group_name>"](формат массива) → 403invalid_access(идентичная ошибка, протестированы оба формата).
- Повысьте
<userid>до Модератора. Повторите вызовы API с группой из шага 3 (оба формата) → всё ещё 403invalid_access. - Повысьте
<userid>до Администратора. Повторите вызовы API с группой из шага 3, с тем же ключом и теми же телами запросов → успешно.
Ожидаемое поведение
Поскольку владения группой достаточно, чтобы пользователь без специальных прав назначил эту группу при приглашении через веб-интерфейс, API — аутентифицированное как тот же самый пользователь через Api-Username — должно уважать те же права доступа. Как минимум, статус Модератора (который является персоналом) не должен вести себя так же, как пользователь без привилегий; тот факт, что Модератор получает ту же ошибку, что и пользователь без роли, а успех достигается только с полным статусом Администратора, указывает на то, что в коде API явно проверяется user.admin?, а не владение группой или даже общий статус персонала (user.staff?, который истинен для модераторов).
Фактическое поведение
API возвращает 403 для любого приглашения с привязкой к группе (в формате строки или массива), если действующий пользователь не является полным Администратором. Ни владение группой (проверено в веб-интерфейсе), ни статус Модератора/персонала (проверено прямым повышением) не являются достаточными для пути API, хотя оба этих условия достаточны для веб-интерфейса или для случая API без привязки к группе.
Вопрос команде Discourse
Требует ли код приглашения с группой через API явной проверки user.admin?, вместо проверки владения группой или user.staff?, как это делает путь веб-интерфейса / аутентифицированный через сессию? Если да, то это намеренное решение (недокументированное ограничение, специфичное для API) или это баг, при котором проверка guardian в API расходится с проверкой guardian в веб-интерфейсе для этого действия?
Готов предоставить полные логи запросов/ответов (с скрытым ключом) по запросу.