/**
   * Initiates the federation termination operation.
   *
   * @param request HTTP request
   * @param response HTTP response
   * @param ssoToken corresponding to the user's session
   * @return <code>true</code> if the termination initiation operation is successful; <code>false
   *     </code> otherwise.
   */
  public boolean handleFederationTermination(
      HttpServletRequest request, HttpServletResponse response, Object ssoToken) {
    FSUtils.debug.message("Entered FSFedTerminationHandler::handleFederationTermination");
    this.request = request;
    this.locale = FSServiceUtils.getLocale(request);
    this.response = response;
    this.ssoToken = ssoToken;
    setTerminationURL();
    if (managerInst == null) {
      FSUtils.debug.error("FSSPFedTerminationHandler " + "Account Manager instance is null");
      if (FSUtils.debug.messageEnabled()) {
        FSUtils.debug.message(
            "FSSPFedTerminationHandler::handleFederationTermination"
                + "failed to get Account Manager instance");
      }
      FSServiceUtils.returnLocallyAfterOperation(
          response,
          termination_done_url,
          false,
          IFSConstants.TERMINATION_SUCCESS,
          IFSConstants.TERMINATION_FAILURE);
      return false;
    }

    try {
      this.userID = SessionManager.getProvider().getPrincipalName(ssoToken);
    } catch (SessionException e) {
      FSUtils.debug.error("FSFedTerminationHandler::handleFederationTermination:", e);
      // cannot proceed without user
      LogUtil.error(Level.INFO, LogUtil.USER_NOT_FOUND, null, ssoToken);
      return false;
    }
    boolean bStatus = updateAccountInformation(null);
    FSUtils.debug.message("After updateAccountInformation");
    if (!bStatus) {
      if (FSUtils.debug.messageEnabled()) {
        FSUtils.debug.message(
            "FSSPFedTerminationHandler::handleFederationTermination "
                + "Federation Termination failed locally. Cannot update "
                + "account");
      }
      String[] data = {userID};
      LogUtil.error(Level.INFO, LogUtil.TERMINATION_FAILED, data, ssoToken);
      FSServiceUtils.returnLocallyAfterOperation(
          response,
          termination_done_url,
          false,
          IFSConstants.TERMINATION_SUCCESS,
          IFSConstants.TERMINATION_FAILURE);
      return false;
    }
    FSUtils.debug.message("Status of local update true");
    String[] data = {userID};
    LogUtil.access(Level.INFO, LogUtil.TERMINATION_SUCCESS, data, ssoToken);
    resetFederateCookie();
    boolean bRemoteStatus = doFederationTermination(request, response, acctInfo);
    return bRemoteStatus;
  }
 private Object getSession(HttpServletRequest request) {
   Object token = null;
   try {
     SessionProvider sessionProvider = SessionManager.getProvider();
     token = sessionProvider.getSession(request);
     if (token == null) {
       SAMLUtils.debug.error("SAMLPOSTProfileServlet.getSession: " + "Session is null.");
       return null;
     }
     if (!sessionProvider.isValid(token)) {
       SAMLUtils.debug.error("SAMLPOSTProfileServlet.getSession: " + "Session is invalid.");
       return null;
     }
   } catch (SessionException se) {
     SAMLUtils.debug.error(
         "SAMLPOSTProfileServlet.getSession: " + "Exception when getting Session:", se);
     return null;
   }
   return token;
 }
  /**
   * Initiates <code>SAML</code> web browser POST profile. This method takes in a TARGET in the
   * request, creates a SAMLResponse, then redirects user to the destination site.
   *
   * @param request <code>HttpServletRequest</code> instance
   * @param response <code>HttpServletResponse</code> instance
   * @throws ServletException if there is an error.
   * @throws IOException if there is an error.
   */
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    if ((request == null) || (response == null)) {
      String[] data = {SAMLUtils.bundle.getString("nullInputParameter")};
      LogUtils.error(java.util.logging.Level.INFO, LogUtils.NULL_PARAMETER, data);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "nullInputParameter",
          SAMLUtils.bundle.getString("nullInputParameter"));
      return;
    }

    SAMLUtils.checkHTTPContentLength(request);

    // get Session
    Object token = getSession(request);
    if (token == null) {
      response.sendRedirect(SAMLUtils.getLoginRedirectURL(request));
      return;
    }

    // obtain TARGET
    String target = request.getParameter(SAMLConstants.POST_TARGET_PARAM);
    if (target == null || target.length() == 0) {
      String[] data = {SAMLUtils.bundle.getString("missingTargetSite")};
      LogUtils.error(java.util.logging.Level.INFO, LogUtils.MISSING_TARGET, data, token);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_BAD_REQUEST,
          "missingTargetSite",
          SAMLUtils.bundle.getString("missingTargetSite"));
      return;
    }

    // Get the Destination site Entry
    // find the destSite POST URL, which is the Receipient
    SAMLServiceManager.SiteEntry destSite = getDestSite(target);
    String destSiteUrl = null;
    if ((destSite == null) || ((destSiteUrl = destSite.getPOSTUrl()) == null)) {
      String[] data = {SAMLUtils.bundle.getString("targetForbidden"), target};
      LogUtils.error(java.util.logging.Level.INFO, LogUtils.TARGET_FORBIDDEN, data, token);
      SAMLUtils.sendError(
          request,
          response,
          response.SC_BAD_REQUEST,
          "targetForbidden",
          SAMLUtils.bundle.getString("targetForbidden") + " " + target);
      return;
    }

    Response samlResponse = null;
    try {
      String version = destSite.getVersion();
      int majorVersion = SAMLConstants.PROTOCOL_MAJOR_VERSION;
      int minorVersion = SAMLConstants.PROTOCOL_MINOR_VERSION;
      if (version != null) {
        StringTokenizer st = new StringTokenizer(version, ".");
        if (st.countTokens() == 2) {
          majorVersion = Integer.parseInt(st.nextToken().trim());
          minorVersion = Integer.parseInt(st.nextToken().trim());
        }
      }
      // create assertion
      AssertionManager am = AssertionManager.getInstance();
      SessionProvider sessionProvider = SessionManager.getProvider();
      Assertion assertion =
          am.createSSOAssertion(
              sessionProvider.getSessionID(token),
              null,
              request,
              response,
              destSite.getSourceID(),
              target,
              majorVersion + "." + minorVersion);

      // create SAMLResponse
      StatusCode statusCode = new StatusCode(SAMLConstants.STATUS_CODE_SUCCESS);
      Status status = new Status(statusCode);
      List contents = new ArrayList();
      contents.add(assertion);
      samlResponse = new Response(null, status, destSiteUrl, contents);
      samlResponse.setMajorVersion(majorVersion);
      samlResponse.setMinorVersion(minorVersion);
    } catch (SessionException sse) {
      SAMLUtils.debug.error(
          "SAMLPOSTProfileServlet.doGet: Exception " + "Couldn't get SessionProvider:", sse);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "couldNotCreateResponse",
          sse.getMessage());
      return;
    } catch (NumberFormatException ne) {
      SAMLUtils.debug.error(
          "SAMLPOSTProfileServlet.doGet: Exception " + "when creating Response: ", ne);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "couldNotCreateResponse",
          ne.getMessage());
      return;
    } catch (SAMLException se) {
      SAMLUtils.debug.error(
          "SAMLPOSTProfileServlet.doGet: Exception " + "when creating Response: ", se);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "couldNotCreateResponse",
          se.getMessage());
      return;
    }

    // sign the samlResponse
    byte signedBytes[] = null;
    try {
      samlResponse.signXML();
      if (SAMLUtils.debug.messageEnabled()) {
        SAMLUtils.debug.message(
            "SAMLPOSTProfileServlet.doGet: "
                + "signed samlResponse is"
                + samlResponse.toString(true, true, true));
      }
      signedBytes = SAMLUtils.getResponseBytes(samlResponse);
    } catch (Exception e) {
      SAMLUtils.debug.error(
          "SAMLPOSTProfileServlet.doGet: Exception " + "when signing the response:", e);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "errorSigningResponse",
          SAMLUtils.bundle.getString("errorSigningResponse"));
      return;
    }

    // base64 encode the signed samlResponse
    String encodedResponse = null;
    try {
      encodedResponse = Base64.encode(signedBytes, true).trim();
    } catch (Exception e) {
      SAMLUtils.debug.error(
          "SAMLPOSTProfileServlet.doGet: Exception " + "when encoding the response:", e);
      SAMLUtils.sendError(
          request,
          response,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "errorEncodeResponse",
          SAMLUtils.bundle.getString("errorEncodeResponse"));
      return;
    }

    if (LogUtils.isAccessLoggable(java.util.logging.Level.FINE)) {
      String[] data = {
        SAMLUtils.bundle.getString("redirectTo"),
        target,
        destSiteUrl,
        new String(signedBytes, "UTF-8")
      };
      LogUtils.access(java.util.logging.Level.FINE, LogUtils.REDIRECT_TO_URL, data, token);
    } else {
      String[] data = {SAMLUtils.bundle.getString("redirectTo"), target, destSiteUrl};
      LogUtils.access(java.util.logging.Level.INFO, LogUtils.REDIRECT_TO_URL, data, token);
    }
    response.setContentType("text/html; charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("<HTML>");
    out.println("<BODY Onload=\"document.forms[0].submit()\">");
    out.println("<FORM METHOD=\"POST\" ACTION=\"" + destSiteUrl + "\">");
    out.println("<INPUT TYPE=\"HIDDEN\" NAME=\"" + SAMLConstants.POST_SAML_RESPONSE_PARAM + "\" ");
    out.println("VALUE=\"" + encodedResponse + "\">");
    out.println(
        "<INPUT TYPE=\"HIDDEN\" NAME=\""
            + SAMLConstants.POST_TARGET_PARAM
            + "\" VALUE=\""
            + target
            + "\"> </FORM>");
    out.println("</BODY></HTML>");
    out.close();
  }