From 76fdd6d8890b5fa2a8437c181d0b3279a4527bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 8 Apr 2024 15:38:05 +0200 Subject: [PATCH] Add explicit controller definition requirement for APIs Updated API creation to require an explicit controller definition. This change has been reflected in the ChillMainExtension and ChillPersonExtension files. Also, it has introduced a new exception, the InvalidCrudConfiguration, which will be thrown when a new API or CRUD is created without this explicit controller definition. --- MIGRATION.md | 68 +++++++++++++++++++ .../Controller/StoredObjectApiController.php | 29 +------- .../StoredObjectStatusApiController.php | 41 +++++++++++ .../ChillDocStoreExtension.php | 2 + .../CRUDControllerCompilerPass.php | 6 ++ .../Exception/InvalidCrudConfiguration.php | 25 +++++++ .../Controller/CountryApiController.php | 16 +++++ .../GeographicalUnitApiController.php | 16 +++++ .../ChillMainExtension.php | 4 ++ ...AccompanyingPeriodCommentApiController.php | 16 +++++ ...ccompanyingPeriodResourceApiController.php | 16 +++++ .../Controller/RelationApiController.php | 16 +++++ .../Controller/RelationshipApiController.php | 3 +- .../ChillPersonExtension.php | 6 ++ .../Controller/ThirdPartyApiController.php | 16 +++++ .../ChillThirdPartyExtension.php | 2 + 16 files changed, 253 insertions(+), 29 deletions(-) create mode 100644 src/Bundle/ChillDocStoreBundle/Controller/StoredObjectStatusApiController.php create mode 100644 src/Bundle/ChillMainBundle/CRUD/Exception/InvalidCrudConfiguration.php create mode 100644 src/Bundle/ChillMainBundle/Controller/CountryApiController.php create mode 100644 src/Bundle/ChillMainBundle/Controller/GeographicalUnitApiController.php create mode 100644 src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodCommentApiController.php create mode 100644 src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodResourceApiController.php create mode 100644 src/Bundle/ChillPersonBundle/Controller/RelationApiController.php create mode 100644 src/Bundle/ChillThirdPartyBundle/Controller/ThirdPartyApiController.php diff --git a/MIGRATION.md b/MIGRATION.md index b3e867402..e823f0b22 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -46,4 +46,72 @@ ]); ``` +- to keep cleaner definition in container's dependency injection and framework bundle, the definition of crud or api + requires to define explicitly a controller. + + Before: + + ```php + $container->prependExtensionConfig('chill_main', [ + 'apis' => [ + [ + 'class' => ThirdParty::class, + 'name' => 'thirdparty', + 'base_path' => '/api/1.0/thirdparty/thirdparty', + 'actions' => [ + '_entity' => [ + 'methods' => [ + Request::METHOD_GET => true, + Request::METHOD_HEAD => true, + Request::METHOD_POST => true, + Request::METHOD_PUT => true, + Request::METHOD_PATCH => true, + ], + 'roles' => [ + Request::METHOD_GET => ThirdPartyVoter::SHOW, + Request::METHOD_HEAD => ThirdPartyVoter::SHOW, + Request::METHOD_POST => ThirdPartyVoter::CREATE, + Request::METHOD_PUT => ThirdPartyVoter::CREATE, + Request::METHOD_PATCH => ThirdPartyVoter::CREATE, + ], + ], + ], + ], + ], + ]); + + After: + + ```php + $container->prependExtensionConfig('chill_main', [ + 'apis' => [ + [ + 'class' => ThirdParty::class, + 'controller' => ThirdPartyApiController::class, + 'name' => 'thirdparty', + 'base_path' => '/api/1.0/thirdparty/thirdparty', + 'actions' => [ + '_entity' => [ + 'methods' => [ + Request::METHOD_GET => true, + Request::METHOD_HEAD => true, + Request::METHOD_POST => true, + Request::METHOD_PUT => true, + Request::METHOD_PATCH => true, + ], + 'roles' => [ + Request::METHOD_GET => ThirdPartyVoter::SHOW, + Request::METHOD_HEAD => ThirdPartyVoter::SHOW, + Request::METHOD_POST => ThirdPartyVoter::CREATE, + Request::METHOD_PUT => ThirdPartyVoter::CREATE, + Request::METHOD_PATCH => ThirdPartyVoter::CREATE, + ], + ], + ], + ], + ], + ]); + + ``` + diff --git a/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectApiController.php b/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectApiController.php index 38856b779..600b6e52d 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectApiController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectApiController.php @@ -11,31 +11,6 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Controller; -use Chill\DocStoreBundle\Entity\StoredObject; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Security\Core\Security; +use Chill\MainBundle\CRUD\Controller\ApiController; -class StoredObjectApiController -{ - public function __construct(private readonly Security $security) {} - - #[Route(path: '/api/1.0/doc-store/stored-object/{uuid}/is-ready')] - public function isDocumentReady(StoredObject $storedObject): Response - { - if (!$this->security->isGranted('ROLE_USER')) { - throw new AccessDeniedHttpException(); - } - - return new JsonResponse( - [ - 'id' => $storedObject->getId(), - 'filename' => $storedObject->getFilename(), - 'status' => $storedObject->getStatus(), - 'type' => $storedObject->getType(), - ] - ); - } -} +class StoredObjectApiController extends ApiController {} diff --git a/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectStatusApiController.php b/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectStatusApiController.php new file mode 100644 index 000000000..2108a8a07 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectStatusApiController.php @@ -0,0 +1,41 @@ +security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + + return new JsonResponse( + [ + 'id' => $storedObject->getId(), + 'filename' => $storedObject->getFilename(), + 'status' => $storedObject->getStatus(), + 'type' => $storedObject->getType(), + ] + ); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/DependencyInjection/ChillDocStoreExtension.php b/src/Bundle/ChillDocStoreBundle/DependencyInjection/ChillDocStoreExtension.php index 7ae5dcbe1..fe9aeecfa 100644 --- a/src/Bundle/ChillDocStoreBundle/DependencyInjection/ChillDocStoreExtension.php +++ b/src/Bundle/ChillDocStoreBundle/DependencyInjection/ChillDocStoreExtension.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\DependencyInjection; +use Chill\DocStoreBundle\Controller\StoredObjectApiController; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; use Symfony\Component\Config\FileLocator; @@ -57,6 +58,7 @@ class ChillDocStoreExtension extends Extension implements PrependExtensionInterf 'apis' => [ [ 'class' => \Chill\DocStoreBundle\Entity\StoredObject::class, + 'controller' => StoredObjectApiController::class, 'name' => 'stored_object', 'base_path' => '/api/1.0/docstore/stored-object', 'base_role' => 'ROLE_USER', diff --git a/src/Bundle/ChillMainBundle/CRUD/CompilerPass/CRUDControllerCompilerPass.php b/src/Bundle/ChillMainBundle/CRUD/CompilerPass/CRUDControllerCompilerPass.php index c3c7b9dc1..601dc9833 100644 --- a/src/Bundle/ChillMainBundle/CRUD/CompilerPass/CRUDControllerCompilerPass.php +++ b/src/Bundle/ChillMainBundle/CRUD/CompilerPass/CRUDControllerCompilerPass.php @@ -11,6 +11,9 @@ declare(strict_types=1); namespace Chill\MainBundle\CRUD\CompilerPass; +use Chill\MainBundle\CRUD\Controller\ApiController; +use Chill\MainBundle\CRUD\Controller\CRUDController; +use Chill\MainBundle\CRUD\Exception\InvalidCrudConfiguration; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -38,6 +41,9 @@ class CRUDControllerCompilerPass implements CompilerPassInterface private function configureCrudController(ContainerBuilder $container, array $crudEntry, string $apiOrCrud): void { $controllerClass = $crudEntry['controller']; + if (ApiController::class === $controllerClass || CRUDController::class === $controllerClass) { + throw InvalidCrudConfiguration::configurationRequiresControllerDefinition($crudEntry['class'], $apiOrCrud); + } $controllerServiceName = 'cs'.$apiOrCrud.'_'.$crudEntry['name'].'_controller'; // create config parameter in container diff --git a/src/Bundle/ChillMainBundle/CRUD/Exception/InvalidCrudConfiguration.php b/src/Bundle/ChillMainBundle/CRUD/Exception/InvalidCrudConfiguration.php new file mode 100644 index 000000000..350eced43 --- /dev/null +++ b/src/Bundle/ChillMainBundle/CRUD/Exception/InvalidCrudConfiguration.php @@ -0,0 +1,25 @@ + Country::class, + 'controller' => CountryApiController::class, 'name' => 'country', 'base_path' => '/api/1.0/main/country', 'base_role' => 'ROLE_USER', @@ -787,6 +790,7 @@ class ChillMainExtension extends Extension implements ], [ 'class' => GeographicalUnitLayer::class, + 'controller' => GeographicalUnitApiController::class, 'name' => 'geographical-unit-layer', 'base_path' => '/api/1.0/main/geographical-unit-layer', 'base_role' => 'ROLE_USER', diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodCommentApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodCommentApiController.php new file mode 100644 index 000000000..a8ede3399 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodCommentApiController.php @@ -0,0 +1,16 @@ + AccompanyingPeriod\Comment::class, + 'controller' => AccompanyingPeriodCommentApiController::class, 'name' => 'accompanying_period_comment', 'base_path' => '/api/1.0/person/accompanying-period/comment', 'base_role' => 'ROLE_USER', @@ -556,6 +560,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac ], [ 'class' => AccompanyingPeriod\Resource::class, + 'controller' => AccompanyingPeriodResourceApiController::class, 'name' => 'accompanying_period_resource', 'base_path' => '/api/1.0/person/accompanying-period/resource', 'base_role' => 'ROLE_USER', @@ -874,6 +879,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac ], [ 'class' => \Chill\PersonBundle\Entity\Relationships\Relation::class, + 'controller' => RelationApiController::class, 'name' => 'relations', 'base_path' => '/api/1.0/relations/relation', 'base_role' => 'ROLE_USER', diff --git a/src/Bundle/ChillThirdPartyBundle/Controller/ThirdPartyApiController.php b/src/Bundle/ChillThirdPartyBundle/Controller/ThirdPartyApiController.php new file mode 100644 index 000000000..d108a6214 --- /dev/null +++ b/src/Bundle/ChillThirdPartyBundle/Controller/ThirdPartyApiController.php @@ -0,0 +1,16 @@ + [ [ 'class' => ThirdParty::class, + 'controller' => ThirdPartyApiController::class, 'name' => 'thirdparty', 'base_path' => '/api/1.0/thirdparty/thirdparty', // 'base_role' => \Chill\ThirdPartyBundle\Security\Authorization\ThirdPartyVoter::SHOW,