Skip to content

Commit

Permalink
EZP-31017: Added Password Validator to change password form (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
ViniTou committed Apr 21, 2020
1 parent 0c2f08f commit 3857004
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 29 deletions.
5 changes: 3 additions & 2 deletions src/bundle/Controller/PasswordChangeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ public function __construct(
*/
public function userPasswordChangeAction(Request $request)
{
$form = $this->formFactory->changeUserPassword();
/** @var \eZ\Publish\API\Repository\Values\User\User $user */
$user = $this->tokenStorage->getToken()->getUser()->getAPIUser();
$form = $this->formFactory->changeUserPassword($user->getContentType());
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
Expand All @@ -76,7 +78,6 @@ public function userPasswordChangeAction(Request $request)
$newPassword = $data->getNewPassword();
$userUpdateStruct = $this->userService->newUserUpdateStruct();
$userUpdateStruct->password = $newPassword;
$user = $this->tokenStorage->getToken()->getUser()->getAPIUser();
$this->userService->updateUser($user, $userUpdateStruct);

if ((new IsAdmin($this->siteAccessGroups))->isSatisfiedBy($request->attributes->get('siteaccess'))) {
Expand Down
4 changes: 2 additions & 2 deletions src/bundle/Controller/PasswordResetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ public function userResetPasswordAction(Request $request, string $hashKey)

return $view;
}
$userPasswordResetData = new UserPasswordResetData(null, $user->getContentType());
$form = $this->formFactory->resetUserPassword($userPasswordResetData);
$userPasswordResetData = new UserPasswordResetData();
$form = $this->formFactory->resetUserPassword($userPasswordResetData, null, $user->getContentType());
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
Expand Down
12 changes: 0 additions & 12 deletions src/bundle/Resources/config/routing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,6 @@ ezplatform.user.reset_password:
defaults:
_controller: 'EzSystems\EzPlatformUserBundle\Controller\PasswordResetController::userResetPasswordAction'

# Deprecated in v2.5 and will be removed in v3.0. Use ezplatform.user.register instead.
ez_user_register:
path: /register
defaults:
_controller: 'EzSystems\EzPlatformUserBundle\Controller\UserRegisterController::registerAction'

# Deprecated in v2.5 and will be removed in v3.0. Use ezplatform.user.register_confirmation instead.
ez_user_register_confirmation:
path: /register-confirm
defaults:
_controller: 'EzSystems\EzPlatformUserBundle\Controller\UserRegisterController::registerConfirmAction'

ezplatform.user.register: &user_register
path: /register
defaults:
Expand Down
6 changes: 6 additions & 0 deletions src/bundle/Resources/config/services/validators.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ services:
EzSystems\EzPlatformUser\Validator\Constraints\UserPasswordValidator:
tags:
- { name: validator.constraint_validator }

EzSystems\EzPlatformUser\Validator\Constraints\PasswordValidator:
arguments:
$userService: '@ezpublish.api.service.user'
tags:
- { name: validator.constraint_validator }
2 changes: 2 additions & 0 deletions src/lib/Form/Data/UserPasswordResetData.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class UserPasswordResetData
private $newPassword;

/**
* @deprecated ContentType should be passed as option to FormType.
*
* @var \eZ\Publish\API\Repository\Values\ContentType\ContentType
*/
private $contentType;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/Form/Data/UserRegisterData.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

namespace EzSystems\EzPlatformUser\Form\Data;

use EzSystems\EzPlatformContentForms\Data as RepositoryFormsData;
use EzSystems\EzPlatformContentForms\Data\User\UserCreateData;

class UserRegisterData extends RepositoryFormsData\User\UserRegisterData
class UserRegisterData extends UserCreateData
{
}
22 changes: 13 additions & 9 deletions src/lib/Form/Factory/FormFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace EzSystems\EzPlatformUser\Form\Factory;

use eZ\Publish\API\Repository\Values\ContentType\ContentType;
use EzSystems\EzPlatformUser\Form\Data\UserPasswordForgotData;
use EzSystems\EzPlatformUser\Form\Data\UserPasswordChangeData;
use EzSystems\EzPlatformUser\Form\Data\UserSettingUpdateData;
Expand Down Expand Up @@ -41,19 +42,19 @@ public function __construct(FormFactoryInterface $formFactory, UrlGeneratorInter
$this->urlGenerator = $urlGenerator;
}

/**
* @param \EzSystems\EzPlatformUser\Form\Data\UserPasswordChangeData|null $data
* @param string|null $name
*
* @return \Symfony\Component\Form\FormInterface
*/
public function changeUserPassword(
ContentType $contentType,
UserPasswordChangeData $data = null,
?string $name = null
): FormInterface {
$name = $name ?: StringUtil::fqcnToBlockPrefix(UserPasswordChangeType::class);

return $this->formFactory->createNamed($name, UserPasswordChangeType::class, $data);
return $this->formFactory->createNamed(
$name,
UserPasswordChangeType::class,
$data,
['content_type' => $contentType]
);
}

/**
Expand Down Expand Up @@ -100,11 +101,14 @@ public function forgotUserPasswordWithLogin(
*/
public function resetUserPassword(
UserPasswordResetData $data = null,
?string $name = null
?string $name = null,
ContentType $contentType = null
): FormInterface {
$name = $name ?: StringUtil::fqcnToBlockPrefix(UserPasswordResetType::class);

return $this->formFactory->createNamed($name, UserPasswordResetType::class, $data, ['content_type' => $data->getContentType()]);
$userContentType = $contentType ?? $data->getContentType();

return $this->formFactory->createNamed($name, UserPasswordResetType::class, $data, ['content_type' => $userContentType]);
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/lib/Form/Type/UserPasswordChangeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

namespace EzSystems\EzPlatformUser\Form\Type;

use eZ\Publish\API\Repository\Values\ContentType\ContentType;
use EzSystems\EzPlatformUser\Form\Data\UserPasswordChangeData;
use EzSystems\EzPlatformUser\Validator\Constraints\Password;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
Expand All @@ -31,6 +33,11 @@ public function buildForm(FormBuilderInterface $builder, array $options)
'required' => true,
'first_options' => ['label' => /** @Desc("New password") */ 'ezplatform.change_user_password.new_password'],
'second_options' => ['label' => /** @Desc("Confirm password") */ 'ezplatform.change_user_password.confirm_new_password'],
'constraints' => [
new Password([
'contentType' => $options['content_type'],
]),
],
])
->add(
'change',
Expand All @@ -41,6 +48,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('content_type');
$resolver->setAllowedTypes('content_type', ContentType::class);
$resolver->setDefaults([
'data_class' => UserPasswordChangeData::class,
'translation_domain' => 'forms',
Expand Down
6 changes: 4 additions & 2 deletions src/lib/Form/Type/UserPasswordResetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

namespace EzSystems\EzPlatformUser\Form\Type;

use eZ\Publish\API\Repository\Values\ContentType\ContentType;
use EzSystems\EzPlatformUser\Form\Data\UserPasswordResetData;
use EzSystems\EzPlatformContentForms\Validator\Constraints\Password;
use EzSystems\EzPlatformUser\Validator\Constraints\Password;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
Expand Down Expand Up @@ -41,10 +42,11 @@ public function buildForm(FormBuilderInterface $builder, array $options)

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('content_type');
$resolver->setAllowedTypes('content_type', ContentType::class);
$resolver->setDefaults([
'data_class' => UserPasswordResetData::class,
'translation_domain' => 'forms',
'content_type' => null,
]);
}
}
31 changes: 31 additions & 0 deletions src/lib/Validator/Constraints/Password.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformUser\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*/
class Password extends Constraint
{
/** @var string */
public $message = 'ez.user.password.invalid';

/** @var \eZ\Publish\API\Repository\Values\ContentType\ContentType|null */
public $contentType;

/**
* {@inheritdoc}
*/
public function getTargets(): array
{
return [self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT];
}
}
48 changes: 48 additions & 0 deletions src/lib/Validator/Constraints/PasswordValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformUser\Validator\Constraints;

use eZ\Publish\API\Repository\UserService;
use eZ\Publish\API\Repository\Values\User\PasswordValidationContext;
use EzSystems\EzPlatformContentForms\Validator\ValidationErrorsProcessor;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class PasswordValidator extends ConstraintValidator
{
/** @var \eZ\Publish\API\Repository\UserService */
private $userService;

public function __construct(UserService $userService)
{
$this->userService = $userService;
}

public function validate($value, Constraint $constraint): void
{
if (!\is_string($value) || empty($value)) {
return;
}

$passwordValidationContext = new PasswordValidationContext([
'contentType' => $constraint->contentType,
]);

$validationErrors = $this->userService->validatePassword($value, $passwordValidationContext);
if (!empty($validationErrors)) {
$validationErrorsProcessor = $this->createValidationErrorsProcessor();
$validationErrorsProcessor->processValidationErrors($validationErrors);
}
}

protected function createValidationErrorsProcessor(): ValidationErrorsProcessor
{
return new ValidationErrorsProcessor($this->context);
}
}
39 changes: 39 additions & 0 deletions tests/lib/Validator/Constraint/PasswordTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformUser\Tests\Validator\Constraint;

use EzSystems\EzPlatformUser\Validator\Constraints\Password;
use EzSystems\EzPlatformUser\Validator\Constraints\PasswordValidator;
use PHPUnit\Framework\TestCase;

class PasswordTest extends TestCase
{
/** @var \EzSystems\EzPlatformUser\Validator\Constraints\Password */
private $constraint;

protected function setUp(): void
{
$this->constraint = new Password();
}

public function testConstruct(): void
{
$this->assertSame('ez.user.password.invalid', $this->constraint->message);
}

public function testValidatedBy(): void
{
$this->assertSame(PasswordValidator::class, $this->constraint->validatedBy());
}

public function testGetTargets(): void
{
$this->assertSame([Password::CLASS_CONSTRAINT, Password::PROPERTY_CONSTRAINT], $this->constraint->getTargets());
}
}
Loading

0 comments on commit 3857004

Please sign in to comment.