From 2ce9067710ece130d29fd5ec1c998b43eccb591d Mon Sep 17 00:00:00 2001 From: Jordi Date: Sun, 17 Mar 2024 14:15:50 +0100 Subject: [PATCH] feature: add a controller to create a user and make use cases encrypt, decrypt and validate a password --- configuration/routes.php | 2 +- .../Command/ChangePasswordCommand.php | 2 +- .../Application/Command/CreateUserCommand.php | 2 +- .../Controller/CreateAUserController.php | 33 +++++++++++++++++++ .../Application/Query/CheckPasswordQuery.php | 2 +- .../Query/CheckPasswordQueryHandler.php | 12 ++++--- tests/Acceptance/AcceptanceTestCase.php | 18 ++++++++-- .../ChangePasswordCommandHandlerTest.php | 2 +- .../Command/CreateUserCommandHandlerTest.php | 2 +- .../Controller/CreateAUserControllerTest.php | 26 +++++++++++++++ .../Query/CheckPasswordQueryHandlerTest.php | 5 ++- 11 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 src/User/Application/Controller/CreateAUserController.php create mode 100644 tests/User/Application/Controller/CreateAUserControllerTest.php diff --git a/configuration/routes.php b/configuration/routes.php index 31009c3..2a27a4b 100644 --- a/configuration/routes.php +++ b/configuration/routes.php @@ -6,7 +6,7 @@ global $app; // Add the routes here like in the following example: -//$app->post('/example', CreateExampleController::class); +$app->post('/user', \Source\User\Application\Controller\CreateAUserController::class); //$app->delete('/example/{ExampleId}', DeleteAnExampleController::class); //$app->put('/example/{exampleId}', UpdateAnExampleController::class); //$app->get('/example/criteria/the-criteria', FindAnExampleByCriteriaController::class); diff --git a/src/User/Application/Command/ChangePasswordCommand.php b/src/User/Application/Command/ChangePasswordCommand.php index 1db07e9..869548d 100644 --- a/src/User/Application/Command/ChangePasswordCommand.php +++ b/src/User/Application/Command/ChangePasswordCommand.php @@ -24,6 +24,6 @@ public function getEmail(): string public function getPassword(): string { - return $this->password; + return password_hash($this->password, PASSWORD_DEFAULT); } } diff --git a/src/User/Application/Command/CreateUserCommand.php b/src/User/Application/Command/CreateUserCommand.php index 2265393..a02ecdd 100644 --- a/src/User/Application/Command/CreateUserCommand.php +++ b/src/User/Application/Command/CreateUserCommand.php @@ -24,6 +24,6 @@ public function getEmail(): string public function getPassword(): string { - return $this->password; + return password_hash($this->password, PASSWORD_DEFAULT); } } diff --git a/src/User/Application/Controller/CreateAUserController.php b/src/User/Application/Controller/CreateAUserController.php new file mode 100644 index 0000000..e5c5159 --- /dev/null +++ b/src/User/Application/Controller/CreateAUserController.php @@ -0,0 +1,33 @@ +commandBus = $commandBus; + } + + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface + { + try { + $parameters = json_decode($request->getBody()->getContents(), true); + $command = new CreateUserCommand($parameters['email'], $parameters['password']); + $this->commandBus->handle($command); + return $response->withStatus(200); + } catch (Exception $e) { + return $response->withStatus($e->getCode(), $e->getMessage()); + } + } +} diff --git a/src/User/Application/Query/CheckPasswordQuery.php b/src/User/Application/Query/CheckPasswordQuery.php index c267063..ac747c8 100644 --- a/src/User/Application/Query/CheckPasswordQuery.php +++ b/src/User/Application/Query/CheckPasswordQuery.php @@ -24,6 +24,6 @@ public function getEmail(): string public function getPassword(): string { - return $this->password; + return password_hash($this->password, PASSWORD_DEFAULT); } } diff --git a/src/User/Application/Query/CheckPasswordQueryHandler.php b/src/User/Application/Query/CheckPasswordQueryHandler.php index c223a8c..dc3c84d 100644 --- a/src/User/Application/Query/CheckPasswordQueryHandler.php +++ b/src/User/Application/Query/CheckPasswordQueryHandler.php @@ -19,9 +19,13 @@ public function __construct(UserRepositoryInterface $repository) public function execute(CheckPasswordQuery $query): bool { - return $this->repository->exists( - new Email($query->getEmail()), - new Password($query->getPassword()) - ); + try { + $user = $this->repository->findByEmail( + new Email($query->getEmail()) + ); + return password_verify($user->getPassword()->toString(), $query->getPassword()); + } catch (\Exception $e) { + return false; + } } } diff --git a/tests/Acceptance/AcceptanceTestCase.php b/tests/Acceptance/AcceptanceTestCase.php index 8c4c4a7..1b40a29 100644 --- a/tests/Acceptance/AcceptanceTestCase.php +++ b/tests/Acceptance/AcceptanceTestCase.php @@ -10,10 +10,24 @@ class AcceptanceTestCase extends TestCase { + protected Client $client; + protected function setUp(): void { parent::setUp(); - MysqlClient::resetDatabase($_ENV('MYSQL_DB')); - $this->client = new Client(); + self::setupDatabase(); + MysqlClient::resetDatabase($_ENV['MYSQL_DB']); + $this->client = new Client([ + 'base_uri' => 'http://127.0.0.1' + ]); + } + + /** + * @return void + */ + public static function setupDatabase(): void + { + MysqlClient::connect($_ENV['MYSQL_HOST'], $_ENV['MYSQL_USER'], $_ENV['MYSQL_PASS'], (int)$_ENV['MYSQL_PORT']); + MysqlClient::selectDatabase($_ENV['MYSQL_DB']); } } \ No newline at end of file diff --git a/tests/User/Application/Command/ChangePasswordCommandHandlerTest.php b/tests/User/Application/Command/ChangePasswordCommandHandlerTest.php index fd96516..58a1b8d 100644 --- a/tests/User/Application/Command/ChangePasswordCommandHandlerTest.php +++ b/tests/User/Application/Command/ChangePasswordCommandHandlerTest.php @@ -38,6 +38,6 @@ public function testCanChangePassword(): void $command = new ChangePasswordCommand($this->user->getEmail()->toString(), $password); $this->commandHandler->execute($command); $actual = $this->userRepository->findById($this->user->getId()); - self::assertEquals($password, $actual->getPassword()->toString()); + self::assertTrue(password_verify($password, $actual->getPassword()->toString())); } } diff --git a/tests/User/Application/Command/CreateUserCommandHandlerTest.php b/tests/User/Application/Command/CreateUserCommandHandlerTest.php index 02bf503..a005f3e 100644 --- a/tests/User/Application/Command/CreateUserCommandHandlerTest.php +++ b/tests/User/Application/Command/CreateUserCommandHandlerTest.php @@ -30,6 +30,6 @@ public function testCanCreateAUser(): void $this->commandHandler->execute($command); $actual = $this->userRepository->findByEmail($user->getEmail()); self::assertEquals($user->getEmail(), $actual->getEmail()); - self::assertEquals($user->getPassword(), $actual->getPassword()); + self::assertTrue(password_verify($user->getPassword()->toString(), $actual->getPassword()->toString())); } } diff --git a/tests/User/Application/Controller/CreateAUserControllerTest.php b/tests/User/Application/Controller/CreateAUserControllerTest.php new file mode 100644 index 0000000..103827e --- /dev/null +++ b/tests/User/Application/Controller/CreateAUserControllerTest.php @@ -0,0 +1,26 @@ +client->post('/user', [ + 'form_params' => [ + 'email' => $email, + 'password' => '1234567', + ], + ]); + + self::assertEquals(200, $response->getStatusCode()); + } +} \ No newline at end of file diff --git a/tests/User/Application/Query/CheckPasswordQueryHandlerTest.php b/tests/User/Application/Query/CheckPasswordQueryHandlerTest.php index d11e72d..438a0ed 100644 --- a/tests/User/Application/Query/CheckPasswordQueryHandlerTest.php +++ b/tests/User/Application/Query/CheckPasswordQueryHandlerTest.php @@ -24,7 +24,10 @@ public function setUp(): void public function testCanCheckEmailAndPassword(): void { - $command = new CheckPasswordQuery($this->user->getEmail()->toString(), $this->user->getPassword()->toString()); + $command = new CheckPasswordQuery( + $this->user->getEmail()->toString(), + $this->user->getPassword()->toString() + ); $result = $this->commandHandler->execute($command); self::assertTrue($result); }