Skip to content

Commit ceda632

Browse files
authored
IBX-3972: Fixed password validation for reset and change password forms
For more details see https://issues.ibexa.co/browse/IBX-3972 and #113 * Fixed password validation for reset and change password forms * [Tests] Aligned PasswordValidatorTest with the changes
1 parent 8267ae3 commit ceda632

File tree

8 files changed

+76
-28
lines changed

8 files changed

+76
-28
lines changed

src/bundle/Controller/PasswordChangeController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function userPasswordChangeAction(Request $request)
6868
{
6969
/** @var \eZ\Publish\API\Repository\Values\User\User $user */
7070
$user = $this->tokenStorage->getToken()->getUser()->getAPIUser();
71-
$form = $this->formFactory->changeUserPassword($user->getContentType());
71+
$form = $this->formFactory->changeUserPassword($user->getContentType(), null, null, $user);
7272
$form->handleRequest($request);
7373

7474
if ($form->isSubmitted() && $form->isValid()) {

src/bundle/Controller/PasswordResetController.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,12 @@ public function userResetPasswordAction(Request $request, string $hashKey)
168168
return $view;
169169
}
170170
$userPasswordResetData = new UserPasswordResetData();
171-
$form = $this->formFactory->resetUserPassword($userPasswordResetData, null, $user->getContentType());
171+
$form = $this->formFactory->resetUserPassword(
172+
$userPasswordResetData,
173+
null,
174+
$user->getContentType(),
175+
$user
176+
);
172177
$form->handleRequest($request);
173178

174179
if ($form->isSubmitted() && $form->isValid()) {

src/lib/Form/Factory/FormFactory.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,21 @@
99
namespace EzSystems\EzPlatformUser\Form\Factory;
1010

1111
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
12-
use EzSystems\EzPlatformUser\Form\Data\UserPasswordForgotData;
12+
use eZ\Publish\API\Repository\Values\User\User;
1313
use EzSystems\EzPlatformUser\Form\Data\UserPasswordChangeData;
14+
use EzSystems\EzPlatformUser\Form\Data\UserPasswordForgotData;
15+
use EzSystems\EzPlatformUser\Form\Data\UserPasswordForgotWithLoginData;
16+
use EzSystems\EzPlatformUser\Form\Data\UserPasswordResetData;
1417
use EzSystems\EzPlatformUser\Form\Data\UserSettingUpdateData;
1518
use EzSystems\EzPlatformUser\Form\Type\UserPasswordChangeType;
1619
use EzSystems\EzPlatformUser\Form\Type\UserPasswordForgotType;
17-
use EzSystems\EzPlatformUser\Form\Data\UserPasswordForgotWithLoginData;
1820
use EzSystems\EzPlatformUser\Form\Type\UserPasswordForgotWithLoginType;
19-
use EzSystems\EzPlatformUser\Form\Data\UserPasswordResetData;
2021
use EzSystems\EzPlatformUser\Form\Type\UserPasswordResetType;
2122
use EzSystems\EzPlatformUser\Form\Type\UserSettingUpdateType;
2223
use Symfony\Component\Form\FormFactoryInterface;
23-
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
2424
use Symfony\Component\Form\FormInterface;
2525
use Symfony\Component\Form\Util\StringUtil;
26+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
2627

2728
class FormFactory
2829
{
@@ -45,15 +46,19 @@ public function __construct(FormFactoryInterface $formFactory, UrlGeneratorInter
4546
public function changeUserPassword(
4647
ContentType $contentType,
4748
UserPasswordChangeData $data = null,
48-
?string $name = null
49+
?string $name = null,
50+
?User $user = null
4951
): FormInterface {
5052
$name = $name ?: StringUtil::fqcnToBlockPrefix(UserPasswordChangeType::class);
5153

5254
return $this->formFactory->createNamed(
5355
$name,
5456
UserPasswordChangeType::class,
5557
$data,
56-
['content_type' => $contentType]
58+
[
59+
'content_type' => $contentType,
60+
'user' => $user,
61+
]
5762
);
5863
}
5964

@@ -102,13 +107,22 @@ public function forgotUserPasswordWithLogin(
102107
public function resetUserPassword(
103108
UserPasswordResetData $data = null,
104109
?string $name = null,
105-
ContentType $contentType = null
110+
?ContentType $contentType = null,
111+
?User $user = null
106112
): FormInterface {
107113
$name = $name ?: StringUtil::fqcnToBlockPrefix(UserPasswordResetType::class);
108114

109115
$userContentType = $contentType ?? $data->getContentType();
110116

111-
return $this->formFactory->createNamed($name, UserPasswordResetType::class, $data, ['content_type' => $userContentType]);
117+
return $this->formFactory->createNamed(
118+
$name,
119+
UserPasswordResetType::class,
120+
$data,
121+
[
122+
'content_type' => $userContentType,
123+
'user' => $user,
124+
]
125+
);
112126
}
113127

114128
/**

src/lib/Form/Type/UserPasswordChangeType.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace EzSystems\EzPlatformUser\Form\Type;
1010

1111
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
12+
use eZ\Publish\API\Repository\Values\User\User;
1213
use EzSystems\EzPlatformUser\Form\Data\UserPasswordChangeData;
1314
use EzSystems\EzPlatformUser\Validator\Constraints\Password;
1415
use Symfony\Component\Form\AbstractType;
@@ -36,6 +37,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
3637
'constraints' => [
3738
new Password([
3839
'contentType' => $options['content_type'],
40+
'user' => $options['user'] ?? null,
3941
]),
4042
],
4143
])
@@ -46,10 +48,12 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4648
);
4749
}
4850

49-
public function configureOptions(OptionsResolver $resolver)
51+
public function configureOptions(OptionsResolver $resolver): void
5052
{
5153
$resolver->setRequired('content_type');
54+
$resolver->setDefined('user');
5255
$resolver->setAllowedTypes('content_type', ContentType::class);
56+
$resolver->setAllowedTypes('user', [User::class, 'null']);
5357
$resolver->setDefaults([
5458
'data_class' => UserPasswordChangeData::class,
5559
'translation_domain' => 'forms',

src/lib/Form/Type/UserPasswordResetType.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace EzSystems\EzPlatformUser\Form\Type;
1010

1111
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
12+
use eZ\Publish\API\Repository\Values\User\User;
1213
use EzSystems\EzPlatformUser\Form\Data\UserPasswordResetData;
1314
use EzSystems\EzPlatformUser\Validator\Constraints\Password;
1415
use Symfony\Component\Form\AbstractType;
@@ -30,7 +31,12 @@ public function buildForm(FormBuilderInterface $builder, array $options)
3031
'first_options' => ['label' => /** @Desc("New password") */ 'ezplatform.reset_user_password.new_password'],
3132
'second_options' => ['label' => /** @Desc("Confirm password") */ 'ezplatform.reset_user_password.confirm_new_password'],
3233
'constraints' => [
33-
new Password(['contentType' => $options['content_type']]),
34+
new Password(
35+
[
36+
'contentType' => $options['content_type'],
37+
'user' => $options['user'] ?? null,
38+
]
39+
),
3440
],
3541
])
3642
->add(
@@ -40,10 +46,12 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4046
);
4147
}
4248

43-
public function configureOptions(OptionsResolver $resolver)
49+
public function configureOptions(OptionsResolver $resolver): void
4450
{
4551
$resolver->setRequired('content_type');
52+
$resolver->setDefined('user');
4653
$resolver->setAllowedTypes('content_type', ContentType::class);
54+
$resolver->setAllowedTypes('user', [User::class, 'null']);
4755
$resolver->setDefaults([
4856
'data_class' => UserPasswordResetData::class,
4957
'translation_domain' => 'forms',

src/lib/Validator/Constraints/Password.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class Password extends Constraint
2121
/** @var \eZ\Publish\API\Repository\Values\ContentType\ContentType|null */
2222
public $contentType;
2323

24+
/** @var \eZ\Publish\API\Repository\Values\User\User|null */
25+
public $user;
26+
2427
/**
2528
* {@inheritdoc}
2629
*/

src/lib/Validator/Constraints/PasswordValidator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ public function validate($value, Constraint $constraint): void
3232

3333
$passwordValidationContext = new PasswordValidationContext([
3434
'contentType' => $constraint->contentType,
35+
'user' => $constraint->user,
3536
]);
3637

37-
$validationErrors = $this->userService->validatePassword($value, $passwordValidationContext);
38+
$validationErrors = $this->userService->validatePassword(
39+
$value,
40+
$passwordValidationContext
41+
);
3842
if (!empty($validationErrors)) {
3943
$validationErrorsProcessor = $this->createValidationErrorsProcessor();
4044
$validationErrorsProcessor->processValidationErrors($validationErrors);

tests/lib/Validator/Constraint/PasswordValidatorTest.php

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use eZ\Publish\API\Repository\UserService;
1212
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
1313
use eZ\Publish\API\Repository\Values\User\PasswordValidationContext;
14+
use eZ\Publish\API\Repository\Values\User\User;
1415
use eZ\Publish\Core\FieldType\ValidationError;
1516
use EzSystems\EzPlatformUser\Validator\Constraints\Password;
1617
use EzSystems\EzPlatformUser\Validator\Constraints\PasswordValidator;
@@ -57,28 +58,37 @@ public function testValid(): void
5758
{
5859
$password = 'pass';
5960
$contentType = $this->createMock(ContentType::class);
61+
$user = $this->createMock(User::class);
6062

6163
$this->userService
62-
->expects($this->once())
64+
->expects(self::once())
6365
->method('validatePassword')
64-
->willReturnCallback(function (string $actualPassword, PasswordValidationContext $actualContext) use (
65-
$password,
66-
$contentType
67-
): array {
68-
$this->assertEquals($password, $actualPassword);
69-
$this->assertInstanceOf(PasswordValidationContext::class, $actualContext);
70-
$this->assertSame($contentType, $actualContext->contentType);
71-
72-
return [];
73-
});
66+
->willReturnCallback(
67+
function (string $actualPassword, PasswordValidationContext $actualContext) use (
68+
$password,
69+
$contentType,
70+
$user
71+
): array {
72+
self::assertEquals($password, $actualPassword);
73+
self::assertInstanceOf(PasswordValidationContext::class, $actualContext);
74+
self::assertSame($contentType, $actualContext->contentType);
75+
self::assertSame($user, $actualContext->user);
76+
77+
return [];
78+
}
79+
);
7480

7581
$this->executionContext
7682
->expects($this->never())
7783
->method('buildViolation');
7884

79-
$this->validator->validate($password, new Password([
80-
'contentType' => $contentType,
81-
]));
85+
$this->validator->validate(
86+
$password,
87+
new Password([
88+
'contentType' => $contentType,
89+
'user' => $user,
90+
])
91+
);
8292
}
8393

8494
public function testInvalid(): void

0 commit comments

Comments
 (0)