@Override
  public void authenticate(AuthenticationFlowContext context) {
    if (!isConfigured(context.getSession(), context.getRealm(), context.getUser())) {
      if (context.getExecution().isOptional()) {
        context.attempted();
      } else if (context.getExecution().isRequired()) {
        context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
        Response challengeResponse =
            errorResponse(
                Response.Status.UNAUTHORIZED.getStatusCode(),
                "invalid_grant",
                "Invalid user credentials");
        context.failure(AuthenticationFlowError.INVALID_USER, challengeResponse);
      }
      return;
    }
    String otp = retrieveOTP(context);
    if (otp == null) {
      if (context.getUser() != null) {
        context.getEvent().user(context.getUser());
      }
      context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
      Response challengeResponse =
          errorResponse(
              Response.Status.UNAUTHORIZED.getStatusCode(),
              "invalid_grant",
              "Invalid user credentials");
      context.failure(AuthenticationFlowError.INVALID_USER, challengeResponse);
      return;
    }
    boolean valid =
        context
            .getSession()
            .userCredentialManager()
            .isValid(
                context.getRealm(),
                context.getUser(),
                UserCredentialModel.otp(context.getRealm().getOTPPolicy().getType(), otp));
    if (!valid) {
      context.getEvent().user(context.getUser());
      context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
      Response challengeResponse =
          errorResponse(
              Response.Status.UNAUTHORIZED.getStatusCode(),
              "invalid_grant",
              "Invalid user credentials");
      context.failure(AuthenticationFlowError.INVALID_USER, challengeResponse);
      return;
    }

    context.success();
  }