From b8f300d34b273a08de1c587785be8621c54f323b Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 14:19:32 +0200
Subject: [PATCH 01/27] Add Validation on RequestResetPassword
---
.../Customer/RequestPasswordResettingAction.php | 16 ++++++++++++++--
.../config/services/actions/customer.xml | 1 +
.../GenerateResetPasswordTokenRequest.xml | 12 ++++++++++++
3 files changed, 27 insertions(+), 2 deletions(-)
create mode 100644 src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index 7a6a12910..0a52d1491 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -10,6 +10,7 @@
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\ShopApiPlugin\CommandProvider\ChannelBasedCommandProviderInterface;
use Sylius\ShopApiPlugin\CommandProvider\CommandProviderInterface;
+use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
@@ -22,6 +23,9 @@ final class RequestPasswordResettingAction
/** @var MessageBusInterface */
private $bus;
+ /** @var ValidationErrorViewFactoryInterface */
+ private $validationErrorViewFactory;
+
/** @var ChannelContextInterface */
private $channelContext;
@@ -34,10 +38,12 @@ final class RequestPasswordResettingAction
public function __construct(
ViewHandlerInterface $viewHandler,
MessageBusInterface $bus,
+ ValidationErrorViewFactoryInterface $validationErrorViewFactory,
ChannelContextInterface $channelContext,
CommandProviderInterface $generateResetPasswordTokenCommandProvider,
ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider
- ) {
+ )
+ {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->channelContext = $channelContext;
@@ -49,7 +55,13 @@ public function __invoke(Request $request): Response
{
/** @var ChannelInterface $channel */
$channel = $this->channelContext->getChannel();
-
+ $validationResults = $this->generateResetPasswordTokenCommandProvider->validate($request);
+ if (0 !== count($validationResults)) {
+ return $this->viewHandler->handle(View::create(
+ $this->validationErrorViewFactory->create($validationResults),
+ Response::HTTP_BAD_REQUEST
+ ));
+ }
$this->bus->dispatch($this->generateResetPasswordTokenCommandProvider->getCommand($request));
$this->bus->dispatch($this->sendResetPasswordTokenCommandProvider->getCommand($request, $channel));
diff --git a/src/Resources/config/services/actions/customer.xml b/src/Resources/config/services/actions/customer.xml
index 4a241f8d9..261c40ba6 100644
--- a/src/Resources/config/services/actions/customer.xml
+++ b/src/Resources/config/services/actions/customer.xml
@@ -42,6 +42,7 @@
>
+
diff --git a/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml b/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml
new file mode 100644
index 000000000..7e965b564
--- /dev/null
+++ b/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
From 58fb7748547333a6542c57eafa3442e25f26330c Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 14:20:07 +0200
Subject: [PATCH 02/27] Add Tests
---
.../Customer/RequestPasswordResettingApiTest.php | 13 +++++++++++++
.../request_reset_password_failed_email.json | 9 +++++++++
2 files changed, 22 insertions(+)
create mode 100644 tests/Responses/Expected/customer/request_reset_password_failed_email.json
diff --git a/tests/Controller/Customer/RequestPasswordResettingApiTest.php b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
index 3c496f2f3..9627d7060 100644
--- a/tests/Controller/Customer/RequestPasswordResettingApiTest.php
+++ b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
@@ -34,6 +34,19 @@ public function it_allows_to_reset_user_password(): void
$this->assertTrue($emailChecker->hasRecipient('oliver@queen.com'));
}
+ public function it_does_not_allow_to_reset_user_password_without_entering_valid_email(): void
+ {
+ $this->loadFixturesFromFiles(['channel.yml', 'customer.yml']);
+
+ $data = '{"email": "oliver"}';
+
+ $this->client->request('PUT', '/shop-api/request-password-reset', [], [], self::CONTENT_TYPE_HEADER, $data);
+
+ $response = $this->client->getResponse();
+ $this->assertResponse($response, 'customer/request_reset_password_failed_email', Response::HTTP_BAD_REQUEST);
+ }
+
+
protected function getContainer(): ContainerInterface
{
return static::$sharedKernel->getContainer();
diff --git a/tests/Responses/Expected/customer/request_reset_password_failed_email.json b/tests/Responses/Expected/customer/request_reset_password_failed_email.json
new file mode 100644
index 000000000..f33026a6a
--- /dev/null
+++ b/tests/Responses/Expected/customer/request_reset_password_failed_email.json
@@ -0,0 +1,9 @@
+{
+ "code": 400,
+ "message": "Validation failed",
+ "errors": {
+ "email": [
+ "This value is not a valid email address."
+ ]
+ }
+}
From 6bcc97e51b20e5fab8b23e7fbc6d82e0a8f7d9d4 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 18:42:12 +0200
Subject: [PATCH 03/27] Fix Email Validation
---
.../RequestPasswordResettingAction.php | 1 +
.../GenerateResetPasswordTokenRequest.xml | 5 ++++-
.../RequestPasswordResettingApiTest.php | 20 +++++++++++++++++++
.../request_reset_password_empty_email.json | 9 +++++++++
.../request_reset_password_failed_email.json | 14 ++++++-------
5 files changed, 41 insertions(+), 8 deletions(-)
create mode 100644 tests/Responses/Expected/customer/request_reset_password_empty_email.json
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index 0a52d1491..21a51c861 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -46,6 +46,7 @@ public function __construct(
{
$this->viewHandler = $viewHandler;
$this->bus = $bus;
+ $this->validationErrorViewFactory = $validationErrorViewFactory;
$this->channelContext = $channelContext;
$this->generateResetPasswordTokenCommandProvider = $generateResetPasswordTokenCommandProvider;
$this->sendResetPasswordTokenCommandProvider = $sendResetPasswordTokenCommandProvider;
diff --git a/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml b/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml
index 7e965b564..64b0d1339 100644
--- a/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml
+++ b/src/Resources/config/validation/customer/GenerateResetPasswordTokenRequest.xml
@@ -2,8 +2,11 @@
-
+
+
+
+
diff --git a/tests/Controller/Customer/RequestPasswordResettingApiTest.php b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
index 9627d7060..16c56154e 100644
--- a/tests/Controller/Customer/RequestPasswordResettingApiTest.php
+++ b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
@@ -17,6 +17,8 @@ final class RequestPasswordResettingApiTest extends JsonApiTestCase
/**
* @test
*/
+
+
public function it_allows_to_reset_user_password(): void
{
$this->loadFixturesFromFiles(['channel.yml', 'customer.yml']);
@@ -34,6 +36,10 @@ public function it_allows_to_reset_user_password(): void
$this->assertTrue($emailChecker->hasRecipient('oliver@queen.com'));
}
+
+ /**
+ * @test
+ */
public function it_does_not_allow_to_reset_user_password_without_entering_valid_email(): void
{
$this->loadFixturesFromFiles(['channel.yml', 'customer.yml']);
@@ -46,6 +52,20 @@ public function it_does_not_allow_to_reset_user_password_without_entering_valid_
$this->assertResponse($response, 'customer/request_reset_password_failed_email', Response::HTTP_BAD_REQUEST);
}
+ /**
+ * @test
+ */
+ public function it_does_not_allow_to_reset_user_password_without_entering_email(): void
+ {
+ $this->loadFixturesFromFiles(['channel.yml', 'customer.yml']);
+
+ $data = '{}';
+
+ $this->client->request('PUT', '/shop-api/request-password-reset', [], [], self::CONTENT_TYPE_HEADER, $data);
+
+ $response = $this->client->getResponse();
+ $this->assertResponse($response, 'customer/request_reset_password_empty_email', Response::HTTP_BAD_REQUEST);
+ }
protected function getContainer(): ContainerInterface
{
diff --git a/tests/Responses/Expected/customer/request_reset_password_empty_email.json b/tests/Responses/Expected/customer/request_reset_password_empty_email.json
new file mode 100644
index 000000000..1a910c0fa
--- /dev/null
+++ b/tests/Responses/Expected/customer/request_reset_password_empty_email.json
@@ -0,0 +1,9 @@
+{
+ "code": 400,
+ "message": "Validation failed",
+ "errors": {
+ "email": [
+ "Please enter your email."
+ ]
+ }
+}
diff --git a/tests/Responses/Expected/customer/request_reset_password_failed_email.json b/tests/Responses/Expected/customer/request_reset_password_failed_email.json
index f33026a6a..168f79134 100644
--- a/tests/Responses/Expected/customer/request_reset_password_failed_email.json
+++ b/tests/Responses/Expected/customer/request_reset_password_failed_email.json
@@ -1,9 +1,9 @@
{
- "code": 400,
- "message": "Validation failed",
- "errors": {
- "email": [
- "This value is not a valid email address."
- ]
- }
+ "code": 400,
+ "message": "Validation failed",
+ "errors": {
+ "email": [
+ "This email is invalid."
+ ]
+ }
}
From b761ad9b1b79e97377b78de0b33fe665f0b63ce4 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 19:13:55 +0200
Subject: [PATCH 04/27] Handle email not exists RequestResetPassword
---
.../GenerateResetPasswordTokenHandler.php | 9 ++++-----
.../Customer/SendResetPasswordTokenHandler.php | 16 ++++++++--------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
index 18f1b6c4f..97718ef6a 100644
--- a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
@@ -8,7 +8,6 @@
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\Component\User\Security\Generator\GeneratorInterface;
use Sylius\ShopApiPlugin\Command\Customer\GenerateResetPasswordToken;
-use Webmozart\Assert\Assert;
final class GenerateResetPasswordTokenHandler
{
@@ -30,10 +29,10 @@ public function __invoke(GenerateResetPasswordToken $generateResetPasswordToken)
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
+ if (null !== $user) {
+ $user->setPasswordResetToken($this->tokenGenerator->generate());
+ $user->setPasswordRequestedAt(new \DateTime());
+ }
- Assert::notNull($user, sprintf('User with %s email has not been found.', $email));
-
- $user->setPasswordResetToken($this->tokenGenerator->generate());
- $user->setPasswordRequestedAt(new \DateTime());
}
}
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index 2054a54b2..411a357c6 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -31,14 +31,14 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
+ if (null !== $user) {
+ Assert::notNull($user->getPasswordResetToken(), sprintf('User with %s email has not verification token defined.', $email));
+ $this->sender->send(
+ Emails::EMAIL_RESET_PASSWORD_TOKEN,
+ [$email],
+ ['user' => $user, 'channelCode' => $resendResetPasswordToken->channelCode()]
+ );
+ }
- Assert::notNull($user, sprintf('User with %s email has not been found.', $email));
- Assert::notNull($user->getPasswordResetToken(), sprintf('User with %s email has not verification token defined.', $email));
-
- $this->sender->send(
- Emails::EMAIL_RESET_PASSWORD_TOKEN,
- [$email],
- ['user' => $user, 'channelCode' => $resendResetPasswordToken->channelCode()]
- );
}
}
From 019cb00c383e4cade24c8035e0e0d14c1b642f97 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 19:16:01 +0200
Subject: [PATCH 05/27] Add Test email doesn't exist RequestResetPassword
---
.../Customer/RequestPasswordResettingApiTest.php | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tests/Controller/Customer/RequestPasswordResettingApiTest.php b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
index 16c56154e..76df861c8 100644
--- a/tests/Controller/Customer/RequestPasswordResettingApiTest.php
+++ b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
@@ -67,6 +67,21 @@ public function it_does_not_allow_to_reset_user_password_without_entering_email(
$this->assertResponse($response, 'customer/request_reset_password_empty_email', Response::HTTP_BAD_REQUEST);
}
+ /**
+ * @test
+ */
+ public function it_allow_to_reset_user_password_without_sending_mail_user_not_exist(): void
+ {
+ $this->loadFixturesFromFiles(['channel.yml', 'customer.yml']);
+
+ $data = '{"email": "Amr@amr.com"}';
+
+ $this->client->request('PUT', '/shop-api/request-password-reset', [], [], self::CONTENT_TYPE_HEADER, $data);
+
+ $response = $this->client->getResponse();
+ $this->assertResponseCode($response, Response::HTTP_NO_CONTENT);
+ }
+
protected function getContainer(): ContainerInterface
{
return static::$sharedKernel->getContainer();
From a5711ddebc8439c495ecc4a2f1d8f9952e580974 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 19:16:28 +0200
Subject: [PATCH 06/27] Add docs email doesn't exist RequestResetPassword
---
doc/swagger.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/swagger.yml b/doc/swagger.yml
index eda95c905..4a6587954 100644
--- a/doc/swagger.yml
+++ b/doc/swagger.yml
@@ -709,9 +709,9 @@ paths:
$ref: "#/definitions/RequestPasswordResetting"
responses:
204:
- description: "Reset password request has been sent."
- 500:
- description: "User with provided email has not been found."
+ description: "Reset password request has been sent If the email exists in our system,."
+ 400:
+ description: "Email not valid"
/password-reset/{token}:
parameters:
From 3d320f82bf3b031dde287b67531041bfb34116e4 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 10 Jan 2020 21:49:34 +0200
Subject: [PATCH 07/27] Remove user not found from specs
---
.../Customer/GenerateResetPasswordTokenHandlerSpec.php | 7 -------
.../Customer/SendResetPasswordTokenHandlerSpec.php | 9 +--------
2 files changed, 1 insertion(+), 15 deletions(-)
diff --git a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
index e2a950c60..e7b8fb2d4 100644
--- a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
@@ -39,11 +39,4 @@ function it_handles_generating_user_verification_token(
$this(new GenerateResetPasswordToken('example@customer.com'));
}
- function it_throws_an_exception_if_user_has_not_been_found(
- UserRepositoryInterface $userRepository
- ): void {
- $userRepository->findOneByEmail('example@customer.com')->willReturn(null);
-
- $this->shouldThrow(\InvalidArgumentException::class)->during('__invoke', [new GenerateResetPasswordToken('example@customer.com')]);
- }
}
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index ab62d3b6e..18aff4fe7 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -36,14 +36,7 @@ function it_handles_emailing_user_with_verification_email(
$this(new SendResetPasswordToken('example@customer.com', 'WEB_GB'));
}
-
- function it_throws_an_exception_if_user_has_not_been_found(
- UserRepositoryInterface $userRepository
- ): void {
- $userRepository->findOneByEmail('example@customer.com')->willReturn(null);
-
- $this->shouldThrow(\InvalidArgumentException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
- }
+
function it_throws_an_exception_if_user_has_not_verification_token(
UserRepositoryInterface $userRepository,
From caaeeca5a7b7080ece258fac8a5e8d2ee9fbab6d Mon Sep 17 00:00:00 2001
From: mamazu <14860264+mamazu@users.noreply.github.com>
Date: Sat, 11 Jan 2020 13:07:07 +0100
Subject: [PATCH 08/27] Codestyle
---
.../Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php | 1 -
spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php | 1 -
src/Controller/Customer/RequestPasswordResettingAction.php | 3 +--
src/Handler/Customer/GenerateResetPasswordTokenHandler.php | 1 -
src/Handler/Customer/SendResetPasswordTokenHandler.php | 1 -
tests/Controller/Customer/RequestPasswordResettingApiTest.php | 3 ---
6 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
index e7b8fb2d4..edd664d9e 100644
--- a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
@@ -38,5 +38,4 @@ function it_handles_generating_user_verification_token(
$this(new GenerateResetPasswordToken('example@customer.com'));
}
-
}
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index 18aff4fe7..1f3d01379 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -36,7 +36,6 @@ function it_handles_emailing_user_with_verification_email(
$this(new SendResetPasswordToken('example@customer.com', 'WEB_GB'));
}
-
function it_throws_an_exception_if_user_has_not_verification_token(
UserRepositoryInterface $userRepository,
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index 21a51c861..e294820d5 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -42,8 +42,7 @@ public function __construct(
ChannelContextInterface $channelContext,
CommandProviderInterface $generateResetPasswordTokenCommandProvider,
ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider
- )
- {
+ ) {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->validationErrorViewFactory = $validationErrorViewFactory;
diff --git a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
index 97718ef6a..be21de7cd 100644
--- a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
@@ -33,6 +33,5 @@ public function __invoke(GenerateResetPasswordToken $generateResetPasswordToken)
$user->setPasswordResetToken($this->tokenGenerator->generate());
$user->setPasswordRequestedAt(new \DateTime());
}
-
}
}
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index 411a357c6..7169b97d4 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -39,6 +39,5 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
['user' => $user, 'channelCode' => $resendResetPasswordToken->channelCode()]
);
}
-
}
}
diff --git a/tests/Controller/Customer/RequestPasswordResettingApiTest.php b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
index 76df861c8..1302bcdcb 100644
--- a/tests/Controller/Customer/RequestPasswordResettingApiTest.php
+++ b/tests/Controller/Customer/RequestPasswordResettingApiTest.php
@@ -17,8 +17,6 @@ final class RequestPasswordResettingApiTest extends JsonApiTestCase
/**
* @test
*/
-
-
public function it_allows_to_reset_user_password(): void
{
$this->loadFixturesFromFiles(['channel.yml', 'customer.yml']);
@@ -36,7 +34,6 @@ public function it_allows_to_reset_user_password(): void
$this->assertTrue($emailChecker->hasRecipient('oliver@queen.com'));
}
-
/**
* @test
*/
From 133f48cb1ffc02ad0d3e027b5961ea1ea67fa2e2 Mon Sep 17 00:00:00 2001
From: mamazu <14860264+mamazu@users.noreply.github.com>
Date: Sat, 11 Jan 2020 13:10:43 +0100
Subject: [PATCH 09/27] Documenting changes in passwort reset endpoint
---
UPGRADE.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/UPGRADE.md b/UPGRADE.md
index 21fc074db..6b53e3f2c 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -7,6 +7,7 @@ access_control:
- { path: "%sylius_shop_api.security.regex%/me", role: ROLE_USER}
```
+* The forgot passwort function now doesn't return an error if the user with this email is not found. It might give a potential attacker information about which users are registered in the shop.
# UPGRADE FROM 1.0.0-rc.2 or 1.0.0-rc.3 to 1.0.0
From 113a9805fd692f0de30141a041557b0e79d8182f Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Sat, 11 Jan 2020 15:40:00 +0200
Subject: [PATCH 10/27] Fix Typo
---
UPGRADE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/UPGRADE.md b/UPGRADE.md
index 6b53e3f2c..a9792b126 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -7,7 +7,7 @@ access_control:
- { path: "%sylius_shop_api.security.regex%/me", role: ROLE_USER}
```
-* The forgot passwort function now doesn't return an error if the user with this email is not found. It might give a potential attacker information about which users are registered in the shop.
+* The forgot password function now doesn't return an error if the user with this email is not found. It might give a potential attacker information about which users are registered in the shop.
# UPGRADE FROM 1.0.0-rc.2 or 1.0.0-rc.3 to 1.0.0
From fefbc304278fba45656b57d2dca842118cc7e1a5 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Sat, 11 Jan 2020 16:14:29 +0200
Subject: [PATCH 11/27] Make Logic clearer ResetPassword
---
.../GenerateResetPasswordTokenHandler.php | 8 +++++---
.../Customer/SendResetPasswordTokenHandler.php | 16 +++++++++-------
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
index be21de7cd..2c16b0565 100644
--- a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
@@ -29,9 +29,11 @@ public function __invoke(GenerateResetPasswordToken $generateResetPasswordToken)
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
- if (null !== $user) {
- $user->setPasswordResetToken($this->tokenGenerator->generate());
- $user->setPasswordRequestedAt(new \DateTime());
+ if (null === $user) {
+ return;
}
+ $user->setPasswordResetToken($this->tokenGenerator->generate());
+ $user->setPasswordRequestedAt(new \DateTime());
+
}
}
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index 7169b97d4..00ed4e521 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -31,13 +31,15 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
- if (null !== $user) {
- Assert::notNull($user->getPasswordResetToken(), sprintf('User with %s email has not verification token defined.', $email));
- $this->sender->send(
- Emails::EMAIL_RESET_PASSWORD_TOKEN,
- [$email],
- ['user' => $user, 'channelCode' => $resendResetPasswordToken->channelCode()]
- );
+ if (null === $user) {
+ return;
}
+ Assert::notNull($user->getPasswordResetToken(), sprintf('User with %s email has not verification token defined.', $email));
+ $this->sender->send(
+ Emails::EMAIL_RESET_PASSWORD_TOKEN,
+ [$email],
+ ['user' => $user, 'channelCode' => $resendResetPasswordToken->channelCode()]
+ );
}
+
}
From e19b3a3dfe6605e4ab3e4b3c5722d91e3274ce70 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Sat, 11 Jan 2020 18:52:59 +0200
Subject: [PATCH 12/27] Add Specs ResetPassword
---
.../GenerateResetPasswordTokenHandlerSpec.php | 11 +++++++++++
.../Customer/SendResetPasswordTokenHandlerSpec.php | 9 +++++++++
2 files changed, 20 insertions(+)
diff --git a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
index edd664d9e..a22ef9492 100644
--- a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
@@ -38,4 +38,15 @@ function it_handles_generating_user_verification_token(
$this(new GenerateResetPasswordToken('example@customer.com'));
}
+
+ function it_continues_if_user_not_found(
+ UserRepositoryInterface $userRepository,
+ GeneratorInterface $tokenGenerator,
+ ShopUserInterface $user
+ ): void {
+ $userRepository->findOneByEmail('amr@amr.com')->willReturn(null);
+ $tokenGenerator->generate()->shouldNotBeCalled();
+ $user->setPasswordResetToken('RANDOM_TOKEN')->shouldNotBeCalled();
+ $user->setPasswordRequestedAt(Argument::type(\DateTime::class))->shouldNotBeCalled();
+ }
}
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index 1f3d01379..6ea679422 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -46,4 +46,13 @@ function it_throws_an_exception_if_user_has_not_verification_token(
$this->shouldThrow(\InvalidArgumentException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
}
+
+ function it_continues_if_user_not_found(
+ UserRepositoryInterface $userRepository,
+ SenderInterface $sender,
+ ShopUserInterface $user
+ ): void {
+ $userRepository->findOneByEmail('amr@amr.com')->willReturn(null);
+ $sender->send(Emails::EMAIL_RESET_PASSWORD_TOKEN, ['example@customer.com'], ['user' => $user, 'channelCode' => 'WEB_GB'])->shouldNotBeCalled();
+ }
}
From 7667198d963e4f9b416a403d2788f830918ebb76 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Thu, 16 Jan 2020 23:44:49 +0200
Subject: [PATCH 13/27] Fix SendResetPassword Specs
---
spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index 6ea679422..953ee2daf 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -5,6 +5,7 @@
namespace spec\Sylius\ShopApiPlugin\Handler\Customer;
use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
@@ -53,6 +54,6 @@ function it_continues_if_user_not_found(
ShopUserInterface $user
): void {
$userRepository->findOneByEmail('amr@amr.com')->willReturn(null);
- $sender->send(Emails::EMAIL_RESET_PASSWORD_TOKEN, ['example@customer.com'], ['user' => $user, 'channelCode' => 'WEB_GB'])->shouldNotBeCalled();
+ $sender->send(Argument::any())->shouldNotBeCalled();
}
}
From 3117dc81db298896e8fc93df50d826c18670b498 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Fri, 17 Jan 2020 11:28:47 +0200
Subject: [PATCH 14/27] Fix Composer
---
src/Handler/Customer/GenerateResetPasswordTokenHandler.php | 1 -
src/Handler/Customer/SendResetPasswordTokenHandler.php | 1 -
2 files changed, 2 deletions(-)
diff --git a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
index 2c16b0565..4cf29f834 100644
--- a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
@@ -34,6 +34,5 @@ public function __invoke(GenerateResetPasswordToken $generateResetPasswordToken)
}
$user->setPasswordResetToken($this->tokenGenerator->generate());
$user->setPasswordRequestedAt(new \DateTime());
-
}
}
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index 00ed4e521..ed7bbaf31 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -41,5 +41,4 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
['user' => $user, 'channelCode' => $resendResetPasswordToken->channelCode()]
);
}
-
}
From 2a79e434518e168609316103031120aacbbfe861 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Sat, 18 Jan 2020 17:32:01 +0200
Subject: [PATCH 15/27] Add ValidationViewFactory last argument
---
.../Customer/RequestPasswordResettingAction.php | 10 +++++++---
src/Resources/config/services/actions/customer.xml | 2 +-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index e294820d5..5a7161a54 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -38,17 +38,21 @@ final class RequestPasswordResettingAction
public function __construct(
ViewHandlerInterface $viewHandler,
MessageBusInterface $bus,
- ValidationErrorViewFactoryInterface $validationErrorViewFactory,
ChannelContextInterface $channelContext,
CommandProviderInterface $generateResetPasswordTokenCommandProvider,
- ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider
+ ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider,
+ ?ValidationErrorViewFactoryInterface $validationErrorViewFactory
) {
+ if (null !== $validationErrorViewFactory) {
+ @trigger_error('Passing ValidationErrorViewFactory as the fourth argument is deprecated', \E_USER_DEPRECATED);
+ }
+
$this->viewHandler = $viewHandler;
$this->bus = $bus;
- $this->validationErrorViewFactory = $validationErrorViewFactory;
$this->channelContext = $channelContext;
$this->generateResetPasswordTokenCommandProvider = $generateResetPasswordTokenCommandProvider;
$this->sendResetPasswordTokenCommandProvider = $sendResetPasswordTokenCommandProvider;
+ $this->validationErrorViewFactory = $validationErrorViewFactory;
}
public function __invoke(Request $request): Response
diff --git a/src/Resources/config/services/actions/customer.xml b/src/Resources/config/services/actions/customer.xml
index 261c40ba6..dda8ed916 100644
--- a/src/Resources/config/services/actions/customer.xml
+++ b/src/Resources/config/services/actions/customer.xml
@@ -42,10 +42,10 @@
>
-
+
Date: Sat, 18 Jan 2020 17:58:16 +0200
Subject: [PATCH 16/27] Make Handlers throw exceptions
---
.../Customer/RequestPasswordResettingAction.php | 10 ++++++++--
.../Customer/GenerateResetPasswordTokenHandler.php | 3 ++-
src/Handler/Customer/SendResetPasswordTokenHandler.php | 7 +++++--
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index 5a7161a54..f9d56907a 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -13,6 +13,8 @@
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\MessageBusInterface;
final class RequestPasswordResettingAction
@@ -66,8 +68,12 @@ public function __invoke(Request $request): Response
Response::HTTP_BAD_REQUEST
));
}
- $this->bus->dispatch($this->generateResetPasswordTokenCommandProvider->getCommand($request));
- $this->bus->dispatch($this->sendResetPasswordTokenCommandProvider->getCommand($request, $channel));
+
+ try {
+ $this->bus->dispatch($this->generateResetPasswordTokenCommandProvider->getCommand($request));
+ $this->bus->dispatch($this->sendResetPasswordTokenCommandProvider->getCommand($request, $channel));
+ } catch (HandlerFailedException $notFoundHttpException) {
+ }
return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
}
diff --git a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
index 4cf29f834..601cc480d 100644
--- a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
@@ -8,6 +8,7 @@
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\Component\User\Security\Generator\GeneratorInterface;
use Sylius\ShopApiPlugin\Command\Customer\GenerateResetPasswordToken;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
final class GenerateResetPasswordTokenHandler
{
@@ -30,7 +31,7 @@ public function __invoke(GenerateResetPasswordToken $generateResetPasswordToken)
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
if (null === $user) {
- return;
+ throw new NotFoundHttpException('User with given email does not exist!');
}
$user->setPasswordResetToken($this->tokenGenerator->generate());
$user->setPasswordRequestedAt(new \DateTime());
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index ed7bbaf31..9dfea590c 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -9,6 +9,7 @@
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\ShopApiPlugin\Command\Customer\SendResetPasswordToken;
use Sylius\ShopApiPlugin\Mailer\Emails;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webmozart\Assert\Assert;
final class SendResetPasswordTokenHandler
@@ -32,9 +33,11 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
if (null === $user) {
- return;
+ throw new NotFoundHttpException('User with given email does not exist!');
+ }
+ if (null === $user->getPasswordResetToken()) {
+ throw new NotFoundHttpException(sprintf('User with %s email has not verification token defined.', $email));
}
- Assert::notNull($user->getPasswordResetToken(), sprintf('User with %s email has not verification token defined.', $email));
$this->sender->send(
Emails::EMAIL_RESET_PASSWORD_TOKEN,
[$email],
From d73537bc8a5cccc74c30e92cd506d0cbeddcbb68 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Sat, 18 Jan 2020 18:18:49 +0200
Subject: [PATCH 17/27] Add Specs
---
.../GenerateResetPasswordTokenHandlerSpec.php | 13 +++++--------
.../Customer/SendResetPasswordTokenHandlerSpec.php | 14 ++++++--------
2 files changed, 11 insertions(+), 16 deletions(-)
diff --git a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
index a22ef9492..387a52640 100644
--- a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
@@ -11,6 +11,7 @@
use Sylius\Component\User\Security\Generator\GeneratorInterface;
use Sylius\ShopApiPlugin\Command\Customer\GenerateResetPasswordToken;
use Sylius\ShopApiPlugin\Handler\Customer\GenerateResetPasswordTokenHandler;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
final class GenerateResetPasswordTokenHandlerSpec extends ObjectBehavior
{
@@ -39,14 +40,10 @@ function it_handles_generating_user_verification_token(
$this(new GenerateResetPasswordToken('example@customer.com'));
}
- function it_continues_if_user_not_found(
- UserRepositoryInterface $userRepository,
- GeneratorInterface $tokenGenerator,
- ShopUserInterface $user
+ function it_throws_an_exception_if_user_has_not_been_found(
+ UserRepositoryInterface $userRepository
): void {
- $userRepository->findOneByEmail('amr@amr.com')->willReturn(null);
- $tokenGenerator->generate()->shouldNotBeCalled();
- $user->setPasswordResetToken('RANDOM_TOKEN')->shouldNotBeCalled();
- $user->setPasswordRequestedAt(Argument::type(\DateTime::class))->shouldNotBeCalled();
+ $userRepository->findOneByEmail('example@customer.com')->willReturn(null);
+ $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [new GenerateResetPasswordToken('example@customer.com')]);
}
}
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index 953ee2daf..50e660d74 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -5,13 +5,13 @@
namespace spec\Sylius\ShopApiPlugin\Handler\Customer;
use PhpSpec\ObjectBehavior;
-use Prophecy\Argument;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\ShopApiPlugin\Command\Customer\SendResetPasswordToken;
use Sylius\ShopApiPlugin\Handler\Customer\SendResetPasswordTokenHandler;
use Sylius\ShopApiPlugin\Mailer\Emails;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
final class SendResetPasswordTokenHandlerSpec extends ObjectBehavior
{
@@ -45,15 +45,13 @@ function it_throws_an_exception_if_user_has_not_verification_token(
$userRepository->findOneByEmail('example@customer.com')->willReturn($user);
$user->getPasswordResetToken()->willReturn(null);
- $this->shouldThrow(\InvalidArgumentException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
+ $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
}
- function it_continues_if_user_not_found(
- UserRepositoryInterface $userRepository,
- SenderInterface $sender,
- ShopUserInterface $user
+ function it_throws_an_exception_if_user_has_not_been_found(
+ UserRepositoryInterface $userRepository
): void {
- $userRepository->findOneByEmail('amr@amr.com')->willReturn(null);
- $sender->send(Argument::any())->shouldNotBeCalled();
+ $userRepository->findOneByEmail('example@customer.com')->willReturn(null);
+ $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
}
}
From 5036738de410cdf5e0fa3bf51c06b01171340698 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Sat, 18 Jan 2020 18:19:10 +0200
Subject: [PATCH 18/27] Remove Unused classes
---
src/Controller/Customer/RequestPasswordResettingAction.php | 1 -
src/Handler/Customer/SendResetPasswordTokenHandler.php | 1 -
2 files changed, 2 deletions(-)
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index f9d56907a..d2c9d203b 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -13,7 +13,6 @@
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\MessageBusInterface;
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index 9dfea590c..0f26946fd 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -10,7 +10,6 @@
use Sylius\ShopApiPlugin\Command\Customer\SendResetPasswordToken;
use Sylius\ShopApiPlugin\Mailer\Emails;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Webmozart\Assert\Assert;
final class SendResetPasswordTokenHandler
{
From 7fca470add2876a8aeef92df2a00ba3f8c5f212a Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Tue, 21 Jan 2020 22:00:55 +0200
Subject: [PATCH 19/27] Create UserNotFound Exception
---
.../RequestPasswordResettingAction.php | 11 ++++++++--
src/Exception/UserNotFoundException.php | 20 +++++++++++++++++++
.../GenerateResetPasswordTokenHandler.php | 4 ++--
.../SendResetPasswordTokenHandler.php | 7 ++++---
4 files changed, 35 insertions(+), 7 deletions(-)
create mode 100644 src/Exception/UserNotFoundException.php
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index d2c9d203b..e7de42f2d 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -10,6 +10,7 @@
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\ShopApiPlugin\CommandProvider\ChannelBasedCommandProviderInterface;
use Sylius\ShopApiPlugin\CommandProvider\CommandProviderInterface;
+use Sylius\ShopApiPlugin\Exception\UserNotFoundException;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -43,7 +44,8 @@ public function __construct(
CommandProviderInterface $generateResetPasswordTokenCommandProvider,
ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider,
?ValidationErrorViewFactoryInterface $validationErrorViewFactory
- ) {
+ )
+ {
if (null !== $validationErrorViewFactory) {
@trigger_error('Passing ValidationErrorViewFactory as the fourth argument is deprecated', \E_USER_DEPRECATED);
}
@@ -71,7 +73,12 @@ public function __invoke(Request $request): Response
try {
$this->bus->dispatch($this->generateResetPasswordTokenCommandProvider->getCommand($request));
$this->bus->dispatch($this->sendResetPasswordTokenCommandProvider->getCommand($request, $channel));
- } catch (HandlerFailedException $notFoundHttpException) {
+ } catch (HandlerFailedException $exception) {
+ $previousException = $exception->getPrevious();
+ if ($previousException instanceof UserNotFoundException) {
+ return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
+ }
+ throw $exception;
}
return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
diff --git a/src/Exception/UserNotFoundException.php b/src/Exception/UserNotFoundException.php
new file mode 100644
index 000000000..ff057bb54
--- /dev/null
+++ b/src/Exception/UserNotFoundException.php
@@ -0,0 +1,20 @@
+userRepository->findOneByEmail($email);
if (null === $user) {
- throw new NotFoundHttpException('User with given email does not exist!');
+ throw UserNotFoundException::withEmail($email);
}
$user->setPasswordResetToken($this->tokenGenerator->generate());
$user->setPasswordRequestedAt(new \DateTime());
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index 0f26946fd..b7215031e 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -8,8 +8,9 @@
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\ShopApiPlugin\Command\Customer\SendResetPasswordToken;
+use Sylius\ShopApiPlugin\Exception\UserNotFoundException;
use Sylius\ShopApiPlugin\Mailer\Emails;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use InvalidArgumentException;
final class SendResetPasswordTokenHandler
{
@@ -32,10 +33,10 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
/** @var ShopUserInterface $user */
$user = $this->userRepository->findOneByEmail($email);
if (null === $user) {
- throw new NotFoundHttpException('User with given email does not exist!');
+ throw UserNotFoundException::withEmail($email);
}
if (null === $user->getPasswordResetToken()) {
- throw new NotFoundHttpException(sprintf('User with %s email has not verification token defined.', $email));
+ throw new InvalidArgumentException(sprintf('User with %s email has not verification token defined.', $email));
}
$this->sender->send(
Emails::EMAIL_RESET_PASSWORD_TOKEN,
From f4abe0775181f69417a43da927d81f69b9d1f803 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <31932378+Amr3zzat@users.noreply.github.com>
Date: Wed, 22 Jan 2020 23:16:04 +0200
Subject: [PATCH 20/27] Update
src/Controller/Customer/RequestPasswordResettingAction.php
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Łukasz Chruściel
---
src/Controller/Customer/RequestPasswordResettingAction.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index e7de42f2d..6dae2df27 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -44,7 +44,7 @@ public function __construct(
CommandProviderInterface $generateResetPasswordTokenCommandProvider,
ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider,
?ValidationErrorViewFactoryInterface $validationErrorViewFactory
- )
+ ) {
{
if (null !== $validationErrorViewFactory) {
@trigger_error('Passing ValidationErrorViewFactory as the fourth argument is deprecated', \E_USER_DEPRECATED);
From a35aec7a00c98b267320ae4ed131829d250f33df Mon Sep 17 00:00:00 2001
From: Amr Ezzat <31932378+Amr3zzat@users.noreply.github.com>
Date: Wed, 22 Jan 2020 23:16:42 +0200
Subject: [PATCH 21/27] Update
src/Controller/Customer/RequestPasswordResettingAction.php
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Łukasz Chruściel
---
src/Controller/Customer/RequestPasswordResettingAction.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index 6dae2df27..af1a0e352 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -45,7 +45,6 @@ public function __construct(
ChannelBasedCommandProviderInterface $sendResetPasswordTokenCommandProvider,
?ValidationErrorViewFactoryInterface $validationErrorViewFactory
) {
- {
if (null !== $validationErrorViewFactory) {
@trigger_error('Passing ValidationErrorViewFactory as the fourth argument is deprecated', \E_USER_DEPRECATED);
}
From 97e8ed2c870154a37905c99eb93d7b1bcd2d0b25 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <31932378+Amr3zzat@users.noreply.github.com>
Date: Wed, 22 Jan 2020 23:17:03 +0200
Subject: [PATCH 22/27] Update src/Exception/UserNotFoundException.php
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Łukasz Chruściel
---
src/Exception/UserNotFoundException.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Exception/UserNotFoundException.php b/src/Exception/UserNotFoundException.php
index ff057bb54..df953bcee 100644
--- a/src/Exception/UserNotFoundException.php
+++ b/src/Exception/UserNotFoundException.php
@@ -5,7 +5,7 @@
namespace Sylius\ShopApiPlugin\Exception;
-class UserNotFoundException extends \InvalidArgumentException
+final class UserNotFoundException extends \InvalidArgumentException
{
public static function occur(): self
{
From bd3ba0092f16e6915dacdb8fe9a171b761d54a5c Mon Sep 17 00:00:00 2001
From: Amr Ezzat <31932378+Amr3zzat@users.noreply.github.com>
Date: Wed, 22 Jan 2020 23:17:17 +0200
Subject: [PATCH 23/27] Update src/Exception/UserNotFoundException.php
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Łukasz Chruściel
---
src/Exception/UserNotFoundException.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Exception/UserNotFoundException.php b/src/Exception/UserNotFoundException.php
index df953bcee..c90d01545 100644
--- a/src/Exception/UserNotFoundException.php
+++ b/src/Exception/UserNotFoundException.php
@@ -16,5 +16,4 @@ public static function withEmail(string $email): self
{
return new self(sprintf('User with email %s has not been found.', $email));
}
-
}
From 0ed1096e5a74de173413f77570914e6cf254598d Mon Sep 17 00:00:00 2001
From: Amr Ezzat <31932378+Amr3zzat@users.noreply.github.com>
Date: Wed, 22 Jan 2020 23:17:30 +0200
Subject: [PATCH 24/27] Update src/Exception/UserNotFoundException.php
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Łukasz Chruściel
---
src/Exception/UserNotFoundException.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Exception/UserNotFoundException.php b/src/Exception/UserNotFoundException.php
index c90d01545..4dae4fb60 100644
--- a/src/Exception/UserNotFoundException.php
+++ b/src/Exception/UserNotFoundException.php
@@ -4,7 +4,6 @@
namespace Sylius\ShopApiPlugin\Exception;
-
final class UserNotFoundException extends \InvalidArgumentException
{
public static function occur(): self
From cd178269c404a8e45a983fdb7ad218f0943ec611 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Wed, 22 Jan 2020 23:30:46 +0200
Subject: [PATCH 25/27] Update Specs
---
.../Customer/GenerateResetPasswordTokenHandlerSpec.php | 4 ++--
.../Handler/Customer/SendResetPasswordTokenHandlerSpec.php | 7 ++++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
index 387a52640..504dd6ebf 100644
--- a/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/GenerateResetPasswordTokenHandlerSpec.php
@@ -10,8 +10,8 @@
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\Component\User\Security\Generator\GeneratorInterface;
use Sylius\ShopApiPlugin\Command\Customer\GenerateResetPasswordToken;
+use Sylius\ShopApiPlugin\Exception\UserNotFoundException;
use Sylius\ShopApiPlugin\Handler\Customer\GenerateResetPasswordTokenHandler;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
final class GenerateResetPasswordTokenHandlerSpec extends ObjectBehavior
{
@@ -44,6 +44,6 @@ function it_throws_an_exception_if_user_has_not_been_found(
UserRepositoryInterface $userRepository
): void {
$userRepository->findOneByEmail('example@customer.com')->willReturn(null);
- $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [new GenerateResetPasswordToken('example@customer.com')]);
+ $this->shouldThrow(UserNotFoundException::class)->during('__invoke', [new GenerateResetPasswordToken('example@customer.com')]);
}
}
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index 50e660d74..68e0055f9 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -9,9 +9,10 @@
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\ShopApiPlugin\Command\Customer\SendResetPasswordToken;
+use Sylius\ShopApiPlugin\Exception\UserNotFoundException;
use Sylius\ShopApiPlugin\Handler\Customer\SendResetPasswordTokenHandler;
use Sylius\ShopApiPlugin\Mailer\Emails;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use InvalidArgumentException;
final class SendResetPasswordTokenHandlerSpec extends ObjectBehavior
{
@@ -45,13 +46,13 @@ function it_throws_an_exception_if_user_has_not_verification_token(
$userRepository->findOneByEmail('example@customer.com')->willReturn($user);
$user->getPasswordResetToken()->willReturn(null);
- $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
+ $this->shouldThrow(InvalidArgumentException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
}
function it_throws_an_exception_if_user_has_not_been_found(
UserRepositoryInterface $userRepository
): void {
$userRepository->findOneByEmail('example@customer.com')->willReturn(null);
- $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
+ $this->shouldThrow(UserNotFoundException::class)->during('__invoke', [new SendResetPasswordToken('example@customer.com', 'WEB_GB')]);
}
}
From 1c09aa6a0bfb0ef96a029fbc80b01c4a2b6f3887 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Wed, 22 Jan 2020 23:32:52 +0200
Subject: [PATCH 26/27] Code Style
---
spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php | 2 +-
src/Controller/Customer/RequestPasswordResettingAction.php | 1 +
src/Handler/Customer/SendResetPasswordTokenHandler.php | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
index 68e0055f9..7f82e57cf 100644
--- a/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
+++ b/spec/Handler/Customer/SendResetPasswordTokenHandlerSpec.php
@@ -4,6 +4,7 @@
namespace spec\Sylius\ShopApiPlugin\Handler\Customer;
+use InvalidArgumentException;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;
@@ -12,7 +13,6 @@
use Sylius\ShopApiPlugin\Exception\UserNotFoundException;
use Sylius\ShopApiPlugin\Handler\Customer\SendResetPasswordTokenHandler;
use Sylius\ShopApiPlugin\Mailer\Emails;
-use InvalidArgumentException;
final class SendResetPasswordTokenHandlerSpec extends ObjectBehavior
{
diff --git a/src/Controller/Customer/RequestPasswordResettingAction.php b/src/Controller/Customer/RequestPasswordResettingAction.php
index af1a0e352..f79b845d2 100644
--- a/src/Controller/Customer/RequestPasswordResettingAction.php
+++ b/src/Controller/Customer/RequestPasswordResettingAction.php
@@ -77,6 +77,7 @@ public function __invoke(Request $request): Response
if ($previousException instanceof UserNotFoundException) {
return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
}
+
throw $exception;
}
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index b7215031e..fad32be9d 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -4,13 +4,13 @@
namespace Sylius\ShopApiPlugin\Handler\Customer;
+use InvalidArgumentException;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\ShopApiPlugin\Command\Customer\SendResetPasswordToken;
use Sylius\ShopApiPlugin\Exception\UserNotFoundException;
use Sylius\ShopApiPlugin\Mailer\Emails;
-use InvalidArgumentException;
final class SendResetPasswordTokenHandler
{
From 5ac484e6dd95eee4a2dc3530019dded7350e7491 Mon Sep 17 00:00:00 2001
From: Amr Ezzat <3mr3zzat@gmail.com>
Date: Thu, 30 Jan 2020 00:26:27 +0200
Subject: [PATCH 27/27] Fix tests
---
src/Handler/Customer/GenerateResetPasswordTokenHandler.php | 2 +-
src/Handler/Customer/SendResetPasswordTokenHandler.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
index 507371947..1f40afe01 100644
--- a/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/GenerateResetPasswordTokenHandler.php
@@ -28,7 +28,7 @@ public function __invoke(GenerateResetPasswordToken $generateResetPasswordToken)
{
$email = $generateResetPasswordToken->email();
- /** @var ShopUserInterface $user */
+ /** @var ShopUserInterface|null $user */
$user = $this->userRepository->findOneByEmail($email);
if (null === $user) {
throw UserNotFoundException::withEmail($email);
diff --git a/src/Handler/Customer/SendResetPasswordTokenHandler.php b/src/Handler/Customer/SendResetPasswordTokenHandler.php
index fad32be9d..c9b268ac2 100644
--- a/src/Handler/Customer/SendResetPasswordTokenHandler.php
+++ b/src/Handler/Customer/SendResetPasswordTokenHandler.php
@@ -30,7 +30,7 @@ public function __invoke(SendResetPasswordToken $resendResetPasswordToken): void
{
$email = $resendResetPasswordToken->email();
- /** @var ShopUserInterface $user */
+ /** @var ShopUserInterface|null $user */
$user = $this->userRepository->findOneByEmail($email);
if (null === $user) {
throw UserNotFoundException::withEmail($email);