Bạn được giao xây dựng một module đăng ký tài khoản cho một hệ thống SaaS. Yêu cầu bao gồm:

1. Hash

  • User nhập mật khẩu plaintext.
  • Mật khẩu phải được băm (hash) bằng SHA-256 hoặc bcrypt trước khi lưu DB.

2. Encrypt

  • Email của user phải được mã hoá (encrypt) bằng một secret key, để DB không lưu email dạng rõ ràng.
  • Khi cần hiển thị email, phải decrypt.

3. Exception

Hệ thống phải ném Exception trong các trường hợp sau:

Tình huốngException
Username chứa ký tự đặc biệtInvalidUsernameException
Email không hợp lệInvalidEmailException
Mật khẩu ít hơn 6 ký tựWeakPasswordException

4. Dependency Injection

  • Class RegisterService không được tự tạo thư viện mã hoá / mã hoá / hash
  • Phải inject chúng thông qua constructor

5. IoC Container

  • Tạo một IoC Container tối giản để bind interface -> implementation:
    • HasherInterface -> Sha256Hasher
    • EncryptorInterface -> OpenSslEncryptor

Sau đó resolve RegisterService qua container.

6. Yêu cầu Code:

Bạn phải hiện thực các interface sau:

interface HasherInterface {
    public function hash(string $value): string;
}

interface EncryptorInterface {
    public function encrypt(string $value): string;
    public function decrypt(string $value): string;
}

RegisterService:

class RegisterService
{
    public function __construct(
        HasherInterface $hasher,
        EncryptorInterface $encryptor,
    ) {}

    public function register(string $username, string $email, string $password): array
    {
        // TODO: validate & throw exception
        // TODO: encrypt email
        // TODO: hash password
        // TODO: return mảng kết quả

        /*
        [
            'username' => 'Ym9i',
            'email' => 'ENCRYPTED_DATA',
            'password' => 'HASHED_DATA'
        ]
        */
    }
}

Bạn phải tự viết:

  • InvalidUsernameException
  • InvalidEmailException
  • WeakPasswordException

IoC Container tối giản:

class Container 
{
    protected array $bindings = [];

    public function bind(string $abstract, string $concrete) 
    {
        $this->bindings[$abstract] = $concrete;
    }

    public function make(string $abstract) 
    {
        $concrete = $this->bindings[$abstract] ?? $abstract;
        return new $concrete();
    }
}

Sau khi hoàn tất, chạy code sau phải hoạt động:

$container = new Container();

$container->bind(HasherInterface::class, Sha256Hasher::class);
$container->bind(EncryptorInterface::class, OpenSslEncryptor::class);

$service = new RegisterService(
    $container->make(HasherInterface::class),
    $container->make(EncryptorInterface::class),
);

$result = $service->register("Bob", "bob@gmail.com", "secret123");
print_r($result);

Rule:

  • Không được hardcode new object trong RegisterService
  • Exception phải được ném ngay khi phát hiện lỗi (throw early)
  • Encrypt email phải decrypt được
  • Output phải tuân theo cấu trúc yêu cầu

By admin