/**
   * Processes submit of the restore password form.
   *
   * @param context Context.
   * @param restoreToken Restore token.
   * @param password Password.
   * @param confirmPassword Password confirmation.
   * @return Result.
   */
  @Transactional
  public Result restorePassword(
      Context context,
      @Param(value = "restoreToken") String restoreToken,
      @Param(value = "password") String password,
      @Param(value = "confirmPassword") String confirmPassword) {
    password = Strings.nullToEmpty(password);
    confirmPassword = Strings.nullToEmpty(confirmPassword);

    Result result = createResult(context, restoreToken);
    try {
      ExpirableToken token = expirableTokenEncryptor.decrypt(restoreToken);
      Long userId = token.getAttributeAsLong("userId");
      User user = userService.get(userId);
      if (user == null) {
        throw new ExpiredTokenException();
      }
      if (isValidPassword(password, confirmPassword)) {
        String ip = (String) context.getAttribute(IpAddressFilter.REMOTE_IP);
        byte[] oldSalt = user.getPasswordSalt();
        byte[] oldHash = user.getPasswordHash();
        userService.updatePasswordAndConfirm(user, password);
        userEventService.onUserPasswordUpdate(user, oldSalt, oldHash, ip, context.getHeaders());
        return Results.redirect(
            urlBuilderProvider.get().getSignInUrl(SignInState.PASSWORD_CHANGED));
      } else {
        result.render("restorePasswordError", "password");
      }
      result.render("user", user);
    } catch (ExpiredTokenException ex) {
      result.render("restorePasswordError", "expired");
    } catch (IllegalTokenException | IllegalFormatException ex) {
      result.render("restorePasswordError", "unknown");
    }
    return result;
  }
 /**
  * Renders restore password form.
  *
  * @param context Context.
  * @param restoreToken Restore token from email sent to user by {@link ForgotPasswordController}.
  * @return Result with data for restore password form.
  */
 @Transactional
 public Result restorePasswordGet(
     Context context, @Param(value = "restoreToken") String restoreToken) {
   Result result = createResult(context, restoreToken);
   try {
     ExpirableToken token = expirableTokenEncryptor.decrypt(restoreToken);
     Long userId = token.getAttributeAsLong("userId");
     User user = userService.get(userId);
     if (user == null) {
       throw new ExpiredTokenException();
     }
     result.render("user", user);
   } catch (ExpiredTokenException ex) {
     result.render("restorePasswordError", "expired");
   } catch (IllegalTokenException | IllegalFormatException ex) {
     result.render("restorePasswordError", "unknown");
   }
   return result;
 }