diff --git a/src/Generator.php b/src/Generator.php index 6245fe43a..476b6f365 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -247,7 +247,7 @@ public function generateTemplate(string $targetPath, string $templateName, array public static function getControllerBaseClass(): ClassNameDetails { - // Support for Controller::class can be dropped when FrameworkBundle minimum supported version is >=4.1 + // @legacy Support for Controller::class can be dropped when FrameworkBundle minimum supported version is >=4.1 $class = method_exists(AbstractController::class, 'getParameter') ? AbstractController::class : Controller::class; return new ClassNameDetails($class, '\\'); diff --git a/src/Maker/MakeRegistrationForm.php b/src/Maker/MakeRegistrationForm.php index e53acfa32..b7250fefa 100644 --- a/src/Maker/MakeRegistrationForm.php +++ b/src/Maker/MakeRegistrationForm.php @@ -42,6 +42,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Address; +use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; @@ -60,11 +61,8 @@ final class MakeRegistrationForm extends AbstractMaker { private $fileManager; - private $formTypeRenderer; - private $router; - private $doctrineHelper; private $userClass; @@ -276,6 +274,16 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Controller\\' ); + /* + * @legacy Conditional can be removed when MakerBundle no longer + * supports Symfony < 5.2 + */ + $passwordHasher = UserPasswordEncoderInterface::class; + + if (interface_exists(UserPasswordHasherInterface::class)) { + $passwordHasher = UserPasswordHasherInterface::class; + } + $useStatements = [ Generator::getControllerBaseClass()->getFullName(), $formClassDetails->getFullName(), @@ -283,7 +291,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen Request::class, Response::class, Route::class, - UserPasswordEncoderInterface::class, + $passwordHasher, ]; if ($this->willVerifyEmail) { @@ -313,8 +321,8 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'user_class_name' => $userClassNameDetails->getShortName(), 'password_field' => $this->passwordField, 'will_verify_email' => $this->willVerifyEmail, + 'email_verifier_class_details' => $verifyEmailServiceClassNameDetails, 'verify_email_anonymously' => $this->verifyEmailAnonymously, - 'verify_email_security_service' => $verifyEmailServiceClassNameDetails->getFullName(), 'from_email' => $this->fromEmailAddress, 'from_email_name' => $this->fromEmailName, 'email_getter' => $this->emailGetter, @@ -322,6 +330,9 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'authenticator_full_class_name' => $this->autoLoginAuthenticator, 'firewall_name' => $this->firewallName, 'redirect_route_name' => $this->redirectRouteName, + 'password_class_details' => ($passwordClassDetails = $generator->createClassNameDetails($passwordHasher, '\\')), + 'password_variable_name' => sprintf('$%s', lcfirst($passwordClassDetails->getShortName())), // @legacy see passwordHasher conditional above + 'use_password_hasher' => UserPasswordHasherInterface::class === $passwordHasher, // @legacy see passwordHasher conditional above ], $userRepoVars ) diff --git a/src/Maker/MakeResetPassword.php b/src/Maker/MakeResetPassword.php index 1451f8555..43c78d36f 100644 --- a/src/Maker/MakeResetPassword.php +++ b/src/Maker/MakeResetPassword.php @@ -13,6 +13,7 @@ use Doctrine\Common\Annotations\Annotation; use PhpParser\Builder\Param; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper; @@ -26,17 +27,28 @@ use Symfony\Bundle\MakerBundle\Security\InteractiveSecurityHelper; use Symfony\Bundle\MakerBundle\Util\ClassNameDetails; use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator; +use Symfony\Bundle\MakerBundle\Util\TemplateComponentGenerator; use Symfony\Bundle\MakerBundle\Util\YamlSourceManipulator; use Symfony\Bundle\MakerBundle\Validator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mime\Address; +use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; +use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Yaml\Yaml; +use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait; +use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface; use SymfonyCasts\Bundle\ResetPassword\Model\ResetPasswordRequestInterface; use SymfonyCasts\Bundle\ResetPassword\Model\ResetPasswordRequestTrait; use SymfonyCasts\Bundle\ResetPassword\Persistence\Repository\ResetPasswordRequestRepositoryTrait; use SymfonyCasts\Bundle\ResetPassword\Persistence\ResetPasswordRequestRepositoryInterface; use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelper; +use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface; use SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle; /** @@ -186,15 +198,41 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Form\\' ); + /* + * @legacy Conditional can be removed when MakerBundle no longer + * supports Symfony < 5.2 + */ + $passwordHasher = UserPasswordEncoderInterface::class; + + if (interface_exists(UserPasswordHasherInterface::class)) { + $passwordHasher = UserPasswordHasherInterface::class; + } + + $useStatements = [ + Generator::getControllerBaseClass()->getFullName(), // @legacy see getControllerBaseClass comment + $userClassNameDetails->getFullName(), + $changePasswordFormTypeClassNameDetails->getFullName(), + $requestFormTypeClassNameDetails->getFullName(), + TemplatedEmail::class, + RedirectResponse::class, + Request::class, + Response::class, + MailerInterface::class, + Address::class, + Route::class, + ResetPasswordControllerTrait::class, + ResetPasswordExceptionInterface::class, + ResetPasswordHelperInterface::class, + $passwordHasher, + ]; + $generator->generateController( $controllerClassNameDetails->getFullName(), 'resetPassword/ResetPasswordController.tpl.php', [ - 'user_full_class_name' => $userClassNameDetails->getFullName(), + 'use_statements' => TemplateComponentGenerator::generateUseStatements($useStatements), 'user_class_name' => $userClassNameDetails->getShortName(), - 'request_form_type_full_class_name' => $requestFormTypeClassNameDetails->getFullName(), 'request_form_type_class_name' => $requestFormTypeClassNameDetails->getShortName(), - 'reset_form_type_full_class_name' => $changePasswordFormTypeClassNameDetails->getFullName(), 'reset_form_type_class_name' => $changePasswordFormTypeClassNameDetails->getShortName(), 'password_setter' => $this->passwordSetterMethodName, 'success_redirect_route' => $this->controllerResetSuccessRedirect, @@ -202,6 +240,9 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'from_email_name' => $this->fromEmailName, 'email_getter' => $this->emailGetterMethodName, 'email_field' => $this->emailPropertyName, + 'password_class_details' => ($passwordClassDetails = $generator->createClassNameDetails($passwordHasher, '\\')), + 'password_variable_name' => sprintf('$%s', lcfirst($passwordClassDetails->getShortName())), // @legacy see passwordHasher conditional above + 'use_password_hasher' => UserPasswordHasherInterface::class === $passwordHasher, // @legacy see passwordHasher conditional above ] ); diff --git a/src/Resources/skeleton/registration/RegistrationController.tpl.php b/src/Resources/skeleton/registration/RegistrationController.tpl.php index cbec531af..3c89c1a6a 100644 --- a/src/Resources/skeleton/registration/RegistrationController.tpl.php +++ b/src/Resources/skeleton/registration/RegistrationController.tpl.php @@ -7,16 +7,16 @@ class extends { - private $emailVerifier; + private getPropertyType($email_verifier_class_details) ?>$emailVerifier; - public function __construct(EmailVerifier $emailVerifier) + public function __construct(getShortName() ?> $emailVerifier) { $this->emailVerifier = $emailVerifier; } generateRouteForControllerMethod($route_path, $route_name) ?> - public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder): Response + public function register(Request $request, getShortName() ?> ): Response { $user = new (); $form = $this->createForm(::class, $user); @@ -25,7 +25,7 @@ public function register(Request $request, UserPasswordEncoderInterface $passwor if ($form->isSubmitted() && $form->isValid()) { // encode the plain password $user->set( - $passwordEncoder->encodePassword( + ->( $user, $form->get('plainPassword')->getData() ) diff --git a/src/Resources/skeleton/resetPassword/ResetPasswordController.tpl.php b/src/Resources/skeleton/resetPassword/ResetPasswordController.tpl.php index 1ebb617b4..675331998 100644 --- a/src/Resources/skeleton/resetPassword/ResetPasswordController.tpl.php +++ b/src/Resources/skeleton/resetPassword/ResetPasswordController.tpl.php @@ -2,21 +2,7 @@ namespace ; -use ; -use ; -use ; -use Symfony\Bridge\Twig\Mime\TemplatedEmail; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Mailer\MailerInterface; -use Symfony\Component\Mime\Address; -use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; -use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait; -use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface; -use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface; + #[Route('/reset-password')] @@ -96,7 +82,7 @@ public function checkEmail(): Response * @Route("/reset/{token}", name="app_reset_password") */ - public function reset(Request $request, UserPasswordEncoderInterface $passwordEncoder, string $token = null): Response + public function reset(Request $request, getShortName() ?> , string $token = null): Response { if ($token) { // We store the token in session and remove it from the URL, to avoid the URL being @@ -130,8 +116,8 @@ public function reset(Request $request, UserPasswordEncoderInterface $passwordEn // A password reset token should be used only once, remove it. $this->resetPasswordHelper->removeResetRequest($token); - // Encode the plain password, and set it. - $encodedPassword = $passwordEncoder->encodePassword( + // Encode(hash) the plain password, and set it. + $encodedPassword = ->( $user, $form->get('plainPassword')->getData() ); diff --git a/src/Util/ClassNameDetails.php b/src/Util/ClassNameDetails.php index 67d74c53c..e0c282576 100644 --- a/src/Util/ClassNameDetails.php +++ b/src/Util/ClassNameDetails.php @@ -16,9 +16,7 @@ final class ClassNameDetails { private $fullClassName; - private $namespacePrefix; - private $suffix; public function __construct(string $fullClassName, string $namespacePrefix, string $suffix = null) diff --git a/src/Util/TemplateComponentGenerator.php b/src/Util/TemplateComponentGenerator.php index 31c0161ad..2fe12eb11 100644 --- a/src/Util/TemplateComponentGenerator.php +++ b/src/Util/TemplateComponentGenerator.php @@ -87,4 +87,13 @@ public function generateRouteForControllerMethod(string $routePath, string $rout return $annotation; } + + public function getPropertyType(ClassNameDetails $classNameDetails): ?string + { + if (!$this->phpCompatUtil->canUseTypedProperties()) { + return null; + } + + return sprintf('%s ', $classNameDetails->getShortName()); + } }