Skip to content

Commit daa3b45

Browse files
committed
[make:registration&reset-password] conditionally use password hashers
1 parent c52c44f commit daa3b45

7 files changed

+78
-33
lines changed

src/Generator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ public function generateTemplate(string $targetPath, string $templateName, array
247247

248248
public static function getControllerBaseClass(): ClassNameDetails
249249
{
250-
// Support for Controller::class can be dropped when FrameworkBundle minimum supported version is >=4.1
250+
// @legacy Support for Controller::class can be dropped when FrameworkBundle minimum supported version is >=4.1
251251
$class = method_exists(AbstractController::class, 'getParameter') ? AbstractController::class : Controller::class;
252252

253253
return new ClassNameDetails($class, '\\');

src/Maker/MakeRegistrationForm.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use Symfony\Component\HttpFoundation\Response;
4343
use Symfony\Component\Mailer\MailerInterface;
4444
use Symfony\Component\Mime\Address;
45+
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
4546
use Symfony\Component\Routing\Annotation\Route;
4647
use Symfony\Component\Routing\RouterInterface;
4748
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
@@ -60,11 +61,8 @@
6061
final class MakeRegistrationForm extends AbstractMaker
6162
{
6263
private $fileManager;
63-
6464
private $formTypeRenderer;
65-
6665
private $router;
67-
6866
private $doctrineHelper;
6967

7068
private $userClass;
@@ -276,14 +274,24 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
276274
'Controller\\'
277275
);
278276

277+
/*
278+
* @legacy Conditional can be removed when MakerBundle no longer
279+
* supports Symfony < 5.2
280+
*/
281+
$passwordHasher = UserPasswordEncoderInterface::class;
282+
283+
if (interface_exists(UserPasswordHasherInterface::class)) {
284+
$passwordHasher = UserPasswordHasherInterface::class;
285+
}
286+
279287
$useStatements = [
280288
Generator::getControllerBaseClass()->getFullName(),
281289
$formClassDetails->getFullName(),
282290
$userClassNameDetails->getFullName(),
283291
Request::class,
284292
Response::class,
285293
Route::class,
286-
UserPasswordEncoderInterface::class,
294+
$passwordHasher,
287295
];
288296

289297
if ($this->willVerifyEmail) {
@@ -313,15 +321,18 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
313321
'user_class_name' => $userClassNameDetails->getShortName(),
314322
'password_field' => $this->passwordField,
315323
'will_verify_email' => $this->willVerifyEmail,
324+
'email_verifier_class_details' => $verifyEmailServiceClassNameDetails,
316325
'verify_email_anonymously' => $this->verifyEmailAnonymously,
317-
'verify_email_security_service' => $verifyEmailServiceClassNameDetails->getFullName(),
318326
'from_email' => $this->fromEmailAddress,
319327
'from_email_name' => $this->fromEmailName,
320328
'email_getter' => $this->emailGetter,
321329
'authenticator_class_name' => $this->autoLoginAuthenticator ? Str::getShortClassName($this->autoLoginAuthenticator) : null,
322330
'authenticator_full_class_name' => $this->autoLoginAuthenticator,
323331
'firewall_name' => $this->firewallName,
324332
'redirect_route_name' => $this->redirectRouteName,
333+
'password_class_details' => ($passwordClassDetails = $generator->createClassNameDetails($passwordHasher, '\\')),
334+
'password_variable_name' => sprintf('$%s', lcfirst($passwordClassDetails->getShortName())), // @legacy see passwordHasher conditional above
335+
'use_password_hasher' => UserPasswordHasherInterface::class === $passwordHasher, // @legacy see passwordHasher conditional above
325336
],
326337
$userRepoVars
327338
)

src/Maker/MakeResetPassword.php

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Doctrine\Common\Annotations\Annotation;
1515
use PhpParser\Builder\Param;
16+
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
1617
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1718
use Symfony\Bundle\MakerBundle\DependencyBuilder;
1819
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
@@ -26,17 +27,28 @@
2627
use Symfony\Bundle\MakerBundle\Security\InteractiveSecurityHelper;
2728
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
2829
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
30+
use Symfony\Bundle\MakerBundle\Util\TemplateComponentGenerator;
2931
use Symfony\Bundle\MakerBundle\Util\YamlSourceManipulator;
3032
use Symfony\Bundle\MakerBundle\Validator;
3133
use Symfony\Component\Console\Command\Command;
3234
use Symfony\Component\Console\Input\InputInterface;
35+
use Symfony\Component\HttpFoundation\RedirectResponse;
36+
use Symfony\Component\HttpFoundation\Request;
37+
use Symfony\Component\HttpFoundation\Response;
3338
use Symfony\Component\Mailer\MailerInterface;
39+
use Symfony\Component\Mime\Address;
40+
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
41+
use Symfony\Component\Routing\Annotation\Route;
42+
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
3443
use Symfony\Component\Yaml\Yaml;
44+
use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
45+
use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
3546
use SymfonyCasts\Bundle\ResetPassword\Model\ResetPasswordRequestInterface;
3647
use SymfonyCasts\Bundle\ResetPassword\Model\ResetPasswordRequestTrait;
3748
use SymfonyCasts\Bundle\ResetPassword\Persistence\Repository\ResetPasswordRequestRepositoryTrait;
3849
use SymfonyCasts\Bundle\ResetPassword\Persistence\ResetPasswordRequestRepositoryInterface;
3950
use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelper;
51+
use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
4052
use SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle;
4153

4254
/**
@@ -186,22 +198,51 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
186198
'Form\\'
187199
);
188200

201+
/*
202+
* @legacy Conditional can be removed when MakerBundle no longer
203+
* supports Symfony < 5.2
204+
*/
205+
$passwordHasher = UserPasswordEncoderInterface::class;
206+
207+
if (interface_exists(UserPasswordHasherInterface::class)) {
208+
$passwordHasher = UserPasswordHasherInterface::class;
209+
}
210+
211+
$useStatements = [
212+
Generator::getControllerBaseClass()->getFullName(), // @legacy see getControllerBaseClass comment
213+
$userClassNameDetails->getFullName(),
214+
$changePasswordFormTypeClassNameDetails->getFullName(),
215+
$requestFormTypeClassNameDetails->getFullName(),
216+
TemplatedEmail::class,
217+
RedirectResponse::class,
218+
Request::class,
219+
Response::class,
220+
MailerInterface::class,
221+
Address::class,
222+
Route::class,
223+
ResetPasswordControllerTrait::class,
224+
ResetPasswordExceptionInterface::class,
225+
ResetPasswordHelperInterface::class,
226+
$passwordHasher,
227+
];
228+
189229
$generator->generateController(
190230
$controllerClassNameDetails->getFullName(),
191231
'resetPassword/ResetPasswordController.tpl.php',
192232
[
193-
'user_full_class_name' => $userClassNameDetails->getFullName(),
233+
'use_statements' => TemplateComponentGenerator::generateUseStatements($useStatements),
194234
'user_class_name' => $userClassNameDetails->getShortName(),
195-
'request_form_type_full_class_name' => $requestFormTypeClassNameDetails->getFullName(),
196235
'request_form_type_class_name' => $requestFormTypeClassNameDetails->getShortName(),
197-
'reset_form_type_full_class_name' => $changePasswordFormTypeClassNameDetails->getFullName(),
198236
'reset_form_type_class_name' => $changePasswordFormTypeClassNameDetails->getShortName(),
199237
'password_setter' => $this->passwordSetterMethodName,
200238
'success_redirect_route' => $this->controllerResetSuccessRedirect,
201239
'from_email' => $this->fromEmailAddress,
202240
'from_email_name' => $this->fromEmailName,
203241
'email_getter' => $this->emailGetterMethodName,
204242
'email_field' => $this->emailPropertyName,
243+
'password_class_details' => ($passwordClassDetails = $generator->createClassNameDetails($passwordHasher, '\\')),
244+
'password_variable_name' => sprintf('$%s', lcfirst($passwordClassDetails->getShortName())), // @legacy see passwordHasher conditional above
245+
'use_password_hasher' => UserPasswordHasherInterface::class === $passwordHasher, // @legacy see passwordHasher conditional above
205246
]
206247
);
207248

src/Resources/skeleton/registration/RegistrationController.tpl.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
class <?= $class_name; ?> extends <?= $parent_class_name; ?><?= "\n" ?>
88
{
99
<?php if ($will_verify_email): ?>
10-
private $emailVerifier;
10+
private <?= $generator->getPropertyType($email_verifier_class_details) ?>$emailVerifier;
1111

12-
public function __construct(EmailVerifier $emailVerifier)
12+
public function __construct(<?= $email_verifier_class_details->getShortName() ?> $emailVerifier)
1313
{
1414
$this->emailVerifier = $emailVerifier;
1515
}
1616

1717
<?php endif; ?>
1818
<?= $generator->generateRouteForControllerMethod($route_path, $route_name) ?>
19-
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder<?= $authenticator_full_class_name ? sprintf(', GuardAuthenticatorHandler $guardHandler, %s $authenticator', $authenticator_class_name) : '' ?>): Response
19+
public function register(Request $request, <?= $password_class_details->getShortName() ?> <?= $password_variable_name ?><?= $authenticator_full_class_name ? sprintf(', GuardAuthenticatorHandler $guardHandler, %s $authenticator', $authenticator_class_name) : '' ?>): Response
2020
{
2121
$user = new <?= $user_class_name ?>();
2222
$form = $this->createForm(<?= $form_class_name ?>::class, $user);
@@ -25,7 +25,7 @@ public function register(Request $request, UserPasswordEncoderInterface $passwor
2525
if ($form->isSubmitted() && $form->isValid()) {
2626
// encode the plain password
2727
$user->set<?= ucfirst($password_field) ?>(
28-
$passwordEncoder->encodePassword(
28+
<?= $password_variable_name ?>-><?= $use_password_hasher ? 'hashPassword' : 'encodePassword' ?>(
2929
$user,
3030
$form->get('plainPassword')->getData()
3131
)

src/Resources/skeleton/resetPassword/ResetPasswordController.tpl.php

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,7 @@
22

33
namespace <?= $namespace ?>;
44

5-
use <?= $user_full_class_name ?>;
6-
use <?= $reset_form_type_full_class_name ?>;
7-
use <?= $request_form_type_full_class_name ?>;
8-
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
9-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
10-
use Symfony\Component\HttpFoundation\RedirectResponse;
11-
use Symfony\Component\HttpFoundation\Request;
12-
use Symfony\Component\HttpFoundation\Response;
13-
use Symfony\Component\Mailer\MailerInterface;
14-
use Symfony\Component\Mime\Address;
15-
use Symfony\Component\Routing\Annotation\Route;
16-
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
17-
use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
18-
use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
19-
use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
5+
<?= $use_statements; ?>
206

217
<?php if ($use_attributes) { ?>
228
#[Route('/reset-password')]
@@ -96,7 +82,7 @@ public function checkEmail(): Response
9682
* @Route("/reset/{token}", name="app_reset_password")
9783
*/
9884
<?php } ?>
99-
public function reset(Request $request, UserPasswordEncoderInterface $passwordEncoder, string $token = null): Response
85+
public function reset(Request $request, <?= $password_class_details->getShortName() ?> <?= $password_variable_name ?>, string $token = null): Response
10086
{
10187
if ($token) {
10288
// 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
130116
// A password reset token should be used only once, remove it.
131117
$this->resetPasswordHelper->removeResetRequest($token);
132118

133-
// Encode the plain password, and set it.
134-
$encodedPassword = $passwordEncoder->encodePassword(
119+
// Encode(hash) the plain password, and set it.
120+
$encodedPassword = <?= $password_variable_name ?>-><?= $use_password_hasher ? 'hashPassword' : 'encodePassword' ?>(
135121
$user,
136122
$form->get('plainPassword')->getData()
137123
);

src/Util/ClassNameDetails.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
final class ClassNameDetails
1717
{
1818
private $fullClassName;
19-
2019
private $namespacePrefix;
21-
2220
private $suffix;
2321

2422
public function __construct(string $fullClassName, string $namespacePrefix, string $suffix = null)

src/Util/TemplateComponentGenerator.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,13 @@ public function generateRouteForControllerMethod(string $routePath, string $rout
8787

8888
return $annotation;
8989
}
90+
91+
public function getPropertyType(ClassNameDetails $classNameDetails): ?string
92+
{
93+
if (!$this->phpCompatUtil->canUseTypedProperties()) {
94+
return null;
95+
}
96+
97+
return sprintf('%s ', $classNameDetails->getShortName());
98+
}
9099
}

0 commit comments

Comments
 (0)