Replace direct password_hash and password_verify calls with the injected PasswordHasher so the bcrypt cost can be substituted out in tests. Production wiring is handled by the container's autowiring of BcryptPasswordHasher. This commit alone breaks the test suite because the existing tests construct these use cases without the new dependency; the next commit restores green by introducing FakePasswordHasher.
48 lines
1.2 KiB
PHP
48 lines
1.2 KiB
PHP
<?php
|
|
|
|
namespace App\User\UseCases;
|
|
|
|
use App\Auth\PasswordHasher;
|
|
use App\Exceptions\BadRequestException;
|
|
use App\User\User;
|
|
use App\User\UserRepository;
|
|
use App\ValueObjects\EmailAddress;
|
|
|
|
class CreateUser
|
|
{
|
|
public function __construct(
|
|
private UserRepository $userRepo,
|
|
private PasswordHasher $passwordHasher,
|
|
) {}
|
|
|
|
/**
|
|
* @throws BadRequestException
|
|
*/
|
|
public function execute(CreateUserRequest $dto): User
|
|
{
|
|
if ($dto->email === null) {
|
|
throw new BadRequestException('email is required');
|
|
}
|
|
|
|
if ($dto->password === null) {
|
|
throw new BadRequestException('password is required');
|
|
}
|
|
|
|
if (strlen($dto->password) < 8) {
|
|
throw new BadRequestException(
|
|
'password must be at least 8 characters'
|
|
);
|
|
}
|
|
|
|
$email = new EmailAddress($dto->email);
|
|
if ($this->userRepo->findByEmail($email) !== null) {
|
|
throw new BadRequestException('email already taken');
|
|
}
|
|
|
|
return $this->userRepo->create(new CreateUserDto(
|
|
email: $email,
|
|
passwordHash: $this->passwordHasher->hash($dto->password),
|
|
isAdmin: $dto->isAdmin,
|
|
));
|
|
}
|
|
}
|