class BcryptAuthenticator implements Authenticator<BasicCredentials, User> {

  @Override public Optional<User> authenticate(BasicCredentials credentials)
      throws AuthenticationException {
    User user = null;
    String username = credentials.getUsername();
    if (!User.isSanitizedUsername(username)) {
      logger.info("Username: {} must match pattern: {}", username, User.USERNAME_PATTERN);
      return Optional.empty();
    }

    // Get hashed password column from BCrypt table by username & verify hash against plaintext
    String password = credentials.getPassword();
    Optional<String> optionalHashedPwForUser = userDAO.getHashedPassword(username);
    if (checkPassword(password, optionalHashedPwForUser)) {
      user = User.named(username);
    }

    return Optional.ofNullable(user);
  }

  public  BcryptAuthenticator(UserDAO userDAO);

}