/***********************************************************************************
 * @@ Program Name : HttpSSOLogin.java Description : SSO 로그인 처리 시스템 Author : 강원중 Create Date : 2004.10.13 History :
 * @@
 ***********************************************************************************/
package kr.co.kihyun.beans.user;

import java.io.IOException;
import java.io.PrintWriter;
//import java.text.SimpleDateFormat;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import kr.co.iniline.swift.sp.api.SPApiManager;
//import kr.co.iniline.swift.sp.api.SPApiManager;
//import kr.co.kihyun.beans.entity.Grade;

import kr.co.kihyun.beans.entity.MDept;
import kr.co.kihyun.beans.entity.MUser;
import kr.co.kihyun.beans.entity.util.MPersistenceManager;
import kr.co.kihyun.beans.entity.util.PMF;
import kr.co.kihyun.lang.MString;
import kr.co.kihyun.moumi.MoumiConfig;
import kr.co.kihyun.text.html.ServletUtil;

import org.jasypt.digest.StandardStringDigester;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@WebServlet("/servlet/kr.co.kihyun.beans.user.HttpSSOLogin")
public class HttpSSOLogin extends HttpServlet {
/**
*
*/
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory.getLogger(HttpSSOLogin.class);

	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		doPost(req, res);
	}

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		try {
			res.setContentType("text/html;charset=UTF-8");
			PrintWriter out = res.getWriter();

			// 세션 활성화
			HttpSession session = req.getSession(true);

			String connURL = "";
			String mode = MString.checkNull(req.getParameter("mode"));
			if (mode.equals("logout")) {
				out.println(kr.co.kihyun.text.html.ServletUtil.getJavaScript("parent.location.href=\"/logout.jsp\"; "));
			return;
			}
			String redirect = MString.checkNull(req.getParameter("redirect"));

			String id = (String) session.getAttribute("SSO_USER_ID");

            // 개발 로컬환경과 운영환경을 구분하게 위한 처리.
            if (false && !"localhost".equals(req.getServerName()) && !"127.0.0.1".equals(req.getServerName())) {
                SPApiManager spApi = new SPApiManager(req, res);
                String spApi_USER_ID = spApi.getUserID();
                id = spApi.getUserID();
            }

            int sysAuth = new User().getSysAuth(id);
			String ip = req.getRemoteAddr();

                        //21.크로스사이트 스크립트 에러(getParameter)_CWE-81 : Add by KWON,HAN
            String reqId = req.getParameter("id");
            if (!MString.isNull(reqId)) {
                reqId = reqId.replaceAll("<","&lt");
                reqId = reqId.replaceAll(">","&gt");
            }

			if (true || MString.isNull(id) && ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip) || "192.168.0.111".equals(ip))) {
                          //21. if (MString.isNull(req.getParameter("id"))) {
				if (MString.isNull(reqId)) {
                          //21. res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + req.getParameter("id") + "' "
					res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + reqId + "' "
							+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.notIdorPasswd"));
					return;
				}
                          //21. id = req.getParameter("id");
				id = reqId;
			}



            /*******************************************************************************************************
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            if(session.getAttribute("SSO_USER_ID") != null) {
                System.out.println(sdf.format(System.currentTimeMillis()) + " - [_SSO]UserID(WASSession)=[" + (String)session.getAttribute("SSO_USER_ID") + "], UserID(SSOCache)=["+ spApi.getUserID() +"]
             * , UserIP:" + req.getRemoteAddr() + ", JSESSIONID:" + session.getId());
                if(!spApi_USER_ID.equals((String)session.getAttribute("SSO_USER_ID"))) {
                    System.out.println("[USERID_MATCH_ERROR!!]" + sdf.format(System.currentTimeMillis()) + " - [_SSO]UserID(WASSession)=[" + (String)session.getAttribute("SSO_USER_ID") + "]
             * , UserID(SSOCache)=["+ spApi.getUserID() +"], UserIP:" + req.getRemoteAddr() + ", JSESSIONID:" + session.getId());
                }
            }else{
                System.out.println(sdf.format(System.currentTimeMillis()) + " - [_SSO]UserID(WASSession) is null, UserID(SSOCache)=["+ spApi.getUserID() +"], UserIP:" + req.getRemoteAddr() + "
             * , JSESSIONID:" + session.getId());
            }
            *******************************************************************************************************/




			LOG.debug("id: {}\nip: {}", id, ip);

			if (MoumiConfig.isSysAdmLoginConstraint()) {
				if (sysAuth == MoumiConfig.SYSADM && !MoumiConfig.getSysAdmIP().equals(ip)) {
                      //21. res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + req.getParameter("id") + "' "
					res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + reqId + "' "
							+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.notConnectAdmin"));
					return;
				}
			}

			if (mode.equals("logout")) {
                  	//21. res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + req.getParameter("id") + "' "
				res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + reqId + "' "
						+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.loginFailRetry"));
				return;
            }else{
				int succNum = 11;
				succNum = executeSSOLogin(id, ip, session);
				if (succNum <= 10) {
					session.setAttribute("APP_LOGIN", true);
					//session.setAttribute("LOCAL_LOGIN", false);
					connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				}
//
//				if (succNum == MoumiConfig.REPOPER) {
//                    connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				} else if (succNum == MoumiConfig.SUB_TOTPER) {
//                    connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				} else if (succNum == MoumiConfig.TOTPER) {
//                	connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				} else if (succNum == MoumiConfig.PART_REPOADM) {
//					connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				} else if (succNum == MoumiConfig.REPOADM) {
//					//connURL = "location='/totsys/repoadm/main.jsp';";
//					connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				} else if (succNum == MoumiConfig.TOTADM || succNum == MoumiConfig.SUB_TOTADM) {
//					connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
//				} else if (succNum == MoumiConfig.SYSADM || succNum == MoumiConfig.SUB_SYSADM) {
//                     connURL = "location='/totsys/login/frame.jsp?redirect=" + redirect + "';";
				} else if (succNum == 11) {
                                  //21. res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + req.getParameter("id") + "' "
					res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "ID: '" + reqId + "' "
							+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.notIdorPasswd"));
					return;
				} else if (succNum == 12) {
                                  //21. res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ID: '" + req.getParameter("id") + "' "
					res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ID: '" + reqId + "' "
							+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.retry"));
					return;
				} else if (succNum == 13) {
                                  //21. res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ID: '" + req.getParameter("id") + "' "
					res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ID: '" + reqId + "' "
							+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.deptChangeFailAdmin"));
					return;
				} else {
                                  //21. res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ID: '" + req.getParameter("id") + "' "
					res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ID: '" + reqId + "' "
							+ MoumiConfig.getMessageBundle().getString("moumi.message.popup.loginFailRetry"));
					return;
				}

				if (succNum > 10) {
					failLogin(session);
				}

				if (succNum <= 8 && succNum >= 0) {
					session.setMaxInactiveInterval(60 * 60 * 2); // 24시간
				}

                //v2. 9.크로스사이트 스크립트 (PrintWrier) : Update by KWON,HAN
