package com.sogou.qadev.service.login.client;
import java.io.IOException;
import java.util.HashSet;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.sogou.qadev.service.login.bean.DataAndEventId;
import com.sogou.qadev.service.login.bean.Key;
import com.sogou.qadev.service.login.client.authenticate.AuthenticateProxy;
import com.sogou.qadev.service.login.client.randomkey.RandomKeyProxy;
public class LoginFilter implements Filter
{
static public final int CAN_SKIP_INPUT = 1;
static public final int CAN_NOT_SKIP_INPUT = 2;
private int retryAccount = 5;
private long productId = -1;
private DataAndEventId[] dataAndEventId = null;
private String sendRedirectUrl = null;
private String sendErrorRedirectUrl = null;
private String magic = null;
private HashSet<String> magicUrlSet = new HashSet<String>();
private HashSet<String> noIEUrlSet = new HashSet<String>();
private RandomKeyProxy randomKeyProxy = new RandomKeyProxy();
private AuthenticateProxy authenticateProxy = new AuthenticateProxy();
public void destroy()
{
}
public void init(FilterConfig config) throws ServletException
{
magic = trimSafe(config.getInitParameter("magic"));
sendRedirectUrl = trimSafe(config.getInitParameter("sendRedirectUrl"));
sendErrorRedirectUrl = trimSafe(config.getInitParameter("sendErrorRedirectUrl"));
String pid = trimSafe(config.getInitParameter("productId"));
String retry = trimSafe(config.getInitParameter("retryAccount"));
String idString = trimSafe(config.getInitParameter("dataAndEventIds"));
String magicUrls = trimSafe(config.getInitParameter("magicUrls"));
String noIEUrls = trimSafe(config.getInitParameter("noIEUrls"));
if (valid(pid))
productId = Long.parseLong(pid);
if (valid(retry))
retryAccount = Integer.parseInt(retry);
if (valid(idString))
{
String[] pairString = idString.split(";");
dataAndEventId = new DataAndEventId[pairString.length];
for (int i = 0; i < pairString.length; i++)
{
String dataId = pairString[i].split(",")[0];
String eventId = pairString[i].split(",")[1];
dataAndEventId[i] = new DataAndEventId();
if (!"".equals(dataId.trim()))
dataAndEventId[i].setDataId(Long.parseLong(dataId));
if (!"".equals(eventId.trim()))
dataAndEventId[i].setEventId(Long.parseLong(eventId));
}
}
if (valid(magicUrls))
{
String[] urls = magicUrls.split(";");
for (String url : urls)
if (valid(url))
magicUrlSet.add(url);
}
System.err.println("magic url set is: " + magicUrlSet);
if (valid(noIEUrls))
{
String[] urls = noIEUrls.split(";");
for (String url : urls)
if (valid(url))
noIEUrlSet.add(url);
}
System.err.println("no ie url set is: " + noIEUrlSet);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain nextFilter) throws IOException, ServletException
{
long start = System.currentTimeMillis();
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpSession session = httpRequest.getSession();
HttpServletResponse httpResponse = (HttpServletResponse) response;
// ����Ƿ�Ҫ�����Ҫ�Ƕ�ʱ���ץȡ
String source = httpRequest.getServletPath();
if (source.indexOf("/") >= 0)
source = source.substring(source.lastIndexOf("/") + 1);
if (magicUrlSet.contains(source))
{
if (magic != null && magic.equals(request.getParameter("magic")))
{
nextFilter.doFilter(request, response);
return;
}
}
Key key = (Key) session.getAttribute("key");
long k = -1;
if (session.getAttribute("kid") != null)
k = (Long) session.getAttribute("kid");
if (k <= 0)
{
session.removeAttribute("kid");
k = -1;
}
if (k <= 0 || key == null)
{
String redirectUrl = null;
if (!valid(sendRedirectUrl))
redirectUrl = httpRequest.getRequestURL() + (httpRequest.getQueryString() == null ? "" : ("?" + httpRequest.getQueryString()));
else
redirectUrl = sendRedirectUrl;
String kid = null;
if (k <= 0)
{
kid = request.getParameter("k");
if (kid != null)
{
try
{
k = Long.parseLong(kid);
}
catch(Exception e)
{
}
}
if (k > 0)
session.setAttribute("kid", k);
}
else
{
kid = Long.toString(k);
}
if (k > 0 && key == null)
{
key = randomKeyProxy.getKey(k);
if (key != null)
{
session.setAttribute("key", key);
}
else
{
k = -1;
kid = null;
}
}
if (kid == null || key == null)
{
String url = randomKeyProxy.getKeyId(productId, dataAndEventId, redirectUrl, null, retryAccount, null);
kid = getKeyId(url);
k = Long.parseLong(kid);
session.setAttribute("kid", k);
if (noIEUrlSet.contains(source))
{
if (url.indexOf("/?") > 0)
//url = url.replaceAll("/\\?", "/index.noie.jsp\\?");
url = url.replaceAll("/\\?", "/index.jsp\\?");
else if (url.indexOf("/index.jsp?") > 0)
//url = url.replaceAll("/index.jsp\\?", "/index.noie.jsp\\?");
url = url.replaceAll("/index.jsp\\?", "/index.jsp\\?");
}
httpResponse.sendRedirect(url);
return;
}
}
// ���key�Ϸ���
String url = checkKey(key, httpResponse, session, k);
if (url != null)
{
httpResponse.sendRedirect(url);
return;
}
if (nextFilter != null)
nextFilter.doFilter(request, response);
System.out.println("login filter time: " + (System.currentTimeMillis() - start));
}
protected String checkKey(Key key, HttpServletResponse httpResponse, HttpSession session, long kid) throws IOException
{
if (key.getUsername() == null || key.getUserID() <= 0)
{
session.removeAttribute("key");
System.err.println("here is a key, but username/userid is invalid, username is: " + key.getUsername() + ", user id is: " + key.getUserID());
return getLoginUrl(key.getLoginUrlPrefix(), kid, CAN_SKIP_INPUT);
}
if (this.productId <= 0)
return null;
int[] result = authenticateProxy.authenticate0(kid, productId, dataAndEventId);
if (result == null)
return sendErrorRedirectUrl;
if (result.length == 0)
return null;
for (int r : result)
if (r <= 0)
return sendErrorRedirectUrl;
return null;
}
protected String trimSafe(String str)
{
if (str == null)
return null;
return str.trim();
}
protected boolean valid(String str)
{
return str != null && str.length() > 0;
}
protected String getKeyId(String url)
{
try
{
String[] kvs = url.split("\\?")[1].split("&");
for (String kv : kvs)
{
String[] s = kv.split("=");
if ("k".equals(s[0]))
return s[1];
}
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
return null;
}
protected String getLoginUrl(String loginUrlPrefix, long keyID, int e)
{
return loginUrlPrefix != null ? loginUrlPrefix + "e=" + e + "&k=" + keyID : "https://login.sogou-inc.com/?e=" + e + "&k=" + keyID;
}
}