Repository navigation
Публичный каталожный API игнорирует resource_groups — решить, поддерживаем ли #659
Description
Вопрос
Ни один публичный каталожный эндпоинт Web API не учитывает принадлежность ресурса к группам ресурсов (resource_groups).
Проверено грепом по ProductCatalogService, CategoryCatalogService и всем контроллерам src/Controllers/Api/Web/ — ни resource_group, ни checkPolicy(), ни getResourceGroups() не встречаются. Фильтрация ограничена published=1, deleted=0, hidemenu=0 и context_key.
Это означает: товар или категория, закрытые в MODX для веб-группы (например, доступные только авторизованным покупателям или партнёрам), через GET /api/v1/product/get/{id}, product/list, category/* отдаются анонимному клиенту наравне с публичными.
Почему это оформлено вопросом, а не багом
Прежде чем чинить, нужно решение о продуктовой модели. Возможны две позиции, и обе внутренне непротиворечивы:
Позиция А — так и задумано. Headless-каталог по определению публичен, разграничение доступа — забота фронта и отдельных приватных эндпоинтов. Тогда это не дыра, а сознательное упрощение, и его нужно явно задокументировать: «публичный каталожный API не поддерживает закрытые группы ресурсов, не кладите в каталог то, что не должно быть видно анониму». Сейчас такой оговорки нет нигде, и интегратор, привыкший к поведению MODX, разумно ожидает обратного.
Позиция Б — это дыра. Разграничение по группам ресурсов — штатный механизм MODX, магазины им реально пользуются (закрытые разделы для оптовиков, предзаказы, B2B-каталоги). Тогда публичный API обязан его уважать, иначе установка MiniShop3 молча раскрывает то, что владелец закрыл средствами платформы.
Склоняюсь ко второй: мы не можем предполагать, что все пользователи знают о таком расхождении, а цена ошибки — раскрытие данных, о котором владелец магазина не узнает.
Что предстоит решить
- Поддерживаем ли мы
resource_groupsв публичном каталоге вообще. - Если да — как именно. Прямолинейный
checkPolicy()на каждый ресурс даст N+1 на листингах; нужен фильтр на уровне запроса (join/подзапрос поmodResourceGroupResourceс учётом групп текущего пользователя, для анонима — только ресурсы вне закрытых групп). - Что с уже авторизованным покупателем: у нас свой
msCustomer-токен, а группы ресурсов MODX завязаны наmodUser. Связи между ними сейчас нет — это отдельный проектный вопрос, возможно, самый существенный из трёх. - Совместимость: если сегодня кто-то полагается на текущее поведение, включение фильтра изменит выдачу. Нужна ли настройка-переключатель.
Контекст
Замечено при ревью PR #644, но к нему не относится — резолв по alias/uri использует те же publicCriteria(), что и существующий id-based доступ, и ничего не ухудшает. Характеристика всего публичного каталожного API целиком, существует с момента его появления.
Связанное: #654 (реакция API на битые данные), #658 (валидация context — соседний по природе вопрос о том, насколько публичный каталог доверяет входным параметрам).
Activity
Ibochkarev commentedon Sep 8, 2026
Продуктовое решение для реализации:
resource_groups.msCustomer↔modUser/ группы — out of scope.checkPolicy.Ветка:
feat/issue-659-catalog-resource-groupsотbeta.feat(web-api): respect MODX resource group ACL in public catalog
feat(web-api): respect MODX resource group ACL in public catalog
feat(web-api): respect MODX resource group ACL in public catalog
feat(web-api): respect MODX resource group ACL in public catalog
feat(web-api): учитывать ACL групп ресурсов в публичном каталоге (#666)