diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 0959d882..aa7a461a 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -12,7 +12,7 @@ jobs: run: uses: "nucleos/actions/.github/workflows/continuous-integration.yml@main" with: - PHP_EXTENSIONS: "mbstring, json, mongodb" + PHP_EXTENSIONS: "mbstring, json" SYMFONY_KERNEL: "Nucleos\\UserBundle\\Tests\\App\\AppKernel" SYMFONY_VERSIONS: "6.4,7.0" secrets: diff --git a/composer-require.json b/composer-require.json index 470ddaf8..5730b349 100644 --- a/composer-require.json +++ b/composer-require.json @@ -15,10 +15,6 @@ "callable", "void", "object", - "Doctrine\\Bundle\\DoctrineBundle\\DependencyInjection\\Compiler\\DoctrineOrmMappingsPass", - "Doctrine\\Bundle\\MongoDBBundle\\DependencyInjection\\Compiler\\DoctrineMongoDBMappingsPass", - "Doctrine\\ODM\\MongoDB\\DocumentManager", - "Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata", "Doctrine\\ORM\\EntityManager", "Doctrine\\ORM\\Mapping\\ClassMetadata" ] diff --git a/composer.json b/composer.json index a74bc623..e21647a6 100644 --- a/composer.json +++ b/composer.json @@ -68,11 +68,8 @@ "twig/twig": "^2.14 || ^3.1" }, "require-dev": { - "ext-mongodb": "*", "dama/doctrine-test-bundle": "^8.0", "doctrine/doctrine-bundle": "^2.4", - "doctrine/mongodb-odm": "^2.3", - "doctrine/mongodb-odm-bundle": "^4.4 || ^5.0", "doctrine/orm": "^2.18 || ^3.0", "ergebnis/composer-normalize": "^2.0.1", "symfony/browser-kit": "^6.4 || ^7.0", @@ -83,9 +80,6 @@ "conflict": { "doctrine/dbal": ">=4", "doctrine/doctrine-bundle": "<1.12", - "doctrine/mongodb": "<1.6", - "doctrine/mongodb-odm": "<1.1", - "doctrine/mongodb-odm-bundle": "<4.1", "doctrine/orm": "<2.18" }, "autoload": { diff --git a/docs/configuration_reference.rst b/docs/configuration_reference.rst index a464d28d..cd648b50 100644 --- a/docs/configuration_reference.rst +++ b/docs/configuration_reference.rst @@ -6,10 +6,8 @@ All available configuration options are listed below with their default values. .. code-block:: yaml nucleos_user: - db_driver: ~ # Required firewall_name: ~ # Required user_class: ~ # Required - use_listener: true use_flash_notifications: true model_manager_name: null # change it to the name of your entity/document manager if you don't want to use the default one. use_authentication_listener: true diff --git a/docs/custom_storage_layer.rst b/docs/custom_storage_layer.rst deleted file mode 100644 index c0df4529..00000000 --- a/docs/custom_storage_layer.rst +++ /dev/null @@ -1,54 +0,0 @@ -Using a custom storage layer -============================ - -NucleosUserBundle has been designed to allow you to change the storage -layer used by your application and keep all of the functionality -provided by the bundle. - -Implementing a new storage layer requires providing two classes: the user -implementation and the corresponding user manager (you will of course need -two other classes if you want to use the groups). - -The user implementation must implement ``Nucleos\UserBundle\Model\UserInterface`` -and the user manager must implement ``Nucleos\UserBundle\Model\UserManagerInterface``. -The ``Nucleos\UserBundle\Model`` namespace provides base classes to make it easier to -implement these interfaces. - -.. note:: - - You need to take care to always call ``updatePassword`` - before saving a user. This is done when calling ``updateUser`` so you will - be safe if you always use the user manager to save the users. - If your storage layer gives you a hook in its saving process, you can use - it to make your implementation more flexible (this is done for Doctrine - using listeners for instance) - -Configuring NucleosUserBundle to use your implementation --------------------------------------------------------- - -To use your own implementation, create a service for your user manager. The -following example will assume that its id is ``app.custom_user_manager``. - -.. code-block:: yaml - - # config/packages/nucleos_user.yaml - nucleos_user: - db_driver: custom # custom means that none of the built-in implementation is used - user_class: App\Model\CustomUser - service: - user_manager: app.custom_user_manager - firewall_name: main - -.. note:: - - Your own service can be a private one. NucleosUserBundle will create an alias - to make it available through ``nucleos_user.user_manager``. - -.. caution:: - - The validation of the uniqueness of the username and email fields is done - using the constraints provided by DoctrineBundle. You will - need to take care of this validation when using a custom storage layer, - using a `custom constraint`_ - -.. _custom constraint: https://symfony.com/doc/current/cookbook/validation/custom_constraint.html diff --git a/docs/doctrine.rst b/docs/doctrine.rst index 71946f31..20e49611 100644 --- a/docs/doctrine.rst +++ b/docs/doctrine.rst @@ -3,26 +3,6 @@ Doctrine Implementations This chapter describes some things specific to these implementations. -Using a different object manager than the default one ------------------------------------------------------ - -Using the default configuration , NucleosUserBundle will use the default doctrine -object manager. If you are using multiple ones and want to handle your users -with a non-default one, you can change the object manager used in the configuration -by giving its name to NucleosUserBundle. - -.. code-block:: yaml - - # config/packages/nucleos_user.yaml - nucleos_user: - db_driver: orm - model_manager_name: non_default # the name of your entity manager - -.. note:: - - Using the default object manager is done by setting the configuration - option to ``null`` which is the default value. - Replacing the mapping of the bundle ----------------------------------- diff --git a/docs/groups.rst b/docs/groups.rst index 52125535..d8b895b3 100644 --- a/docs/groups.rst +++ b/docs/groups.rst @@ -21,7 +21,6 @@ Below is an example configuration for enabling groups support. # config/packages/nucleos_user.yaml nucleos_user: - db_driver: orm firewall_name: main user_class: App\Entity\User group: @@ -33,9 +32,6 @@ The Group class The simplest way to create a Group class is to extend the mapped superclass provided by the bundle. -a) ORM Group class implementation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - .. code-block:: php-annotations // src/Entity/Group.php @@ -62,37 +58,11 @@ a) ORM Group class implementation ``Group`` is a reserved keyword in SQL so it cannot be used as the table name. -b) MongoDB Group class implementation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - // src/Document/Group.php - namespace App\Document; - - use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; - use Nucleos\UserBundle\Model\Group as BaseGroup; - - /** - * @MongoDB\Document - */ - class Group extends BaseGroup - { - /** - * @MongoDB\Id(strategy="auto") - */ - protected $id; - } - Defining the User-Group relation -------------------------------- The next step is to map the relation in your ``User`` class. -a) ORM User-Group mapping -~~~~~~~~~~~~~~~~~~~~~~~~~ - - .. code-block:: php-annotations // src/Entity/User.php @@ -122,28 +92,3 @@ a) ORM User-Group mapping */ protected $groups; } - -b) MongoDB User-Group mapping -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - // src/Document/User.php - namespace App\Document; - - use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; - use Nucleos\UserBundle\Model\User as BaseUser; - - /** - * @MongoDB\Document - */ - class User extends BaseUser - { - /** @MongoDB\Id(strategy="auto") */ - protected $id; - - /** - * @MongoDB\ReferenceMany(targetDocument="App\Document\Group") - */ - protected $groups; - } diff --git a/docs/index.rst b/docs/index.rst index f7b6cf23..9b8cfa0e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,7 +22,6 @@ The following documents are available: emails groups doctrine - custom_storage_layer security deletion configuration_reference diff --git a/docs/installation.rst b/docs/installation.rst index 573a3039..1ca06aca 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -38,7 +38,7 @@ Require the bundle with composer: $ composer require nucleos/user-bundle -If you encounter installation errors pointing at a lack of configuration parameters, such as ``The child node "db_driver" at path "nucleos_user" must be configured``, you should complete the configuration in Step 5 first and then re-run this step. +If you encounter installation errors pointing at a lack of configuration parameters, you should complete the configuration in Step 5 first and then re-run this step. Step 2: Enable the bundle ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -57,8 +57,8 @@ Enable the bundle in the kernel: Step 3: Create your User class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The goal of this bundle is to persist some ``User`` class to a database (MySql, -MongoDB, etc). Your first job, then, is to create the ``User`` class +The goal of this bundle is to persist some ``User`` class to a database. +Your first job, then, is to create the ``User`` class for your application. This class can look and act however you want: add any properties or methods you find useful. This is *your* ``User`` class. @@ -75,7 +75,7 @@ to make it easier to create your entity. Here is how you use it: redefine the mapping for the other fields as it is provided by the bundle. In the following sections, you'll see examples of how your ``User`` class should -look, depending on how you're storing your users (Doctrine ORM or MongoDB ODM). +look. .. note:: @@ -89,9 +89,6 @@ look, depending on how you're storing your users (Doctrine ORM or MongoDB ODM). to call parent::__construct(), as the base User class depends on this to initialize some fields. -a) Doctrine ORM User class -.......................... - If you're persisting your users via the Doctrine ORM, then your ``User`` class should live in the ``Entity`` namespace of your bundle and look like this to start: @@ -129,38 +126,6 @@ start: ``user`` is a reserved keyword in the SQL standard. If you need to use reserved words, surround them with backticks, *e.g.* ``@ORM\Table(name="`user`")`` -b) MongoDB User class -..................... - -If you're persisting your users via the Doctrine MongoDB ODM, then your ``User`` -class should live in the ``Document`` namespace of your bundle and look like -this to start. - -.. code-block:: php-annotations - - // src/Document/User.php - namespace App\Document; - - use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; - use Nucleos\UserBundle\Model\User as BaseUser; - - /** - * @MongoDB\Document - */ - class User extends BaseUser - { - /** - * @MongoDB\Id(strategy="auto") - */ - protected $id; - - public function __construct() - { - parent::__construct(); - // your own logic - } - } - Step 4: Configure your application's security.yaml ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -256,7 +221,6 @@ of datastore you are using. # config/packages/nucleos_user.yaml nucleos_user: - db_driver: orm # other valid values is 'mongodb' firewall_name: main user_class: App\Entity\User from_email: "%mailer_user%" @@ -266,7 +230,6 @@ of datastore you are using. Only four configuration's nodes are required to use the bundle: -* The type of datastore you are using (``orm`` or ``mongodb``). * The firewall name which you configured in Step 4. * The fully qualified class name (FQCN) of the ``User`` class which you created in Step 3. @@ -317,11 +280,5 @@ For ORM run the following command. $ php bin/console doctrine:schema:update --force -For MongoDB users you can run the following command to create the indexes. - -.. code-block:: bash - - $ php bin/console doctrine:mongodb:schema:create --index - .. _Symfony documentation: https://symfony.com/doc/current/book/translation.html .. _security component documentation: https://symfony.com/doc/current/book/security.html diff --git a/docs/user_manager.rst b/docs/user_manager.rst index b9ac44d6..534096c0 100644 --- a/docs/user_manager.rst +++ b/docs/user_manager.rst @@ -7,13 +7,6 @@ Using it ensures that your code will continue to work if you change the storage. The controllers provided by the bundle use the configured user manager instead of interacting directly with the storage layer. -If you configure the ``db_driver`` option to ``orm``, this service is an instance -of ``Nucleos\UserBundle\Doctrine\UserManager``. - -If you configure the ``db_driver`` option to ``mongodb``, this service is an -instance of ``Nucleos\UserBundle\Doctrine\UserManager``. - - Accessing the User Manager service ---------------------------------- @@ -72,20 +65,6 @@ Updating a User object $userManager->updateUser($user); -.. note:: - - To make it easier, the bundle comes with a Doctrine listener handling - the update of the password fields for you behind the - scenes. If you always save the user through the user manager, you may - want to disable it to improve performance. - -.. code-block:: yaml - - # config/packages/nucleos_user.yaml - nucleos_user: - # ... - use_listener: false - .. note:: For the Doctrine implementations, the default behavior is to flush the diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 8bb94731..14cd1018 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -37,40 +37,15 @@ public function getConfigTreeBuilder(): TreeBuilder private function addMainSection(NodeDefinition $node): void { - $supportedDrivers = ['noop', 'orm', 'mongodb', 'custom']; - $node ->children() - ->scalarNode('db_driver') - ->validate() - ->ifNotInArray($supportedDrivers) - ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($supportedDrivers)) - ->end() - ->cannotBeOverwritten() - ->defaultValue('noop') - ->cannotBeEmpty() - ->end() ->scalarNode('user_class')->isRequired()->cannotBeEmpty()->end() ->scalarNode('firewall_name')->isRequired()->cannotBeEmpty()->end() ->scalarNode('model_manager_name')->defaultNull()->end() ->booleanNode('use_authentication_listener')->defaultTrue()->end() - ->booleanNode('use_listener')->defaultTrue()->end() ->booleanNode('use_flash_notifications')->defaultTrue()->end() ->scalarNode('from_email')->isRequired()->cannotBeEmpty()->end() ->end() - // Using the custom driver requires changing the manager services - ->validate() - ->ifTrue(static function ($v): bool { - return 'custom' === $v['db_driver'] && 'nucleos_user.user_manager.default' === $v['service']['user_manager']; - }) - ->thenInvalid('You need to specify your own user manager service when using the "custom" driver.') - ->end() - ->validate() - ->ifTrue(static function ($v): bool { - return 'custom' === $v['db_driver'] && isset($v['group']) && 'nucleos_user.group_manager.default' === $v['group']['group_manager']; - }) - ->thenInvalid('You need to specify your own group manager service when using the "custom" driver.') - ->end() ; } diff --git a/src/DependencyInjection/NucleosUserExtension.php b/src/DependencyInjection/NucleosUserExtension.php index de878395..39d4628c 100644 --- a/src/DependencyInjection/NucleosUserExtension.php +++ b/src/DependencyInjection/NucleosUserExtension.php @@ -13,7 +13,6 @@ namespace Nucleos\UserBundle\DependencyInjection; -use Doctrine\ORM\Events; use Nucleos\UserBundle\Mailer\ResettingMailer; use Nucleos\UserBundle\Model\GroupManager; use Nucleos\UserBundle\Model\UserManager; @@ -23,35 +22,12 @@ use Symfony\Component\Config\Loader\FileLoader; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; -final class NucleosUserExtension extends Extension implements PrependExtensionInterface +final class NucleosUserExtension extends Extension { - /** - * @var array - */ - private static array $doctrineDrivers = [ - 'orm' => [ - 'registry' => 'doctrine', - 'tag' => 'doctrine.event_listener', - 'events' => [ - Events::prePersist, - Events::preUpdate, - ], - ], - 'mongodb' => [ - 'registry' => 'doctrine_mongodb', - 'tag' => 'doctrine_mongodb.odm.event_listener', - 'events' => [ - Events::prePersist, - Events::preUpdate, - ], - ], - ]; - private bool $mailerNeeded = false; /** @@ -68,20 +44,12 @@ public function load(array $configs, ContainerBuilder $container): void $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - if ('custom' !== $config['db_driver']) { - if (isset(self::$doctrineDrivers[$config['db_driver']])) { - $loader->load('doctrine.php'); - $container->setAlias('nucleos_user.doctrine_registry', new Alias(self::$doctrineDrivers[$config['db_driver']]['registry'], false)); - } else { - $loader->load(sprintf('%s.php', $config['db_driver'])); - } - $container->setParameter($this->getAlias().'.backend_type_'.$config['db_driver'], true); - } + $loader->load('doctrine.php'); + $container->setAlias('nucleos_user.doctrine_registry', new Alias('doctrine', false)); + $container->setParameter($this->getAlias().'.backend_type_orm', true); - if (isset(self::$doctrineDrivers[$config['db_driver']])) { - $definition = $container->getDefinition('nucleos_user.object_manager'); - $definition->setFactory([new Reference('nucleos_user.doctrine_registry'), 'getManager']); - } + $definition = $container->getDefinition('nucleos_user.object_manager'); + $definition->setFactory([new Reference('nucleos_user.doctrine_registry'), 'getManager']); foreach (['validator', 'security', 'util', 'mailer', 'listeners', 'commands'] as $basename) { $loader->load(sprintf('%s.php', $basename)); @@ -101,16 +69,8 @@ public function load(array $configs, ContainerBuilder $container): void $container->setAlias('nucleos_user.user_manager', new Alias($config['service']['user_manager'], true)); $container->setAlias(UserManager::class, new Alias($config['service']['user_manager'], true)); - if ($config['use_listener'] && isset(self::$doctrineDrivers[$config['db_driver']])) { - $listenerDefinition = $container->getDefinition('nucleos_user.user_listener'); - foreach (self::$doctrineDrivers[$config['db_driver']]['events'] as $event) { - $listenerDefinition->addTag(self::$doctrineDrivers[$config['db_driver']]['tag'], ['event' => $event]); - } - } - $this->remapParametersNamespaces($config, $container, [ '' => [ - 'db_driver' => 'nucleos_user.storage', 'firewall_name' => 'nucleos_user.firewall_name', 'model_manager_name' => 'nucleos_user.model_manager_name', 'user_class' => 'nucleos_user.model.user.class', @@ -123,7 +83,7 @@ public function load(array $configs, ContainerBuilder $container): void $this->loadLoggedin($config['loggedin'], $container); if (isset($config['group'])) { - $this->loadGroups($config['group'], $container, $loader, $config['db_driver']); + $this->loadGroups($config['group'], $container, $loader); } if ($this->mailerNeeded) { @@ -132,32 +92,6 @@ public function load(array $configs, ContainerBuilder $container): void } } - public function prepend(ContainerBuilder $container): void - { - $configs = $container->getExtensionConfig('nucleos_user'); - - $storage = null; - foreach ($configs as $config) { - if (isset($config['db_driver'])) { - $storage = $config['db_driver']; - } - } - - if (null === $storage || !isset(self::$doctrineDrivers[$storage])) { - return; - } - - $container->prependExtensionConfig('framework', [ - 'validation' => [ - 'mapping' => [ - 'paths' => [ - __DIR__.'/../Resources/config/storage-validation/'.$storage, - ], - ], - ], - ]); - } - private function remapParameters(array $config, ContainerBuilder $container, array $map): void { foreach ($map as $name => $paramName) { @@ -228,15 +162,9 @@ private function loadResetting(array $config, ContainerBuilder $container, FileL ]); } - private function loadGroups(array $config, ContainerBuilder $container, FileLoader $loader, string $dbDriver): void + private function loadGroups(array $config, ContainerBuilder $container, FileLoader $loader): void { - if ('custom' !== $dbDriver) { - if (isset(self::$doctrineDrivers[$dbDriver])) { - $loader->load('doctrine_group.php'); - } else { - $loader->load(sprintf('%s_group.php', $dbDriver)); - } - } + $loader->load('doctrine_group.php'); $container->setAlias('nucleos_user.group_manager', new Alias($config['group_manager'], true)); $container->setAlias(GroupManager::class, new Alias('nucleos_user.group_manager', true)); diff --git a/src/Doctrine/UserListener.php b/src/Doctrine/UserListener.php index 27329d57..cb6d8573 100644 --- a/src/Doctrine/UserListener.php +++ b/src/Doctrine/UserListener.php @@ -14,8 +14,6 @@ namespace Nucleos\UserBundle\Doctrine; use Doctrine\Common\EventSubscriber; -use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as MongoClassMetadata; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Event\PrePersistEventArgs; use Doctrine\ORM\Event\PreUpdateEventArgs; @@ -81,9 +79,5 @@ private function recomputeChangeSet(ObjectManager $om, UserInterface $user): voi return; } - - if ($om instanceof DocumentManager && $meta instanceof MongoClassMetadata) { - $om->getUnitOfWork()->recomputeSingleDocumentChangeSet($meta, $user); - } } } diff --git a/src/Noop/UserListener.php b/src/Entity/BaseGroup.php old mode 100644 new mode 100755 similarity index 55% rename from src/Noop/UserListener.php rename to src/Entity/BaseGroup.php index 9c4f4f91..2f9431b3 --- a/src/Noop/UserListener.php +++ b/src/Entity/BaseGroup.php @@ -11,15 +11,8 @@ * file that was distributed with this source code. */ -namespace Nucleos\UserBundle\Noop; +namespace Nucleos\UserBundle\Entity; -use Doctrine\Common\EventSubscriber; +use Nucleos\UserBundle\Model\Group; -final class UserListener implements EventSubscriber -{ - public function getSubscribedEvents(): array - { - return [ - ]; - } -} +class BaseGroup extends Group {} diff --git a/src/Entity/BaseUser.php b/src/Entity/BaseUser.php new file mode 100755 index 00000000..1fbef9c8 --- /dev/null +++ b/src/Entity/BaseUser.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Nucleos\UserBundle\Entity; + +use Nucleos\UserBundle\Model\GroupInterface; +use Nucleos\UserBundle\Model\User; + +/** + * @phpstan-template GroupTemplate of GroupInterface + * + * @phpstan-extends User + */ +class BaseUser extends User {} diff --git a/src/Noop/Exception/NoDriverException.php b/src/Noop/Exception/NoDriverException.php deleted file mode 100644 index 7be0f171..00000000 --- a/src/Noop/Exception/NoDriverException.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Nucleos\UserBundle\Noop\Exception; - -use Exception; -use RuntimeException; - -final class NoDriverException extends RuntimeException -{ - public function __construct(?string $message = null, int $code = 0, Exception $previous = null) - { - parent::__construct( - null === $message ? 'The child node "db_driver" at path "nucleos_user" must be configured.' : $message, - $code, - $previous - ); - } -} diff --git a/src/Noop/GroupManager.php b/src/Noop/GroupManager.php deleted file mode 100644 index 62df1cff..00000000 --- a/src/Noop/GroupManager.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Nucleos\UserBundle\Noop; - -use Nucleos\UserBundle\Model\BaseGroupManager; -use Nucleos\UserBundle\Model\GroupInterface; -use Nucleos\UserBundle\Noop\Exception\NoDriverException; - -/** - * @phpstan-template GroupTemplate of \Nucleos\UserBundle\Model\GroupInterface - * - * @phpstan-extends BaseGroupManager - */ -final class GroupManager extends BaseGroupManager -{ - public function deleteGroup(GroupInterface $group): void - { - throw new NoDriverException(); - } - - public function findGroupBy(array $criteria): ?GroupInterface - { - throw new NoDriverException(); - } - - public function findGroups(): array - { - throw new NoDriverException(); - } - - public function getClass(): string - { - throw new NoDriverException(); - } - - public function updateGroup(GroupInterface $group, bool $andFlush = true): void - { - throw new NoDriverException(); - } -} diff --git a/src/Noop/UserManager.php b/src/Noop/UserManager.php deleted file mode 100644 index 5118ded4..00000000 --- a/src/Noop/UserManager.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Nucleos\UserBundle\Noop; - -use Nucleos\UserBundle\Model\BaseUserManager; -use Nucleos\UserBundle\Model\UserInterface; -use Nucleos\UserBundle\Noop\Exception\NoDriverException; - -final class UserManager extends BaseUserManager -{ - public function deleteUser(UserInterface $user): void - { - throw new NoDriverException(); - } - - public function findUserBy(array $criteria): ?UserInterface - { - throw new NoDriverException(); - } - - public function findUsers(): array - { - throw new NoDriverException(); - } - - public function getClass(): string - { - throw new NoDriverException(); - } - - public function reloadUser(UserInterface $user): void - { - throw new NoDriverException(); - } - - public function updateUser(UserInterface $user, bool $andFlush = true): void - { - throw new NoDriverException(); - } -} diff --git a/src/NucleosUserBundle.php b/src/NucleosUserBundle.php index eeaf0978..1de85b7f 100644 --- a/src/NucleosUserBundle.php +++ b/src/NucleosUserBundle.php @@ -13,8 +13,6 @@ namespace Nucleos\UserBundle; -use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass; -use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass; use Nucleos\UserBundle\DependencyInjection\Compiler\InjectUserCheckerPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -26,22 +24,5 @@ public function build(ContainerBuilder $container): void parent::build($container); $container->addCompilerPass(new InjectUserCheckerPass()); - - $this->addRegisterMappingsPass($container); - } - - private function addRegisterMappingsPass(ContainerBuilder $container): void - { - $mappings = [ - (string) realpath(__DIR__.'/Resources/config/doctrine-mapping') => 'Nucleos\UserBundle\Model', - ]; - - if (class_exists(DoctrineOrmMappingsPass::class)) { - $container->addCompilerPass(DoctrineOrmMappingsPass::createXmlMappingDriver($mappings, ['nucleos_user.model_manager_name'], 'nucleos_user.backend_type_orm')); - } - if (class_exists(DoctrineMongoDBMappingsPass::class)) { - /** @psalm-suppress InternalClass, InternalMethod */ - $container->addCompilerPass(DoctrineMongoDBMappingsPass::createXmlMappingDriver($mappings, ['nucleos_user.model_manager_name'], 'nucleos_user.backend_type_mongodb')); - } } } diff --git a/src/Resources/config/doctrine-mapping/Group.mongodb.xml b/src/Resources/config/doctrine-mapping/Group.mongodb.xml deleted file mode 100644 index 4ac52966..00000000 --- a/src/Resources/config/doctrine-mapping/Group.mongodb.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - diff --git a/src/Resources/config/doctrine-mapping/User.mongodb.xml b/src/Resources/config/doctrine-mapping/User.mongodb.xml deleted file mode 100644 index 1f245749..00000000 --- a/src/Resources/config/doctrine-mapping/User.mongodb.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/doctrine.php b/src/Resources/config/doctrine.php index a4ed6f91..b958a96a 100644 --- a/src/Resources/config/doctrine.php +++ b/src/Resources/config/doctrine.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use Doctrine\ORM\Events; use Doctrine\Persistence\ObjectManager; use Nucleos\UserBundle\Doctrine\UserListener; use Nucleos\UserBundle\Doctrine\UserManager; @@ -33,6 +34,8 @@ ]) ->set('nucleos_user.user_listener', UserListener::class) + ->tag('doctrine.event_listener', ['event' => Events::prePersist]) + ->tag('doctrine.event_listener', ['event' => Events::preUpdate]) ->args([ new Reference('security.password_hasher'), ]) diff --git a/src/Resources/config/doctrine-mapping/Group.orm.xml b/src/Resources/config/doctrine/BaseGroup.orm.xml similarity index 88% rename from src/Resources/config/doctrine-mapping/Group.orm.xml rename to src/Resources/config/doctrine/BaseGroup.orm.xml index 2e36c930..f947e051 100644 --- a/src/Resources/config/doctrine-mapping/Group.orm.xml +++ b/src/Resources/config/doctrine/BaseGroup.orm.xml @@ -1,6 +1,6 @@ - + diff --git a/src/Resources/config/doctrine-mapping/User.orm.xml b/src/Resources/config/doctrine/BaseUser.orm.xml similarity index 94% rename from src/Resources/config/doctrine-mapping/User.orm.xml rename to src/Resources/config/doctrine/BaseUser.orm.xml index dd9db689..ab1586a6 100644 --- a/src/Resources/config/doctrine-mapping/User.orm.xml +++ b/src/Resources/config/doctrine/BaseUser.orm.xml @@ -1,6 +1,6 @@ - + diff --git a/src/Resources/config/noop.php b/src/Resources/config/noop.php deleted file mode 100644 index 854291c0..00000000 --- a/src/Resources/config/noop.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Loader\Configurator; - -use Nucleos\UserBundle\Noop\UserListener; -use Nucleos\UserBundle\Noop\UserManager; - -return static function (ContainerConfigurator $container): void { - $container->services() - - ->set('nucleos_user.user_manager.default', UserManager::class) - - ->set('nucleos_user.user_listener', UserListener::class) - ; -}; diff --git a/src/Resources/config/noop_group.php b/src/Resources/config/noop_group.php deleted file mode 100644 index 2f1409f7..00000000 --- a/src/Resources/config/noop_group.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Loader\Configurator; - -use Nucleos\UserBundle\Noop\GroupManager; - -return static function (ContainerConfigurator $container): void { - $container->services() - - ->set('nucleos_user.group_manager.default', GroupManager::class) - ; -}; diff --git a/src/Resources/config/storage-validation/mongodb/validation.xml b/src/Resources/config/storage-validation/mongodb/validation.xml deleted file mode 100644 index 3f5af14c..00000000 --- a/src/Resources/config/storage-validation/mongodb/validation.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/storage-validation/orm/validation.xml b/src/Resources/validation.xml similarity index 100% rename from src/Resources/config/storage-validation/orm/validation.xml rename to src/Resources/validation.xml diff --git a/tests/App/AppKernel.php b/tests/App/AppKernel.php index a8aa9f17..cce7d41c 100644 --- a/tests/App/AppKernel.php +++ b/tests/App/AppKernel.php @@ -28,11 +28,6 @@ final class AppKernel extends Kernel { use MicroKernelTrait; - public function __construct(string $environment = 'test', bool $debug = false) - { - parent::__construct($environment, $debug); - } - public function registerBundles(): iterable { yield new FrameworkBundle(); diff --git a/tests/App/Entity/TestGroup.php b/tests/App/Entity/TestGroup.php index aa8eae4d..bb29348a 100644 --- a/tests/App/Entity/TestGroup.php +++ b/tests/App/Entity/TestGroup.php @@ -15,11 +15,11 @@ use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use Nucleos\UserBundle\Model\Group; +use Nucleos\UserBundle\Entity\BaseGroup; #[ORM\Entity] #[ORM\Table(name: 'user__group')] -class TestGroup extends Group +class TestGroup extends BaseGroup { #[ORM\Id] #[ORM\Column(type: Types::INTEGER)] diff --git a/tests/App/Entity/TestUser.php b/tests/App/Entity/TestUser.php index 70da0bb6..c3fd0b22 100644 --- a/tests/App/Entity/TestUser.php +++ b/tests/App/Entity/TestUser.php @@ -17,15 +17,15 @@ use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; +use Nucleos\UserBundle\Entity\BaseUser; use Nucleos\UserBundle\Model\GroupInterface; -use Nucleos\UserBundle\Model\User; /** - * @phpstan-extends User + * @phpstan-extends BaseUser */ #[ORM\Entity] #[ORM\Table(name: 'user__user')] -class TestUser extends User +class TestUser extends BaseUser { #[ORM\Id] #[ORM\Column(type: Types::INTEGER)] @@ -38,6 +38,7 @@ class TestUser extends User #[ORM\ManyToMany(targetEntity: TestGroup::class)] #[ORM\JoinTable(name: 'user__user_group')] protected Collection $groups; + private static int $index = 1; public function __construct() diff --git a/tests/App/config/config.php b/tests/App/config/config.php index 99ae524e..47913a82 100644 --- a/tests/App/config/config.php +++ b/tests/App/config/config.php @@ -16,7 +16,6 @@ use Nucleos\UserBundle\Model\UserInterface; use Nucleos\UserBundle\Tests\App\Entity\TestGroup; use Nucleos\UserBundle\Tests\App\Entity\TestUser; -use Symfony\Component\Security\Http\Attribute\IsGranted; return static function (ContainerConfigurator $containerConfigurator): void { $containerConfigurator->extension('framework', ['secret' => 'secret']); @@ -35,7 +34,7 @@ $containerConfigurator->extension('twig', ['exception_controller' => null]); - $securityConfig = [ + $containerConfigurator->extension('security', [ 'firewalls' => ['main' => [ 'security' => true, 'form_login' => [ @@ -44,14 +43,7 @@ 'default_target_path' => '/profile', ], ]], - ]; - - // TODO: Remove if when dropping support of Symfony 5.4 - if (!class_exists(IsGranted::class)) { - $securityConfig['enable_authenticator_manager'] = true; - } - - $containerConfigurator->extension('security', $securityConfig); + ]); $containerConfigurator->extension('security', [ 'providers' => ['nucleos_userbundle' => ['id' => 'nucleos_user.user_provider.username']], @@ -78,8 +70,6 @@ ], ]]); - $containerConfigurator->extension('nucleos_user', ['db_driver' => 'orm']); - $containerConfigurator->extension('nucleos_user', ['firewall_name' => 'main']); $containerConfigurator->extension('nucleos_user', ['from_email' => 'no-reply@localhost']); @@ -90,8 +80,7 @@ $containerConfigurator->extension('nucleos_user', ['loggedin' => ['route' => 'nucleos_user_update_security']]); - $containerConfigurator->extension('nucleos_user', ['deletion' => [ - ]]); + $containerConfigurator->extension('nucleos_user', ['deletion' => []]); $containerConfigurator->extension('dama_doctrine_test', ['enable_static_connection' => true, 'enable_static_meta_data_cache' => true, 'enable_static_query_cache' => true]); }; diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index c3946c82..3fb69c22 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -36,10 +36,8 @@ public function testOptions(): void 'loggedin' => [ 'route' => 'custom_loggedin', ], - 'db_driver' => 'noop', 'model_manager_name' => null, 'use_authentication_listener' => true, - 'use_listener' => true, 'use_flash_notifications' => true, 'resetting' => [ 'retry_ttl' => 7200, diff --git a/tests/DependencyInjection/NucleosUserExtensionTest.php b/tests/DependencyInjection/NucleosUserExtensionTest.php index 998ded34..977c6b0a 100644 --- a/tests/DependencyInjection/NucleosUserExtensionTest.php +++ b/tests/DependencyInjection/NucleosUserExtensionTest.php @@ -13,7 +13,6 @@ namespace Nucleos\UserBundle\Tests\DependencyInjection; -use Generator; use Nucleos\UserBundle\Action\AccountDeletionAction; use Nucleos\UserBundle\DependencyInjection\NucleosUserExtension; use Nucleos\UserBundle\EventListener\FlashListener; @@ -21,7 +20,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Yaml\Parser; /** @@ -31,16 +29,6 @@ final class NucleosUserExtensionTest extends TestCase { protected ContainerBuilder $configuration; - public function testUserLoadThrowsExceptionUnlessDatabaseDriverIsValid(): void - { - $this->expectException(InvalidConfigurationException::class); - - $loader = new NucleosUserExtension(); - $config = $this->getEmptyConfig(); - $config['db_driver'] = 'foo'; - $loader->load([$config], new ContainerBuilder()); - } - public function testUserLoadThrowsExceptionUnlessFirewallNameSet(): void { $this->expectException(InvalidConfigurationException::class); @@ -71,30 +59,6 @@ public function testUserLoadThrowsExceptionUnlessUserModelClassSet(): void $loader->load([$config], new ContainerBuilder()); } - public function testCustomDriverWithoutManager(): void - { - $this->expectException(InvalidConfigurationException::class); - - $loader = new NucleosUserExtension(); - $config = $this->getEmptyConfig(); - $config['db_driver'] = 'custom'; - $loader->load([$config], new ContainerBuilder()); - } - - public function testCustomDriver(): void - { - $this->configuration = new ContainerBuilder(); - $loader = new NucleosUserExtension(); - $config = $this->getEmptyConfig(); - $config['db_driver'] = 'custom'; - $config['service']['user_manager'] = 'acme.user_manager'; - $loader->load([$config], $this->configuration); - - $this->assertNotHasDefinition('nucleos_user.user_manager.default'); - $this->assertAlias('acme.user_manager', 'nucleos_user.user_manager'); - $this->assertParameter('custom', 'nucleos_user.storage'); - } - public function testUserLoadModelClassWithDefaults(): void { $this->createEmptyConfiguration(); @@ -109,21 +73,10 @@ public function testUserLoadModelClass(): void $this->assertParameter('Acme\MyBundle\Entity\User', 'nucleos_user.model.user.class'); } - public function testUserLoadManagerClassWithDefaults(): void - { - $this->createEmptyConfiguration(); - - $this->assertParameter('mongodb', 'nucleos_user.storage'); - $this->assertParameter(null, 'nucleos_user.model_manager_name'); - $this->assertAlias('nucleos_user.user_manager.default', 'nucleos_user.user_manager'); - $this->assertNotHasDefinition('nucleos_user.group_manager'); - } - public function testUserLoadManagerClass(): void { $this->createFullConfiguration(); - $this->assertParameter('orm', 'nucleos_user.storage'); $this->assertParameter('custom', 'nucleos_user.model_manager_name'); $this->assertAlias('acme_my.user_manager', 'nucleos_user.user_manager'); $this->assertAlias('nucleos_user.group_manager.default', 'nucleos_user.group_manager'); @@ -174,39 +127,6 @@ public function testUserLoadDeletionSrvice(): void $this->assertHasDefinition(AccountDeletionFormType::class); } - /** - * @dataProvider provideUserManagerSetFactoryCases - */ - public function testUserManagerSetFactory(string $dbDriver, string $doctrineService): void - { - $this->configuration = new ContainerBuilder(); - $loader = new NucleosUserExtension(); - $config = $this->getEmptyConfig(); - $config['db_driver'] = $dbDriver; - $loader->load([$config], $this->configuration); - - $definition = $this->configuration->getDefinition('nucleos_user.object_manager'); - - $this->assertAlias($doctrineService, 'nucleos_user.doctrine_registry'); - - $factory = $definition->getFactory(); - - self::assertIsArray($factory); - self::assertInstanceOf(Reference::class, $factory[0]); - self::assertSame('nucleos_user.doctrine_registry', (string) $factory[0]); - self::assertSame('getManager', $factory[1]); - } - - /** - * @phpstan-return Generator - */ - public static function provideUserManagerSetFactoryCases(): iterable - { - yield ['orm', 'doctrine']; - - yield ['mongodb', 'doctrine_mongodb']; - } - protected function createEmptyConfiguration(): void { $this->configuration = new ContainerBuilder(); @@ -228,7 +148,6 @@ protected function createFullConfiguration(): void protected function getEmptyConfig(): array { $yaml = <<<'EOF' -db_driver: mongodb firewall_name: nucleos_user user_class: Acme\MyBundle\Document\User from_email: Acme Corp @@ -243,9 +162,7 @@ protected function getEmptyConfig(): array protected function getFullConfig(): array { $yaml = <<<'EOF' -db_driver: orm firewall_name: nucleos_user -use_listener: true use_flash_notifications: false user_class: Acme\MyBundle\Entity\User model_manager_name: custom