diff --git a/composer.json b/composer.json index 1650536ed..d65c7e288 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "require-dev": { "composer/semver": "^3.0", "doctrine/doctrine-bundle": "^2.4", - "doctrine/orm": "^2.3", + "doctrine/orm": "^2.10.0", "symfony/http-client": "^5.4.7|^6.0", "symfony/phpunit-bridge": "^5.4.7|^6.0", "symfony/polyfill-php80": "^1.16.0", @@ -41,6 +41,9 @@ "preferred-install": "dist", "sort-packages": true }, + "conflict": { + "doctrine/orm": "<2.10" + }, "autoload": { "psr-4": { "Symfony\\Bundle\\MakerBundle\\": "src/" } }, diff --git a/src/DependencyInjection/CompilerPass/SetDoctrineManagerRegistryClassPass.php b/src/DependencyInjection/CompilerPass/SetDoctrineManagerRegistryClassPass.php deleted file mode 100644 index 3d28827f4..000000000 --- a/src/DependencyInjection/CompilerPass/SetDoctrineManagerRegistryClassPass.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass; - -use Doctrine\Persistence\ManagerRegistry; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * Helps determine which "ManagerRegistry" autowiring alias is available. - */ -class SetDoctrineManagerRegistryClassPass implements CompilerPassInterface -{ - public function process(ContainerBuilder $container): void - { - if ($container->hasAlias(ManagerRegistry::class)) { - $definition = $container->getDefinition('maker.entity_class_generator'); - $definition->addMethodCall('setMangerRegistryClassName', [ManagerRegistry::class]); - } - } -} diff --git a/src/Doctrine/EntityClassGenerator.php b/src/Doctrine/EntityClassGenerator.php index ef59c6742..2f6eef59e 100644 --- a/src/Doctrine/EntityClassGenerator.php +++ b/src/Doctrine/EntityClassGenerator.php @@ -11,12 +11,21 @@ namespace Symfony\Bundle\MakerBundle\Doctrine; -use Doctrine\Common\Persistence\ManagerRegistry as LegacyManagerRegistry; +use ApiPlatform\Metadata\ApiResource; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Exception\ORMException; +use Doctrine\ORM\Mapping; +use Doctrine\ORM\OptimisticLockException; +use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Util\ClassNameDetails; +use Symfony\Bundle\MakerBundle\Util\UseStatementGenerator; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; +use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\UX\Turbo\Attribute\Broadcast; /** * @internal @@ -25,7 +34,6 @@ final class EntityClassGenerator { private $generator; private $doctrineHelper; - private $managerRegistryClassName = LegacyManagerRegistry::class; public function __construct(Generator $generator, DoctrineHelper $doctrineHelper) { @@ -43,11 +51,25 @@ public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $ $tableName = $this->doctrineHelper->getPotentialTableName($entityClassDetails->getFullName()); + $useStatements = new UseStatementGenerator([ + $repoClassDetails->getFullName(), + [Mapping::class => 'ORM'], + ]); + + if ($broadcast) { + $useStatements->addUseStatement(Broadcast::class); + } + + if ($apiResource) { + // @legacy Drop annotation class when annotations are no longer supported. + $useStatements->addUseStatement(class_exists(ApiResource::class) ? ApiResource::class : \ApiPlatform\Core\Annotation\ApiResource::class); + } + $entityPath = $this->generator->generateClass( $entityClassDetails->getFullName(), 'doctrine/Entity.tpl.php', [ - 'repository_full_class_name' => $repoClassDetails->getFullName(), + 'use_statements' => $useStatements, 'repository_class_name' => $repoClassDetails->getShortName(), 'api_resource' => $apiResource, 'broadcast' => $broadcast, @@ -69,7 +91,7 @@ public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $ return $entityPath; } - public function generateRepositoryClass(string $repositoryClass, string $entityClass, bool $withPasswordUpgrade, bool $includeExampleComments = true) + public function generateRepositoryClass(string $repositoryClass, string $entityClass, bool $withPasswordUpgrade, bool $includeExampleComments = true): void { $shortEntityClass = Str::getShortClassName($entityClass); $entityAlias = strtolower($shortEntityClass[0]); @@ -82,26 +104,33 @@ public function generateRepositoryClass(string $repositoryClass, string $entityC $interfaceClassNameDetails = new ClassNameDetails($passwordUserInterfaceName, 'Symfony\Component\Security\Core\User'); + $useStatements = new UseStatementGenerator([ + $entityClass, + ManagerRegistry::class, + ServiceEntityRepository::class, + OptimisticLockException::class, + ORMException::class, + ]); + + if ($withPasswordUpgrade) { + $useStatements->addUseStatement([ + $interfaceClassNameDetails->getFullName(), + PasswordUpgraderInterface::class, + UnsupportedUserException::class, + ]); + } + $this->generator->generateClass( $repositoryClass, 'doctrine/Repository.tpl.php', [ - 'entity_full_class_name' => $entityClass, + 'use_statements' => $useStatements, 'entity_class_name' => $shortEntityClass, 'entity_alias' => $entityAlias, 'with_password_upgrade' => $withPasswordUpgrade, 'password_upgrade_user_interface' => $interfaceClassNameDetails, - 'doctrine_registry_class' => $this->managerRegistryClassName, 'include_example_comments' => $includeExampleComments, ] ); } - - /** - * Called by a compiler pass to inject the non-legacy value if available. - */ - public function setMangerRegistryClassName(string $managerRegistryClassName) - { - $this->managerRegistryClassName = $managerRegistryClassName; - } } diff --git a/src/Maker/MakeEntity.php b/src/Maker/MakeEntity.php index a1732e79e..dc9a87045 100644 --- a/src/Maker/MakeEntity.php +++ b/src/Maker/MakeEntity.php @@ -28,6 +28,7 @@ use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Util\ClassDetails; use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator; +use Symfony\Bundle\MakerBundle\Util\PhpCompatUtil; use Symfony\Bundle\MakerBundle\Validator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -48,12 +49,22 @@ final class MakeEntity extends AbstractMaker implements InputAwareMakerInterface private $doctrineHelper; private $generator; private $entityClassGenerator; - - public function __construct(FileManager $fileManager, DoctrineHelper $doctrineHelper, string $projectDirectory, Generator $generator = null, EntityClassGenerator $entityClassGenerator = null) - { + private $phpCompatUtil; + + public function __construct( + FileManager $fileManager, + DoctrineHelper $doctrineHelper, + string $projectDirectory = null, + Generator $generator = null, + EntityClassGenerator $entityClassGenerator = null, + PhpCompatUtil $phpCompatUtil = null + ) { $this->fileManager = $fileManager; $this->doctrineHelper = $doctrineHelper; - // $projectDirectory is unused, argument kept for BC + + if (null !== $projectDirectory) { + @trigger_error('The $projectDirectory constructor argument is no longer used since 1.41.0', \E_USER_DEPRECATED); + } if (null === $generator) { @trigger_error(sprintf('Passing a "%s" instance as 4th argument is mandatory since version 1.5.', Generator::class), \E_USER_DEPRECATED); @@ -68,6 +79,13 @@ public function __construct(FileManager $fileManager, DoctrineHelper $doctrineHe } else { $this->entityClassGenerator = $entityClassGenerator; } + + if (null === $phpCompatUtil) { + @trigger_error(sprintf('Passing a "%s" instance as 6th argument is mandatory since version 1.41.0', PhpCompatUtil::class), \E_USER_DEPRECATED); + $this->phpCompatUtil = new PhpCompatUtil($this->fileManager); + } else { + $this->phpCompatUtil = $phpCompatUtil; + } } public static function getCommandName(): string @@ -80,7 +98,7 @@ public static function getCommandDescription(): string return 'Creates or updates a Doctrine entity class, and optionally an API Platform resource'; } - public function configureCommand(Command $command, InputConfiguration $inputConf) + public function configureCommand(Command $command, InputConfiguration $inputConfig): void { $command ->addArgument('name', InputArgument::OPTIONAL, sprintf('Class name of the entity to create or update (e.g. %s)', Str::asClassName(Str::getRandomTerm()))) @@ -91,10 +109,10 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeEntity.txt')) ; - $inputConf->setArgumentAsNonInteractive('name'); + $inputConfig->setArgumentAsNonInteractive('name'); } - public function interact(InputInterface $input, ConsoleStyle $io, Command $command) + public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void { if ($input->getArgument('name')) { return; @@ -143,7 +161,7 @@ class_exists(Broadcast::class) && } } - public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) + public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void { $overwrite = $input->getOption('overwrite'); @@ -308,7 +326,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen ]); } - public function configureDependencies(DependencyBuilder $dependencies, InputInterface $input = null) + public function configureDependencies(DependencyBuilder $dependencies, InputInterface $input = null): void { if (null !== $input && $input->getOption('api-resource')) { $dependencies->addClassDependency( @@ -424,7 +442,7 @@ private function askForNextField(ConsoleStyle $io, array $fields, string $entity return $data; } - private function printAvailableTypes(ConsoleStyle $io) + private function printAvailableTypes(ConsoleStyle $io): void { $allTypes = $this->getTypesMap(); @@ -810,9 +828,7 @@ private function createClassManipulator(string $path, ConsoleStyle $io, bool $ov private function getPathOfClass(string $class): string { - $classDetails = new ClassDetails($class); - - return $classDetails->getPath(); + return (new ClassDetails($class))->getPath(); } private function isClassInVendor(string $class): bool @@ -822,7 +838,7 @@ private function isClassInVendor(string $class): bool return $this->fileManager->isPathInVendor($path); } - private function regenerateEntities(string $classOrNamespace, bool $overwrite, Generator $generator) + private function regenerateEntities(string $classOrNamespace, bool $overwrite, Generator $generator): void { $regenerator = new EntityRegenerator($this->doctrineHelper, $this->fileManager, $generator, $this->entityClassGenerator, $overwrite); $regenerator->regenerateEntities($classOrNamespace); @@ -841,6 +857,7 @@ private function getPropertyNames(string $class): array }, $reflClass->getProperties()); } + /** @legacy Drop when Annotations are no longer supported */ private function doesEntityUseAnnotationMapping(string $className): bool { if (!class_exists($className)) { @@ -857,9 +874,10 @@ private function doesEntityUseAnnotationMapping(string $className): bool return $this->doctrineHelper->isClassAnnotated($className); } + /** @legacy Drop when Annotations are no longer supported */ private function doesEntityUseAttributeMapping(string $className): bool { - if (\PHP_MAJOR_VERSION < 8) { + if (!$this->phpCompatUtil->canUseAttributes()) { return false; } diff --git a/src/Maker/MakeUser.php b/src/Maker/MakeUser.php index 06ad85f57..a6aca4f19 100644 --- a/src/Maker/MakeUser.php +++ b/src/Maker/MakeUser.php @@ -25,6 +25,7 @@ use Symfony\Bundle\MakerBundle\Security\UserClassBuilder; use Symfony\Bundle\MakerBundle\Security\UserClassConfiguration; use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator; +use Symfony\Bundle\MakerBundle\Util\UseStatementGenerator; use Symfony\Bundle\MakerBundle\Util\YamlManipulationFailedException; use Symfony\Bundle\MakerBundle\Validator; use Symfony\Bundle\SecurityBundle\SecurityBundle; @@ -32,9 +33,12 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UserNotFoundException; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Yaml\Yaml; /** @@ -45,13 +49,9 @@ final class MakeUser extends AbstractMaker { private $fileManager; - private $userClassBuilder; - private $configUpdater; - private $entityClassGenerator; - private $doctrineHelper; public function __construct(FileManager $fileManager, UserClassBuilder $userClassBuilder, SecurityConfigUpdater $configUpdater, EntityClassGenerator $entityClassGenerator, DoctrineHelper $doctrineHelper) @@ -141,7 +141,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $classPath = $this->entityClassGenerator->generateEntityClass( $userClassNameDetails, false, // api resource - $userClassConfiguration->hasPassword() && interface_exists(PasswordUpgraderInterface::class) // security user + $userClassConfiguration->hasPassword() // security user ); } else { $classPath = $generator->generateClass($userClassNameDetails->getFullName(), 'Class.tpl.php'); @@ -169,13 +169,22 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen // C) Generate a custom user provider, if necessary if (!$userClassConfiguration->isEntity()) { $userClassConfiguration->setUserProviderClass($generator->getRootNamespace().'\\Security\\UserProvider'); + + $useStatements = new UseStatementGenerator([ + UnsupportedUserException::class, + UserNotFoundException::class, + PasswordAuthenticatedUserInterface::class, + PasswordUpgraderInterface::class, + UserInterface::class, + UserProviderInterface::class, + ]); + $customProviderPath = $generator->generateClass( $userClassConfiguration->getUserProviderClass(), 'security/UserProvider.tpl.php', [ - 'uses_user_identifier' => class_exists(UserNotFoundException::class), + 'use_statements' => $useStatements, 'user_short_name' => $userClassNameDetails->getShortName(), - 'use_legacy_password_upgrader_type' => !interface_exists(PasswordAuthenticatedUserInterface::class), ] ); } diff --git a/src/MakerBundle.php b/src/MakerBundle.php index 8c6ae26a4..7d946b111 100644 --- a/src/MakerBundle.php +++ b/src/MakerBundle.php @@ -15,7 +15,6 @@ use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\MakeCommandRegistrationPass; use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\RemoveMissingParametersPass; use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineAnnotatedPrefixesPass; -use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineManagerRegistryClassPass; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -32,7 +31,6 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new DoctrineAttributesCheckPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 11); $container->addCompilerPass(new MakeCommandRegistrationPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10); $container->addCompilerPass(new RemoveMissingParametersPass()); - $container->addCompilerPass(new SetDoctrineManagerRegistryClassPass()); $container->addCompilerPass(new SetDoctrineAnnotatedPrefixesPass()); } } diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index 5f2ec75b2..626c317a0 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -39,9 +39,10 @@ - %kernel.project_dir% + null + diff --git a/src/Resources/skeleton/doctrine/Entity.tpl.php b/src/Resources/skeleton/doctrine/Entity.tpl.php index 8014b9699..636f81da5 100644 --- a/src/Resources/skeleton/doctrine/Entity.tpl.php +++ b/src/Resources/skeleton/doctrine/Entity.tpl.php @@ -2,13 +2,7 @@ namespace ; -use ApiPlatform\Metadata\ApiResource; -use ApiPlatform\Core\Annotation\ApiResource; - -use ; -use Doctrine\ORM\Mapping as ORM; -use Symfony\UX\Turbo\Attribute\Broadcast; - + /** diff --git a/src/Resources/skeleton/doctrine/Repository.tpl.php b/src/Resources/skeleton/doctrine/Repository.tpl.php index 22e406a3d..28994ba7f 100644 --- a/src/Resources/skeleton/doctrine/Repository.tpl.php +++ b/src/Resources/skeleton/doctrine/Repository.tpl.php @@ -2,15 +2,7 @@ namespace ; -use ; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Doctrine\ORM\OptimisticLockException; -use Doctrine\ORM\ORMException; -use ; - -getFullName(), 'Password')) ? sprintf("use %s;\n", $password_upgrade_user_interface->getFullName()) : null ?> - -getFullName(), '\UserInterface')) ? sprintf("use %s;\n", $password_upgrade_user_interface->getFullName()) : null ?> + /** * @extends ServiceEntityRepository<> diff --git a/src/Resources/skeleton/security/UserProvider.tpl.php b/src/Resources/skeleton/security/UserProvider.tpl.php index c7ee1ef38..1e9da0456 100644 --- a/src/Resources/skeleton/security/UserProvider.tpl.php +++ b/src/Resources/skeleton/security/UserProvider.tpl.php @@ -2,14 +2,9 @@ namespace ; -use Symfony\Component\Security\Core\Exception\UnsupportedUserException; -use Symfony\Component\Security\Core\Exception\; - - -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; + -class implements UserProviderInterface +class implements UserProviderInterface, PasswordUpgraderInterface { /** * Symfony calls this method if you use features like switch_user @@ -18,18 +13,17 @@ class implements UserProviderInterface if the user is not found + * @throws UserNotFoundException if the user is not found */ - public function : UserInterface + public function loadUserByIdentifier($identifier): UserInterface { - // Load a User object from your data source or throw . - // The argument may not actually be a username: - // it is whatever value is being returned by the () + // Load a User object from your data source or throw UserNotFoundException. + // The $identifier argument may not actually be a username: + // it is whatever value is being returned by the getUserIdentifier() // method in your User class. - throw new \Exception('TODO: fill in inside '.__FILE__); + throw new \Exception('TODO: fill in loadUserByIdentifier() inside '.__FILE__); } - /** * @deprecated since Symfony 5.3, loadUserByIdentifier() is used instead */ @@ -38,7 +32,6 @@ public function loadUserByUsername($username): UserInterface return $this->loadUserByIdentifier($username); } - /** * Refreshes the user after being reloaded from the session. * @@ -68,16 +61,14 @@ public function supportsClass($class): bool { return ::class === $class || is_subclass_of($class, ::class); } - /** * Upgrades the hashed password of a user, typically for using a better hash algorithm. */ - public function upgradePassword( $user, string $newHashedPassword): void + public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void { // TODO: when hashed passwords are in use, this method should: // 1. persist the new password in the user storage // 2. update the $user object with $user->setPassword($newHashedPassword); } - } diff --git a/src/Security/SecurityConfigUpdater.php b/src/Security/SecurityConfigUpdater.php index 5c69088b9..19d3d7749 100644 --- a/src/Security/SecurityConfigUpdater.php +++ b/src/Security/SecurityConfigUpdater.php @@ -13,8 +13,6 @@ use Symfony\Bundle\MakerBundle\Util\YamlSourceManipulator; use Symfony\Component\HttpKernel\Log\Logger; -use Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher; -use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; /** @@ -52,8 +50,7 @@ public function updateForUserClass(string $yamlSource, UserClassConfiguration $u $this->updateProviders($userConfig, $userClass); if ($userConfig->hasPassword()) { - $symfonyGte53 = class_exists(NativePasswordHasher::class); - $this->updatePasswordHashers($userConfig, $userClass, $symfonyGte53 ? 'password_hashers' : 'encoders'); + $this->updatePasswordHashers($userConfig, $userClass); } $contents = $this->manipulator->getContents(); @@ -166,38 +163,37 @@ private function updateProviders(UserClassConfiguration $userConfig, string $use $this->manipulator->setData($newData); } - private function updatePasswordHashers(UserClassConfiguration $userConfig, string $userClass, string $keyName = 'password_hashers'): void + private function updatePasswordHashers(UserClassConfiguration $userConfig, string $userClass): void { $newData = $this->manipulator->getData(); - if ('password_hashers' === $keyName && isset($newData['security']['encoders'])) { - // fallback to "encoders" if the user already defined encoder config - $this->updatePasswordHashers($userConfig, $userClass, 'encoders'); - return; + if (isset($newData['security']['encoders'])) { + throw new \RuntimeException('Password Encoders are no longer supported by MakerBundle. Please update your "config/packages/security.yaml" file to use Password Hashers instead.'); } - if (isset($newData['security'][$keyName][PasswordAuthenticatedUserInterface::class])) { + // The security-bundle recipe sets the password hasher via Flex. If it exists, move on... + if (isset($newData['security']['password_hashers'][PasswordAuthenticatedUserInterface::class])) { return; } - if (!isset($newData['security'][$keyName])) { - // by convention, password_hashers are put before the user provider option - $providersIndex = array_search('providers', array_keys($newData['security'])); - if (false === $providersIndex) { - $newData['security'] = [$keyName => []] + $newData['security']; - } else { - $newData['security'] = array_merge( - \array_slice($newData['security'], 0, $providersIndex), - [$keyName => []], - \array_slice($newData['security'], $providersIndex) - ); - } + // by convention, password_hashers are put before the user provider option + $providersIndex = array_search('providers', array_keys($newData['security'])); + + if (false === $providersIndex) { + $newData['security'] = ['password_hashers' => []] + $newData['security']; + } else { + $newData['security'] = array_merge( + \array_slice($newData['security'], 0, $providersIndex), + ['password_hashers' => []], + \array_slice($newData['security'], $providersIndex) + ); } - $newData['security'][$keyName][$userClass] = [ - 'algorithm' => $userConfig->shouldUseArgon2() ? 'argon2i' : ((class_exists(NativePasswordHasher::class) || class_exists(NativePasswordEncoder::class)) ? 'auto' : 'bcrypt'), + $newData['security']['password_hashers'][$userClass] = [ + 'algorithm' => 'auto', ]; - $newData['security'][$keyName]['_'] = $this->manipulator->createEmptyLine(); + + $newData['security']['password_hashers']['_'] = $this->manipulator->createEmptyLine(); $this->manipulator->setData($newData); } diff --git a/src/Security/UserClassBuilder.php b/src/Security/UserClassBuilder.php index 066844f34..0860d4199 100644 --- a/src/Security/UserClassBuilder.php +++ b/src/Security/UserClassBuilder.php @@ -14,7 +14,6 @@ use PhpParser\Node; use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator; use Symfony\Component\HttpKernel\Kernel; -use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -40,25 +39,13 @@ public function addUserInterfaceImplementation(ClassSourceManipulator $manipulat private function addPasswordImplementation(ClassSourceManipulator $manipulator, UserClassConfiguration $userClassConfig): void { + // @legacy Drop conditional when Symfony 5.4 is no longer supported if (60000 > Kernel::VERSION_ID) { // Add methods required to fulfill the UserInterface contract $this->addGetPassword($manipulator, $userClassConfig); $this->addGetSalt($manipulator, $userClassConfig); - - // Symfony >=5.3 uses "@see PasswordAuthenticatedInterface" for getPassword() - if (interface_exists(PasswordAuthenticatedUserInterface::class)) { - $manipulator->addUseStatementIfNecessary(PasswordAuthenticatedUserInterface::class); - } - - // Future proof the entity for >= Symfony 6 && the entity will check passwords - if ($userClassConfig->hasPassword() && interface_exists(PasswordAuthenticatedUserInterface::class)) { - $manipulator->addInterface(PasswordAuthenticatedUserInterface::class); - } - - return; } - // Future proof >= Symfony 6.0 if (!$userClassConfig->hasPassword()) { return; } @@ -98,15 +85,10 @@ private function addGetUsername(ClassSourceManipulator $manipulator, UserClassCo ); } - // Check if we're using Symfony 5.3+ - UserInterface::getUsername() was replaced with UserInterface::getUserIdentifier() - $symfony53GTE = class_exists(InMemoryUser::class); - $symfony6GTE = !method_exists(UserInterface::class, 'getSalt'); - $getterIdentifierName = $symfony53GTE ? 'getUserIdentifier' : 'getUsername'; - // define getUsername (if it was defined above, this will override) $manipulator->addAccessorMethod( $userClassConfig->getIdentityPropertyName(), - $getterIdentifierName, + 'getUserIdentifier', 'string', false, [ @@ -117,7 +99,8 @@ private function addGetUsername(ClassSourceManipulator $manipulator, UserClassCo true ); - if ($symfony53GTE && !$symfony6GTE) { + // @legacy Drop when Symfony 5.4 is no longer supported. + if (method_exists(UserInterface::class, 'getSalt')) { // also add the deprecated getUsername method $manipulator->addAccessorMethod( $userClassConfig->getIdentityPropertyName(), @@ -209,8 +192,6 @@ private function addGetRoles(ClassSourceManipulator $manipulator, UserClassConfi private function addGetPassword(ClassSourceManipulator $manipulator, UserClassConfiguration $userClassConfig): void { - $seeInterface = interface_exists(PasswordAuthenticatedUserInterface::class) ? '@see PasswordAuthenticatedUserInterface' : '@see UserInterface'; - if (!$userClassConfig->hasPassword()) { // add an empty method only $builder = $manipulator->createMethodBuilder( @@ -220,7 +201,7 @@ private function addGetPassword(ClassSourceManipulator $manipulator, UserClassCo [ 'This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords.', '', - $seeInterface, + '@see PasswordAuthenticatedUserInterface', ] ); @@ -271,7 +252,7 @@ private function addGetPassword(ClassSourceManipulator $manipulator, UserClassCo 'string', false, [ - $seeInterface, + '@see PasswordAuthenticatedUserInterface', ] ); } diff --git a/tests/Doctrine/EntityRegeneratorTest.php b/tests/Doctrine/EntityRegeneratorTest.php index fa9fb1737..275862ed9 100644 --- a/tests/Doctrine/EntityRegeneratorTest.php +++ b/tests/Doctrine/EntityRegeneratorTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\MakerBundle\Tests\Doctrine; use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; -use Doctrine\Persistence\ManagerRegistry; use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; @@ -42,17 +41,6 @@ class EntityRegeneratorTest extends TestCase */ public function testRegenerateEntities(string $expectedDirName, bool $overwrite): void { - /* - * Prior to symfony/doctrine-bridge 5.0 (which require - * PHP 7.3), the deprecated Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain - * is used when our test container. This shows up as a *direct* - * deprecation. We're choosing to silence it here, instead of - * ignoring all direct deprecations. - */ - if (\PHP_VERSION_ID < 70300) { - $this->setGroups(['@legacy']); - } - $kernel = new TestEntityRegeneratorKernel('dev', true); $this->doTestRegeneration( __DIR__.'/fixtures/source_project', @@ -117,7 +105,6 @@ private function doTestRegeneration(string $sourceDir, Kernel $kernel, string $n $phpCompatUtil = new PhpCompatUtil($fileManager); $generator = new Generator($fileManager, 'App\\', $phpCompatUtil); $entityClassGenerator = new EntityClassGenerator($generator, $doctrineHelper); - $entityClassGenerator->setMangerRegistryClassName(ManagerRegistry::class); $regenerator = new EntityRegenerator( $doctrineHelper, $fileManager, diff --git a/tests/Doctrine/fixtures/expected_xml/src/Repository/UserRepository.php b/tests/Doctrine/fixtures/expected_xml/src/Repository/UserRepository.php index dd3d8f374..5f8074576 100644 --- a/tests/Doctrine/fixtures/expected_xml/src/Repository/UserRepository.php +++ b/tests/Doctrine/fixtures/expected_xml/src/Repository/UserRepository.php @@ -2,11 +2,11 @@ namespace Symfony\Bundle\MakerBundle\Tests\tmp\current_project_xml\src\Repository; -use Symfony\Bundle\MakerBundle\Tests\tmp\current_project_xml\src\Entity\UserXml; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Exception\ORMException; use Doctrine\ORM\OptimisticLockException; -use Doctrine\ORM\ORMException; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Bundle\MakerBundle\Tests\tmp\current_project_xml\src\Entity\UserXml; /** * @extends ServiceEntityRepository diff --git a/tests/Doctrine/fixtures/expected_xml/src/Repository/XOtherRepository.php b/tests/Doctrine/fixtures/expected_xml/src/Repository/XOtherRepository.php index e81340dd0..9b2b2eb81 100644 --- a/tests/Doctrine/fixtures/expected_xml/src/Repository/XOtherRepository.php +++ b/tests/Doctrine/fixtures/expected_xml/src/Repository/XOtherRepository.php @@ -2,11 +2,11 @@ namespace Symfony\Bundle\MakerBundle\Tests\tmp\current_project_xml\src\Repository; -use Symfony\Bundle\MakerBundle\Tests\tmp\current_project_xml\src\Entity\XOther; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Exception\ORMException; use Doctrine\ORM\OptimisticLockException; -use Doctrine\ORM\ORMException; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Bundle\MakerBundle\Tests\tmp\current_project_xml\src\Entity\XOther; /** * @extends ServiceEntityRepository diff --git a/tests/Maker/MakeUserTest.php b/tests/Maker/MakeUserTest.php index 2086361c0..b3a59377e 100644 --- a/tests/Maker/MakeUserTest.php +++ b/tests/Maker/MakeUserTest.php @@ -23,7 +23,7 @@ protected function getMakerClass(): string return MakeUser::class; } - public function getTestDetails() + public function getTestDetails(): \Generator { yield 'it_generates_entity_with_password' => [$this->createMakerTest() ->addExtraDependencies('doctrine') @@ -42,10 +42,7 @@ public function getTestDetails() 'y', // with password ]); - // require 5.3 so we can use password hasher - if ($runner->getSymfonyVersion() >= 50300) { - $this->runUserTest($runner, 'it_generates_entity_with_password.php'); - } + $this->runUserTest($runner, 'it_generates_entity_with_password.php'); }), ]; @@ -67,26 +64,24 @@ public function getTestDetails() ]); // simplification: allows us to assume loadUserByIdentifier in test - if ($runner->getSymfonyVersion() >= 50300) { - $runner->replaceInFile( - 'src/Security/UserProvider.php', - 'throw new \Exception(\'TODO: fill in refreshUser() inside \'.__FILE__);', - 'return $user;' - ); - - $runner->replaceInFile( - 'src/Security/UserProvider.php', - 'throw new \Exception(\'TODO: fill in loadUserByIdentifier() inside \'.__FILE__);', - 'return (new FunUser())->setUsername($identifier);' - ); - - $this->runUserTest($runner, 'it_generates_non_entity_no_password.php'); - } + $runner->replaceInFile( + 'src/Security/UserProvider.php', + 'throw new \Exception(\'TODO: fill in refreshUser() inside \'.__FILE__);', + 'return $user;' + ); + + $runner->replaceInFile( + 'src/Security/UserProvider.php', + 'throw new \Exception(\'TODO: fill in loadUserByIdentifier() inside \'.__FILE__);', + 'return (new FunUser())->setUsername($identifier);' + ); + + $this->runUserTest($runner, 'it_generates_non_entity_no_password.php'); }), ]; } - private function runUserTest(MakerTestRunner $runner, string $filename, bool $withDatabase = true) + private function runUserTest(MakerTestRunner $runner, string $filename): void { $runner->copy( 'make-user/tests/'.$filename, @@ -110,9 +105,7 @@ private function runUserTest(MakerTestRunner $runner, string $filename, bool $wi return $config; }); - if ($withDatabase) { - $runner->configureDatabase(); - } + $runner->configureDatabase(); $runner->runTests(); } diff --git a/tests/Security/UserClassBuilderTest.php b/tests/Security/UserClassBuilderTest.php index fecb23033..fd4f56166 100644 --- a/tests/Security/UserClassBuilderTest.php +++ b/tests/Security/UserClassBuilderTest.php @@ -15,8 +15,6 @@ use Symfony\Bundle\MakerBundle\Security\UserClassBuilder; use Symfony\Bundle\MakerBundle\Security\UserClassConfiguration; use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; class UserClassBuilderTest extends TestCase @@ -26,10 +24,6 @@ class UserClassBuilderTest extends TestCase */ public function testAddUserInterfaceImplementation(UserClassConfiguration $userClassConfig, string $expectedFilename): void { - if (!interface_exists(PasswordAuthenticatedUserInterface::class)) { - self::markTestSkipped('Requires Symfony >= 5.3'); - } - $manipulator = $this->getClassSourceManipulator($userClassConfig); $classBuilder = new UserClassBuilder(); @@ -80,94 +74,6 @@ public function getUserInterfaceTests(): \Generator ]; } - /** - * Covers Symfony <= 5.2 UserInterface::getUsername(). - * - * In Symfony 5.3, getUsername was replaced with getUserIdentifier() - * - * @dataProvider legacyUserInterfaceGetUsernameDataProvider - */ - public function testLegacyUserInterfaceGetUsername(UserClassConfiguration $userClassConfig, string $expectedFilename): void - { - if (method_exists(InMemoryUser::class, 'getUserIdentifier')) { - self::markTestSkipped(); - } - - $manipulator = $this->getClassSourceManipulator($userClassConfig); - - $classBuilder = new UserClassBuilder(); - $classBuilder->addUserInterfaceImplementation($manipulator, $userClassConfig); - - $expectedPath = $this->getExpectedPath($expectedFilename, 'legacy_get_username'); - - self::assertStringEqualsFile($expectedPath, $manipulator->getSourceCode()); - } - - public function legacyUserInterfaceGetUsernameDataProvider(): \Generator - { - yield 'entity_with_get_username' => [ - new UserClassConfiguration(true, 'username', false), - 'UserEntityGetUsername.php', - ]; - - yield 'model_with_get_username' => [ - new UserClassConfiguration(false, 'username', false), - 'UserModelGetUsername.php', - ]; - - yield 'model_with_email_as_username' => [ - new UserClassConfiguration(false, 'email', false), - 'UserModelWithEmailAsUsername.php', - ]; - } - - /** - * Covers Symfony <= 5.2 UserInterface::getPassword(). - * - * In Symfony 5.3, getPassword was moved from UserInterface::class to the - * new PasswordAuthenticatedUserInterface::class. - * - * @dataProvider legacyUserInterfaceGetPasswordDataProvider - */ - public function testLegacyUserInterfaceGetPassword(UserClassConfiguration $userClassConfig, string $expectedFilename): void - { - if (interface_exists(PasswordAuthenticatedUserInterface::class)) { - self::markTestSkipped(); - } - - $manipulator = $this->getClassSourceManipulator($userClassConfig); - - $classBuilder = new UserClassBuilder(); - $classBuilder->addUserInterfaceImplementation($manipulator, $userClassConfig); - - $expectedPath = $this->getExpectedPath($expectedFilename, 'legacy_get_password'); - - self::assertStringEqualsFile($expectedPath, $manipulator->getSourceCode()); - } - - public function legacyUserInterfaceGetPasswordDataProvider(): \Generator - { - yield 'entity_with_password' => [ - new UserClassConfiguration(true, 'username', true), - 'UserEntityWithPassword.php', - ]; - - yield 'entity_without_password' => [ - new UserClassConfiguration(true, 'username', false), - 'UserEntityNoPassword.php', - ]; - - yield 'model_with_password' => [ - new UserClassConfiguration(false, 'username', true), - 'UserModelWithPassword.php', - ]; - - yield 'model_without_password' => [ - new UserClassConfiguration(false, 'username', false), - 'UserModelNoPassword.php', - ]; - } - private function getClassSourceManipulator(UserClassConfiguration $userClassConfiguration): ClassSourceManipulator { $sourceFilename = __DIR__.'/fixtures/source/'.($userClassConfiguration->isEntity() ? 'UserEntity.php' : 'UserModel.php'); diff --git a/tests/Security/fixtures/expected/legacy_5_user_class/UserEntityWithoutPassword.php b/tests/Security/fixtures/expected/legacy_5_user_class/UserEntityWithoutPassword.php index 102307f42..bdaa8328f 100644 --- a/tests/Security/fixtures/expected/legacy_5_user_class/UserEntityWithoutPassword.php +++ b/tests/Security/fixtures/expected/legacy_5_user_class/UserEntityWithoutPassword.php @@ -3,7 +3,6 @@ namespace App\Entity; use Doctrine\ORM\Mapping as ORM; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; /** diff --git a/tests/Security/fixtures/expected/legacy_5_user_class/UserModelWithoutPassword.php b/tests/Security/fixtures/expected/legacy_5_user_class/UserModelWithoutPassword.php index 4d012f2c3..98285e7b6 100644 --- a/tests/Security/fixtures/expected/legacy_5_user_class/UserModelWithoutPassword.php +++ b/tests/Security/fixtures/expected/legacy_5_user_class/UserModelWithoutPassword.php @@ -2,7 +2,6 @@ namespace App\Security; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; class User implements UserInterface diff --git a/tests/Security/fixtures/expected/legacy_get_password/UserEntityNoPassword.php b/tests/Security/fixtures/expected/legacy_get_password/UserEntityNoPassword.php deleted file mode 100644 index ccbd6846f..000000000 --- a/tests/Security/fixtures/expected/legacy_get_password/UserEntityNoPassword.php +++ /dev/null @@ -1,99 +0,0 @@ -id; - } - - /** - * A visual identifier that represents this user. - * - * @see UserInterface - */ - public function getUsername(): string - { - return (string) $this->username; - } - - public function setUsername(string $username): self - { - $this->username = $username; - - return $this; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getPassword(): ?string - { - return null; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/Security/fixtures/expected/legacy_get_password/UserEntityWithPassword.php b/tests/Security/fixtures/expected/legacy_get_password/UserEntityWithPassword.php deleted file mode 100644 index 573d3bde6..000000000 --- a/tests/Security/fixtures/expected/legacy_get_password/UserEntityWithPassword.php +++ /dev/null @@ -1,111 +0,0 @@ -id; - } - - /** - * A visual identifier that represents this user. - * - * @see UserInterface - */ - public function getUsername(): string - { - return (string) $this->username; - } - - public function setUsername(string $username): self - { - $this->username = $username; - - return $this; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * @see UserInterface - */ - public function getPassword(): string - { - return $this->password; - } - - public function setPassword(string $password): self - { - $this->password = $password; - - return $this; - } - - /** - * Returning a salt is only needed, if you are not using a modern - * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/Security/fixtures/expected/legacy_get_password/UserModelNoPassword.php b/tests/Security/fixtures/expected/legacy_get_password/UserModelNoPassword.php deleted file mode 100644 index 81d9820a6..000000000 --- a/tests/Security/fixtures/expected/legacy_get_password/UserModelNoPassword.php +++ /dev/null @@ -1,77 +0,0 @@ -username; - } - - public function setUsername(string $username): self - { - $this->username = $username; - - return $this; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getPassword(): ?string - { - return null; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/Security/fixtures/expected/legacy_get_password/UserModelWithPassword.php b/tests/Security/fixtures/expected/legacy_get_password/UserModelWithPassword.php deleted file mode 100644 index 349ca3f9a..000000000 --- a/tests/Security/fixtures/expected/legacy_get_password/UserModelWithPassword.php +++ /dev/null @@ -1,88 +0,0 @@ -username; - } - - public function setUsername(string $username): self - { - $this->username = $username; - - return $this; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * @see UserInterface - */ - public function getPassword(): string - { - return $this->password; - } - - public function setPassword(string $password): self - { - $this->password = $password; - - return $this; - } - - /** - * Returning a salt is only needed, if you are not using a modern - * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/Security/fixtures/expected/legacy_get_username/UserEntityGetUsername.php b/tests/Security/fixtures/expected/legacy_get_username/UserEntityGetUsername.php deleted file mode 100644 index ccbd6846f..000000000 --- a/tests/Security/fixtures/expected/legacy_get_username/UserEntityGetUsername.php +++ /dev/null @@ -1,99 +0,0 @@ -id; - } - - /** - * A visual identifier that represents this user. - * - * @see UserInterface - */ - public function getUsername(): string - { - return (string) $this->username; - } - - public function setUsername(string $username): self - { - $this->username = $username; - - return $this; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getPassword(): ?string - { - return null; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/Security/fixtures/expected/legacy_get_username/UserModelGetUsername.php b/tests/Security/fixtures/expected/legacy_get_username/UserModelGetUsername.php deleted file mode 100644 index 81d9820a6..000000000 --- a/tests/Security/fixtures/expected/legacy_get_username/UserModelGetUsername.php +++ /dev/null @@ -1,77 +0,0 @@ -username; - } - - public function setUsername(string $username): self - { - $this->username = $username; - - return $this; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getPassword(): ?string - { - return null; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/Security/fixtures/expected/legacy_get_username/UserModelWithEmailAsUsername.php b/tests/Security/fixtures/expected/legacy_get_username/UserModelWithEmailAsUsername.php deleted file mode 100644 index f17e53c10..000000000 --- a/tests/Security/fixtures/expected/legacy_get_username/UserModelWithEmailAsUsername.php +++ /dev/null @@ -1,82 +0,0 @@ -email; - } - - public function setEmail(string $email): self - { - $this->email = $email; - - return $this; - } - - /** - * A visual identifier that represents this user. - * - * @see UserInterface - */ - public function getUsername(): string - { - return (string) $this->email; - } - - /** - * @see UserInterface - */ - public function getRoles(): array - { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); - } - - public function setRoles(array $roles): self - { - $this->roles = $roles; - - return $this; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getPassword(): ?string - { - return null; - } - - /** - * This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ - public function eraseCredentials() - { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; - } -} diff --git a/tests/fixtures/make-auth/LoginFlowTest.php.twig b/tests/fixtures/make-auth/LoginFlowTest.php.twig index 5411d9f58..318e3b8a1 100644 --- a/tests/fixtures/make-auth/LoginFlowTest.php.twig +++ b/tests/fixtures/make-auth/LoginFlowTest.php.twig @@ -73,11 +73,8 @@ class LoginFlowTest extends WebTestCase */ private function getToken(): ?TokenInterface { - $tokenStorage = static::{{ useLegacyContainerProperty ? '$container' : 'getContainer()' }}->get('security.token_storage'); - - if (Kernel::VERSION_ID >= 50300) { - $tokenStorage->disableUsageTracking(); - } + $tokenStorage = static::getContainer()->get('security.token_storage'); + $tokenStorage->disableUsageTracking(); return $tokenStorage->getToken(); }