Skip to content

feat(mgr-api): document-level ACL для category products - #473

Open
Ibochkarev wants to merge 3 commits into
betafrom
feat/issue-445-category-document-acl
Open

feat(mgr-api): document-level ACL для category products#473
Ibochkarev wants to merge 3 commits into
betafrom
feat/issue-445-category-document-acl

Conversation

@Ibochkarev

Copy link
Copy Markdown
Member

Описание

Добавлен resource-level ACL (checkPolicy) для Manager API «Товары категории»: поверх глобальных view_document / msproduct_* (#378) проверяются права MODX на документ категории и каждый товар.

  • Read (getList, getFilters): view на категорию; в списке — view на товар, при nested=1 также view на родительскую категорию товара.
  • Write (sort, multiple, publish): save / publish / delete (+ составные save+unpublish, save+undelete как в legacy processors).
  • Единый реестр action → permission + document policies в CategoryProductActionPermissions.

Closes #445

Тип изменений

  • Исправление бага (non-breaking change)
  • Новая функциональность (non-breaking change)
  • Breaking change (изменение, ломающее обратную совместимость)
  • Рефакторинг (без изменения функциональности)
  • Документация
  • Другое (опишите):

Связанные Issues

Closes #445

Дополнительно: дополняет #378; не заменяет category scope IDOR из #418 / PR #443.

Как это было протестировано?

cd core/components/minishop3
composer ci:php   # exit 0
  • php -l — 378 PHP-файлов, exit 0

  • Smoke: CategoryProductDocumentPolicyTest.php, CategoryProductActionPermissionsTest.php и остальные 19 тестов — exit 0

  • Ручное тестирование

  • Автоматические тесты (composer ci:php)

  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: branch feat/issue-445-category-document-acl
  • MODX: не требовался (smoke без MODX)
  • PHP: 8.2+

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность (ужесточение ACL)
  • Лексиконы добавлены на двух языках (ru/en) — сообщения на англ., как в соседнем ProductDataService
  • PHPStan проходит без новых ошибок (локально; в CI пока нет)
  • ESLint проходит без ошибок (npm run lint:ci для Vue) — Vue не затронут
  • Обновлён CHANGELOG.md (для значимых изменений)

Дополнительные заметки

  • getList: total из SQL может быть выше числа видимых строк после document ACL filter на странице (pagination edge case); данные недоступных товаров не отдаются.
  • Web API не затронут (scope issue).

@Ibochkarev Ibochkarev added the enhancement New feature or request label Jul 29, 2026
@Ibochkarev
Ibochkarev requested a review from biz87 July 29, 2026 02:16
Add checkPolicy view/save/publish/delete on CategoryProductsController
endpoints to complement global msproduct_* permissions (#378).
@Ibochkarev
Ibochkarev force-pushed the feat/issue-445-category-document-acl branch from 94b0f94 to ae8c4bd Compare July 29, 2026 11:35
CategoryProductsControllerScopeTest failed after #445 because sort
requires a category with checkPolicy(view) and products with save.
Ibochkarev added a commit that referenced this pull request Jul 29, 2026
Apply CategoryProductDocumentPolicy save check on the updateProductData
inline-edit path (#473 pattern) and resolve scope via
CategoryProductScopePolicy through findInCategory() instead of the
separate isProductInCategoryScope() bool-only getObject round-trip.

- Import CategoryProductDocumentPolicy (cherry-picked from #473)
- Refactor CategoryProductScopeService::findInCategory nested branch to
  delegate to CategoryProductScopePolicy::isParentInScope
- Replace isProductInCategoryScope() call in updateProductData with
  scopeService()->findInCategory() (single lookup, yields product for ACL)
- Add 403 save-policy guard + logDocumentPolicyDenied helper
- Tests: CategoryProductDocumentPolicyTest + ACL denial / out-of-scope
  cases in CategoryProductsControllerScopeTest; stubs support per-product
  policies and lexicon
Over-fetch visible rows for paginated grids, count ACL-visible total,
batch-load products for view filter, and return 403 when bulk actions
are denied solely by document policy.
Ibochkarev added a commit that referenced this pull request Jul 29, 2026
Apply CategoryProductDocumentPolicy save check on the updateProductData
inline-edit path (#473 pattern) and resolve scope via
CategoryProductScopePolicy through findInCategory() instead of the
separate isProductInCategoryScope() bool-only getObject round-trip.

- Import CategoryProductDocumentPolicy (cherry-picked from #473)
- Refactor CategoryProductScopeService::findInCategory nested branch to
  delegate to CategoryProductScopePolicy::isParentInScope
- Replace isProductInCategoryScope() call in updateProductData with
  scopeService()->findInCategory() (single lookup, yields product for ACL)
- Add 403 save-policy guard + logDocumentPolicyDenied helper
- Tests: CategoryProductDocumentPolicyTest + ACL denial / out-of-scope
  cases in CategoryProductsControllerScopeTest; stubs support per-product
  policies and lexicon
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Manager API: document-level ACL для category products

1 participant