From f2b1166ce1717988646080a44bc658b170942113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Tue, 25 Nov 2025 16:02:50 +0100 Subject: [PATCH 1/3] Updated performAccessCheck doc --- .../src/Controller/CustomController.php | 42 +------------ .../Controller/CustomLimitationController.php | 59 +++++++++++++++++++ docs/permissions/custom_policies.md | 2 +- docs/permissions/permission_overview.md | 17 ++---- 4 files changed, 67 insertions(+), 53 deletions(-) create mode 100644 code_samples/back_office/limitation/src/Controller/CustomLimitationController.php diff --git a/code_samples/back_office/limitation/src/Controller/CustomController.php b/code_samples/back_office/limitation/src/Controller/CustomController.php index 8806f635c9..e94a847e0d 100644 --- a/code_samples/back_office/limitation/src/Controller/CustomController.php +++ b/code_samples/back_office/limitation/src/Controller/CustomController.php @@ -2,56 +2,16 @@ namespace App\Controller; -use App\Security\Limitation\CustomLimitationValue; use Ibexa\Contracts\AdminUi\Controller\Controller; -use Ibexa\Contracts\AdminUi\Permission\PermissionCheckerInterface; -use Ibexa\Contracts\Core\Repository\PermissionResolver; use Ibexa\Contracts\User\Controller\AuthenticatedRememberedCheckTrait; -use Ibexa\Contracts\User\Controller\RestrictedControllerInterface; use Ibexa\Core\MVC\Symfony\Security\Authorization\Attribute; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -class CustomController extends Controller implements RestrictedControllerInterface +class CustomController extends Controller { use AuthenticatedRememberedCheckTrait { AuthenticatedRememberedCheckTrait::performAccessCheck as public traitPerformAccessCheck; } - public function __construct( - // ..., - private readonly PermissionResolver $permissionResolver, - private readonly PermissionCheckerInterface $permissionChecker - ) { - } - - // Controller actions... - public function customAction(Request $request): Response - { - // ... - if ($this->getCustomLimitationValue()) { - // Action only for user having the custom limitation checked - } - - return new Response('...'); - } - - private function getCustomLimitationValue(): bool - { - $hasAccess = $this->permissionResolver->hasAccess('custom_module', 'custom_function_2'); - - if (is_bool($hasAccess)) { - return $hasAccess; - } - - $customLimitationValues = $this->permissionChecker->getRestrictions( - $hasAccess, - CustomLimitationValue::class - ); - - return $customLimitationValues['value'] ?? false; - } - public function performAccessCheck(): void { $this->traitPerformAccessCheck(); diff --git a/code_samples/back_office/limitation/src/Controller/CustomLimitationController.php b/code_samples/back_office/limitation/src/Controller/CustomLimitationController.php new file mode 100644 index 0000000000..0f698afa0d --- /dev/null +++ b/code_samples/back_office/limitation/src/Controller/CustomLimitationController.php @@ -0,0 +1,59 @@ +getCustomLimitationValue()) { + // Action only for user having the custom limitation checked + } + + return new Response('...'); + } + + private function getCustomLimitationValue(): bool + { + $hasAccess = $this->permissionResolver->hasAccess('custom_module', 'custom_function_2'); + + if (is_bool($hasAccess)) { + return $hasAccess; + } + + $customLimitationValues = $this->permissionChecker->getRestrictions( + $hasAccess, + CustomLimitationValue::class + ); + + return $customLimitationValues['value'] ?? false; + } + + public function performAccessCheck(): void + { + $this->traitPerformAccessCheck(); + $this->denyAccessUnlessGranted(new Attribute('custom_module', 'custom_function_2')); + } +} diff --git a/docs/permissions/custom_policies.md b/docs/permissions/custom_policies.md index 84b65e3866..6929a51a0b 100644 --- a/docs/permissions/custom_policies.md +++ b/docs/permissions/custom_policies.md @@ -251,5 +251,5 @@ For example, `translations/ibexa_content_forms_policies.en.yaml`: Check if current user has this custom limitation set to true from a custom controller: ```php -[[= include_file('code_samples/back_office/limitation/src/Controller/CustomController.php') =]] +[[= include_file('code_samples/back_office/limitation/src/Controller/CustomLimitationController.php') =]] ``` diff --git a/docs/permissions/permission_overview.md b/docs/permissions/permission_overview.md index 6a8b2f1dbe..14b8dbd9ee 100644 --- a/docs/permissions/permission_overview.md +++ b/docs/permissions/permission_overview.md @@ -34,23 +34,18 @@ The more role assignments and complex policies you add for a given user, the mor ## Permissions for custom controllers -You can control access to a custom controller by implementing the `performAccessCheck()` method. +You can control access to a custom controller by implementing the [`RestrictedControllerInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-RestrictedControllerInterface.html) interface directly or, for back office controllers, by inheriting from [`\Ibexa\Contracts\AdminUi\Controller\Controller`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-AdminUi-Controller-Controller.html). -In the following example the user doesn't have access to the controller unless they have the `section/view` policy: +In the following example the user doesn't have access to the controller unless they have the `section/view` policy and are [logged in using the "rememeber me cookie"]([[= symfony_doc =]]/security.html#checking-to-see-if-a-user-is-logged-in). +It uses the [`AuthenticatedRememberedCheckTrait`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-AuthenticatedRememberedCheckTrait.html) to reuse the existing code. -``` php -use Ibexa\Core\MVC\Symfony\Security\Authorization\Attribute; - -public function performAccessCheck(): void -{ - parent::performAccessCheck(); - $this->denyAccessUnlessGranted(new Attribute('section', 'view')); -} +``` php hl_lines="17-18" +[[= include_file('code_samples/back_office/limitation/src/Controller/CustomController.php', 0, 20) =]] ``` `Attribute` accepts three arguments: -- `module` is the policy module (for example,`content`) +- `module` is the policy module (for example, `content`) - `function` is the function inside the module (for example, `read`) - `limitations` are optional limitations to check against. Here you can provide two keys: - `valueObject` is the object you want to check for, for example `ContentInfo`. From 05218f686ff3bdb3b20c58c1b2a03c34d9b1a094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Tue, 25 Nov 2025 20:11:40 +0100 Subject: [PATCH 2/3] Selfreview --- docs/permissions/permission_overview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/permissions/permission_overview.md b/docs/permissions/permission_overview.md index 14b8dbd9ee..af6eb5bbd3 100644 --- a/docs/permissions/permission_overview.md +++ b/docs/permissions/permission_overview.md @@ -34,12 +34,12 @@ The more role assignments and complex policies you add for a given user, the mor ## Permissions for custom controllers -You can control access to a custom controller by implementing the [`RestrictedControllerInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-RestrictedControllerInterface.html) interface directly or, for back office controllers, by inheriting from [`\Ibexa\Contracts\AdminUi\Controller\Controller`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-AdminUi-Controller-Controller.html). +You can control access to a custom controller by implementing the [`RestrictedControllerInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-RestrictedControllerInterface.html) interface directly or, for back office controllers, by extending the [`\Ibexa\Contracts\AdminUi\Controller\Controller`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-AdminUi-Controller-Controller.html) class. In the following example the user doesn't have access to the controller unless they have the `section/view` policy and are [logged in using the "rememeber me cookie"]([[= symfony_doc =]]/security.html#checking-to-see-if-a-user-is-logged-in). -It uses the [`AuthenticatedRememberedCheckTrait`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-AuthenticatedRememberedCheckTrait.html) to reuse the existing code. +It uses the [`AuthenticatedRememberedCheckTrait`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-AuthenticatedRememberedCheckTrait.html) to for the latter check. -``` php hl_lines="17-18" +``` php hl_lines="15-19" [[= include_file('code_samples/back_office/limitation/src/Controller/CustomController.php', 0, 20) =]] ``` From a5a560a17644241658c30704a8a442c4c380cf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Wed, 26 Nov 2025 09:21:45 +0100 Subject: [PATCH 3/3] Update docs/permissions/permission_overview.md --- docs/permissions/permission_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/permissions/permission_overview.md b/docs/permissions/permission_overview.md index af6eb5bbd3..630314ebda 100644 --- a/docs/permissions/permission_overview.md +++ b/docs/permissions/permission_overview.md @@ -37,7 +37,7 @@ The more role assignments and complex policies you add for a given user, the mor You can control access to a custom controller by implementing the [`RestrictedControllerInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-RestrictedControllerInterface.html) interface directly or, for back office controllers, by extending the [`\Ibexa\Contracts\AdminUi\Controller\Controller`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-AdminUi-Controller-Controller.html) class. In the following example the user doesn't have access to the controller unless they have the `section/view` policy and are [logged in using the "rememeber me cookie"]([[= symfony_doc =]]/security.html#checking-to-see-if-a-user-is-logged-in). -It uses the [`AuthenticatedRememberedCheckTrait`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-AuthenticatedRememberedCheckTrait.html) to for the latter check. +It uses the [`AuthenticatedRememberedCheckTrait`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-User-Controller-AuthenticatedRememberedCheckTrait.html) for the latter check. ``` php hl_lines="15-19" [[= include_file('code_samples/back_office/limitation/src/Controller/CustomController.php', 0, 20) =]]