@Override
  @Transactional
  public UserPrincipal authenticate(Authentication authentication) {
    UsernamePasswordAuthenticationToken credentials =
        (UsernamePasswordAuthenticationToken) authentication;
    String username = credentials.getPrincipal().toString();
    String password = credentials.getCredentials().toString();
    credentials.eraseCredentials();

    UserPrincipal principal = this.userRepository.getByUsername(username);
    if (principal == null) {
      log.warn("Authentication failed for non-existent user {}.", username);
      return null;
    }

    if (!BCrypt.checkpw(password, new String(principal.getPassword(), StandardCharsets.UTF_8))) {
      log.warn("Authentication failed for user {}.", username);
      return null;
    }

    principal.setAuthenticated(true);
    log.debug("User {} successfully authenticated.", username);

    return principal;
  }
  @Override
  @Transactional
  public void saveUser(UserPrincipal principal, String newPassword) {
    if (newPassword != null && newPassword.length() > 0) {
      String salt = BCrypt.gensalt(HASHING_ROUNDS, RANDOM);
      principal.setPassword(BCrypt.hashpw(newPassword, salt).getBytes());
    }

    this.userRepository.save(principal);
  }