//				out.println(ServletUtil.getJavaScript(connURL));

	                // 수정 : 외부 입력값 필터링 : '/totsys/login/frame.jsp?redirect=';
	                String filtered_connURL = connURL.replaceAll("<","").replaceAll(">","").replaceAll(",","");
	                //LOG.debug("v2 9.크로스사이트 스크립트 (PrintWrier) : HttpSSOLogin.doPost() filtered_connURL={}, Test OK", filtered_connURL);
	                out.println(ServletUtil.getJavaScript(filtered_connURL));
	                //========================================
			}
		} catch (Exception ex) {
			throw new RuntimeException(ex);
             	}
        }

	private void failLogin(HttpSession session) {
		session.setAttribute("APP_LOGIN", false);
		//session.setAttribute("LOCAL_LOGIN", false);
	}

	protected void executeLogout(HttpSession session) {
		session.invalidate();
	}

	/**************
	 * USER ************** return 0 => 보고자 계정 return 1 => 집계자 계정 return 5 => ID존재 PW일치하지 않음 return 6 => 존재하는 ID없음 return
	 * 7 => 시스템 에러
	 ************************************/
	private int executeSSOLogin(String id, String ip, HttpSession session) {

		LOG.debug("SSO Login for user {}", id);
		MUser mUser = null;
		String userId = "";
		String deptId = "";
		String userPassword = "";
		PersistenceManager pm = new MPersistenceManager(PMF.get().getPersistenceManager());
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();

            /*이부분이 multi check시 선택되어 받아온 아이디와 패스워드로 로그인하는 부분*/
			mUser = pm.detachCopy(pm.getObjectById(MUser.class, id));
			userId = mUser.getId();
			deptId = mUser.getUpperDept(pm).getId();
			userPassword = mUser.getPassword();
			LOG.debug("user password: {}", userPassword);
            /**/

			tx.rollback();

			return executeLogin(userId, userPassword, ip, session, deptId);
		} catch (Exception e) {
			LOG.error("User '{}' login failed: {}", id, e.getMessage());
			return 11;
		} finally {
			if (tx.isActive())
				tx.rollback();
			pm.close();
		}
	}

	int executeLogin(String id, String password, String ip, HttpSession session, String deptID) {
		int result = 11;
		MUser tmpUser = null;
		MDept userDept = null;
		PersistenceManager pm = new MPersistenceManager(PMF.get().getPersistenceManager());
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			tmpUser = pm.getObjectById(MUser.class, id);
			if (!((MoumiConfig.getUsePasswdEncrypt() && new StandardStringDigester().matches(password, tmpUser.getPassword())) || tmpUser
					.getPassword().equals(password))) {
				session.setAttribute("SSO_SIGN_MOUMI", "fail");
				LOG.debug("id: {} password: {}", id, password);

				return 11;
			}
			userDept = pm.getObjectById(MDept.class, deptID);
//			tmpUser.setUpperDept(userDept);
//			pm.makePersistent(tmpUser);

			LOG.debug("sessionID: {} for {}", session.getId(), tmpUser);
            LOG.debug("Dept ID: {}", deptID);
			session.setAttribute("userID", tmpUser.getId());
			session.setAttribute("userName", tmpUser.getName(pm));
			session.setAttribute("sysAuth", new Integer(tmpUser.getSysAuth().ordinal()));
			session.setAttribute("deptID", userDept.getId());
			session.setAttribute("deptName", userDept.getName());
            session.setAttribute("grade", userDept.getGrade());
//			session.setAttribute("organ", userDept.getOrgan(pm));
			// session.setAttribute("organName", userDept.getOrganization().getName());
			session.setAttribute("SSO_SIGN_MOUMI", "success"); // SSO연동을 위한 세션값에 체크
			result = tmpUser.getSysAuth().ordinal();

			LOG.info("{} logged in.", tmpUser);
//			tx.commit();
			tx.rollback();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			session.setAttribute("SSO_SIGN_MOUMI", "fail");

			return 12;
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
	}

	public static boolean isLogin(HttpServletRequest req) {
		return req.getSession(true).getAttribute("userID") != null;
	}

	/**
	 *
	 * use getMUser
	 *
	 * @deprecated
	 * @param req
	 * @return
	 */
	@Deprecated
	public static String getLoginID(HttpServletRequest req) {
		return (String) req.getSession(true).getAttribute("userID");
	}

	/**
	 *
	 * use getUser
	 *
	 * @deprecated
	 * @param req
	 * @return
	 */
	@Deprecated
	public static String getUserName(HttpServletRequest req) {
		return (String) req.getSession(true).getAttribute("userName");
	}

	public static MUser getUser(HttpServletRequest req) {
		PersistenceManager pm = new MPersistenceManager(PMF.get().getPersistenceManager());
		try {
			return pm.getObjectById(MUser.class, req.getSession(true).getAttribute("userID"));
		} finally {
			pm.close();
		}
	}

	/**
	 *
	 * use getUser
	 *
	 * @deprecated
	 * @param req
	 * @return
	 */
	@Deprecated
	public static String getDeptID(HttpServletRequest req) {
		return (String) req.getSession(true).getAttribute("deptID");
	}

	/**
	 *
	 * use getUser
	 *
	 * @deprecated
	 * @param req
	 * @return
	 */
	@Deprecated
	public static String getDeptName(HttpServletRequest req) {
		return (String) req.getSession(true).getAttribute("deptName");
	}

	/**
	 *
	 * use getOrganization
	 *
	 * @deprecated
	 * @param req
	 * @return
	 */
	@Deprecated
	public static String getOrganID(HttpServletRequest req) {
		return (String) req.getSession(true).getAttribute("organID");
	}

	/**
	 *
	 * use getMUser
	 *
	 * @deprecated
	 * @param req
	 * @return
	 */
	@Deprecated
	public static int getSysAuth(HttpServletRequest req) {
		String userID = "";
		try {
			userID = (String) req.getSession(true).getAttribute("userID");
			return (Integer) req.getSession(true).getAttribute("sysAuth");
		} catch (NullPointerException npe) {
			LOG.error("user@{} is disconnected.", userID);
			throw new NullPointerException("user: " + userID + " is disconnected.");
		}
	}
}
