From 0f1925f4586bcdf8a4e8bb17750aaba689d2b481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Poirier=20Th=C3=A9or=C3=AAt?= Date: Mon, 1 Apr 2024 16:17:34 -0400 Subject: [PATCH] [SonataExtraBundle] delete batch object check base on patch --- composer.json | 3 + .../DependencyInjection/Configuration.php | 13 +++ .../DrawSonataExtraExtension.php | 5 ++ ...PreObjectDeleteBatchEventEventListener.php | 26 ++++++ .../DependencyInjection/ConfigurationTest.php | 3 + ...ataExtraExtensionAutoActionEnabledTest.php | 1 + ...onataExtraExtensionAutoHelpEnabledTest.php | 1 + ...raExtensionBatchDeleteCheckEnabledTest.php | 32 +++++++ ...ExtensionCanSecurityHandlerEnabledTest.php | 1 + ...taExtraExtensionFixMenuDeptEnabledTest.php | 1 + ...onataExtraExtensionNotifierEnabledTest.php | 1 + ...xtraExtensionSessionTimeoutEnabledTest.php | 1 + .../DrawSonataExtraExtensionTest.php | 6 +- packages/sonata-extra-bundle/composer.json | 11 +++ ...bjectDeleteBatchEventEventListenerTest.php | 87 +++++++++++++++++++ 15 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 packages/sonata-extra-bundle/EventListener/PreObjectDeleteBatchEventEventListener.php create mode 100644 packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionBatchDeleteCheckEnabledTest.php create mode 100644 tests/SonataExtraBundle/EventListener/PreObjectDeleteBatchEventEventListenerTest.php diff --git a/composer.json b/composer.json index 2bbf62452..9efe1f960 100644 --- a/composer.json +++ b/composer.json @@ -222,6 +222,9 @@ "target-directory": "vendor-bin" }, "patches": { + "sonata-project/doctrine-orm-admin-bundle": { + "Batch model delete check": "https://github.com/mpoiriert/SonataDoctrineORMAdminBundle/commit/9f9768c99d63020e3b9168d4456edf2a3dc97cca.patch" + } } }, "scripts": { diff --git a/packages/sonata-extra-bundle/DependencyInjection/Configuration.php b/packages/sonata-extra-bundle/DependencyInjection/Configuration.php index 4792939aa..7fc5393a2 100755 --- a/packages/sonata-extra-bundle/DependencyInjection/Configuration.php +++ b/packages/sonata-extra-bundle/DependencyInjection/Configuration.php @@ -3,6 +3,7 @@ namespace Draw\Bundle\SonataExtraBundle\DependencyInjection; use Draw\Bundle\SonataExtraBundle\Extension\AutoActionExtension; +use Sonata\DoctrineORMAdminBundle\Event\PreObjectDeleteBatchEvent; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -21,6 +22,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->booleanNode('install_assets')->defaultTrue()->end() ->append($this->createAutoActionNode()) ->append($this->createAutoHelpNode()) + ->append($this->createBatchDeleteCheckNode()) ->append($this->createCanSecurityHandlerNode()) ->append($this->createFixMenuDepthNode()) ->append($this->createListFieldPriorityNode()) @@ -38,6 +40,17 @@ private function createAutoHelpNode(): ArrayNodeDefinition ->canBeEnabled(); } + private function createBatchDeleteCheckNode(): ArrayNodeDefinition + { + $node = new ArrayNodeDefinition('batch_delete_check'); + + class_exists(PreObjectDeleteBatchEvent::class) + ? $node->canBeDisabled() + : $node->canBeEnabled(); + + return $node; + } + private function createNotifierNode(): ArrayNodeDefinition { $node = new ArrayNodeDefinition('notifier'); diff --git a/packages/sonata-extra-bundle/DependencyInjection/DrawSonataExtraExtension.php b/packages/sonata-extra-bundle/DependencyInjection/DrawSonataExtraExtension.php index 842d8b4c9..1528ef78f 100644 --- a/packages/sonata-extra-bundle/DependencyInjection/DrawSonataExtraExtension.php +++ b/packages/sonata-extra-bundle/DependencyInjection/DrawSonataExtraExtension.php @@ -7,6 +7,7 @@ use Draw\Bundle\SonataExtraBundle\Controller\AdminControllerInterface; use Draw\Bundle\SonataExtraBundle\EventListener\AutoHelpListener; use Draw\Bundle\SonataExtraBundle\EventListener\FixDepthMenuBuilderListener; +use Draw\Bundle\SonataExtraBundle\EventListener\PreObjectDeleteBatchEventEventListener; use Draw\Bundle\SonataExtraBundle\EventListener\SessionTimeoutRequestListener; use Draw\Bundle\SonataExtraBundle\Extension\AutoActionExtension; use Draw\Bundle\SonataExtraBundle\Extension\ListFieldPriorityExtension; @@ -46,6 +47,10 @@ public function load(array $configs, ContainerBuilder $container): void $container->removeDefinition(AutoHelpListener::class); } + if (!($config['batch_delete_check']['enabled'] ?? false)) { + $container->removeDefinition(PreObjectDeleteBatchEventEventListener::class); + } + if (!($config['fix_menu_depth']['enabled'] ?? false)) { $container->removeDefinition(FixDepthMenuBuilderListener::class); } diff --git a/packages/sonata-extra-bundle/EventListener/PreObjectDeleteBatchEventEventListener.php b/packages/sonata-extra-bundle/EventListener/PreObjectDeleteBatchEventEventListener.php new file mode 100644 index 000000000..3b7be2cb0 --- /dev/null +++ b/packages/sonata-extra-bundle/EventListener/PreObjectDeleteBatchEventEventListener.php @@ -0,0 +1,26 @@ +pool + ->getAdminByClass($event->getClassName()) + ->hasAccess('delete', $event->getObject()); + + if (!$canDelete) { + $event->preventDelete(); + } + } +} diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/ConfigurationTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/ConfigurationTest.php index 57975040b..2cb4f8360 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/ConfigurationTest.php @@ -25,6 +25,9 @@ public function getDefaultConfiguration(): array 'auto_help' => [ 'enabled' => false, ], + 'batch_delete_check' => [ + 'enabled' => true, + ], 'can_security_handler' => [ 'enabled' => false, 'grant_by_default' => true, diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoActionEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoActionEnabledTest.php index 9e4a3a0c5..ccbbc5b04 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoActionEnabledTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoActionEnabledTest.php @@ -16,6 +16,7 @@ public function createExtension(): Extension public function getConfiguration(): array { return [ + ...parent::getConfiguration(), 'auto_action' => [ 'enabled' => true, ], diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoHelpEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoHelpEnabledTest.php index 2e71de8aa..775679e83 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoHelpEnabledTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionAutoHelpEnabledTest.php @@ -16,6 +16,7 @@ public function createExtension(): Extension public function getConfiguration(): array { return [ + ...parent::getConfiguration(), 'auto_help' => [ 'enabled' => true, ], diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionBatchDeleteCheckEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionBatchDeleteCheckEnabledTest.php new file mode 100644 index 000000000..dce9ad9ef --- /dev/null +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionBatchDeleteCheckEnabledTest.php @@ -0,0 +1,32 @@ + [ + 'enabled' => true, + ], + ]; + } + + public static function provideTestHasServiceDefinition(): iterable + { + yield from parent::provideTestHasServiceDefinition(); + yield [PreObjectDeleteBatchEventEventListener::class]; + } +} diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionCanSecurityHandlerEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionCanSecurityHandlerEnabledTest.php index 07935bc49..324536559 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionCanSecurityHandlerEnabledTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionCanSecurityHandlerEnabledTest.php @@ -19,6 +19,7 @@ public function createExtension(): Extension public function getConfiguration(): array { return [ + ...parent::getConfiguration(), 'can_security_handler' => [ 'enabled' => true, 'prevent_delete_voter' => [ diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionFixMenuDeptEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionFixMenuDeptEnabledTest.php index 4d8434f49..1a4cc5ecd 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionFixMenuDeptEnabledTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionFixMenuDeptEnabledTest.php @@ -16,6 +16,7 @@ public function createExtension(): Extension public function getConfiguration(): array { return [ + ...parent::getConfiguration(), 'fix_menu_depth' => [ 'enabled' => true, ], diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionNotifierEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionNotifierEnabledTest.php index d89d214e1..b3586848d 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionNotifierEnabledTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionNotifierEnabledTest.php @@ -17,6 +17,7 @@ public function createExtension(): Extension public function getConfiguration(): array { return [ + ...parent::getConfiguration(), 'notifier' => [ 'enabled' => true, ], diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionSessionTimeoutEnabledTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionSessionTimeoutEnabledTest.php index e7f6163e3..8b6ebed59 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionSessionTimeoutEnabledTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionSessionTimeoutEnabledTest.php @@ -16,6 +16,7 @@ public function createExtension(): Extension public function getConfiguration(): array { return [ + ...parent::getConfiguration(), 'session_timeout' => [ 'enabled' => true, 'delay' => 900, diff --git a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionTest.php b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionTest.php index 6f4090ac2..06e8480f4 100644 --- a/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionTest.php +++ b/packages/sonata-extra-bundle/Tests/DependencyInjection/DrawSonataExtraExtensionTest.php @@ -35,7 +35,11 @@ public function createExtension(): Extension public function getConfiguration(): array { - return []; + return [ + 'batch_delete_check' => [ + 'enabled' => false, + ], + ]; } public static function provideTestHasServiceDefinition(): iterable diff --git a/packages/sonata-extra-bundle/composer.json b/packages/sonata-extra-bundle/composer.json index cac5e1582..43585cf4d 100644 --- a/packages/sonata-extra-bundle/composer.json +++ b/packages/sonata-extra-bundle/composer.json @@ -10,6 +10,7 @@ "symfony/expression-language": "^6.4.0" }, "require-dev": { + "cweagans/composer-patches": "^1.7", "draw/tester": "^0.11", "draw/security": "^0.11", "phpunit/phpunit": "^9.0 || ^10.0", @@ -24,9 +25,19 @@ "Draw\\Bundle\\SonataExtraBundle\\": "" } }, + "config": { + "allow-plugins": { + "cweagans/composer-patches": true + } + }, "extra": { "branch-alias": { "dev-master": "0.11-dev" + }, + "patches": { + "sonata-project/doctrine-orm-admin-bundle": { + "Batch model delete check": "https://github.com/mpoiriert/SonataDoctrineORMAdminBundle/commit/9f9768c99d63020e3b9168d4456edf2a3dc97cca.patch" + } } } } diff --git a/tests/SonataExtraBundle/EventListener/PreObjectDeleteBatchEventEventListenerTest.php b/tests/SonataExtraBundle/EventListener/PreObjectDeleteBatchEventEventListenerTest.php new file mode 100644 index 000000000..3b7eee36a --- /dev/null +++ b/tests/SonataExtraBundle/EventListener/PreObjectDeleteBatchEventEventListenerTest.php @@ -0,0 +1,87 @@ +entityManager + ->getRepository(User::class) + ->findOneBy(['email' => 'admin@example.com']); + + $this->connectUser($user); + + $this->object->handlePreObjectDeleteBatchEvent( + $event = new PreObjectDeleteBatchEvent( + User::class, + $user + ) + ); + + static::assertFalse( + $event->shouldDelete(), + CannotDeleteSelfVoter::class.' should prevent deletion of the user.' + ); + } + + public function testHandlePreObjectDeleteBatchEventCanDelete(): void + { + $user = $this->entityManager + ->getRepository(User::class) + ->findOneBy(['email' => 'admin@example.com']); + + $this->connectUser($user); + + $this->object->handlePreObjectDeleteBatchEvent( + $event = new PreObjectDeleteBatchEvent( + User::class, + new User() + ) + ); + + static::assertTrue( + $event->shouldDelete() + ); + } + + private function connectUser(User $user): void + { + $this->tokenStorage + ->setToken( + new class($user) extends AbstractToken { + public function __construct(User $user) + { + parent::__construct(['ROLE_SUPER_ADMIN']); + + $this->setUser($user); + } + + public function getCredentials() + { + return null; + } + } + ); + } +}