package com.sogou.qadev.service.cynthia.util;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashSet;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
import bsh.Console;
import com.sogou.qadev.service.cynthia.bean.Key;
import com.sogou.qadev.service.cynthia.bean.UserInfo;
import com.sogou.qadev.service.cynthia.bean.UserInfo.UserRole;
import com.sogou.qadev.service.cynthia.bean.UserInfo.UserStat;
import com.sogou.qadev.service.cynthia.factory.DataAccessFactory;
import com.sogou.qadev.service.cynthia.service.ConfigManager;
import com.sogou.qadev.service.cynthia.service.CookieManager;
import com.sogou.qadev.service.cynthia.service.DataAccessSession;
import com.sogou.qadev.service.cynthia.service.ProjectInvolveManager;
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 int dataAndEventId = 1;
private String sendRedirectUrl = null;
private String magic = null;
private HashSet<String> magicUrlSet = new HashSet<String>();
private HashSet<String> noIEUrlSet = new HashSet<String>();
private DataAccessSession das = DataAccessFactory.getInstance()
.createDataAccessSession(ConfigUtil.sysEmail,
DataAccessFactory.magic);
public void destroy() {
}
public void init(FilterConfig config) throws ServletException {
magic = trimSafe(config.getInitParameter("magic"));
sendRedirectUrl = trimSafe(config.getInitParameter("sendRedirectUrl"));
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(retry))
retryAccount = Integer.parseInt(retry);
if (valid(idString)) {
String[] pairString = idString.split(";");
for (int i = 0; i < pairString.length; i++) {
if (idString != null)
dataAndEventId = Integer.parseInt(idString);
}
}
if (valid(magicUrls)) {
String[] urls = magicUrls.split(";");
for (String url : urls)
if (valid(url))
magicUrlSet.add(url);
}
if (valid(noIEUrls)) {
String[] urls = noIEUrls.split(";");
for (String url : urls)
if (valid(url))
noIEUrlSet.add(url);
}
}
public void doFilter(ServletRequest request, ServletResponse response,FilterChain nextFilter) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpSession session = httpRequest.getSession();
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestURI = httpRequest.getRequestURI();
// if (ConfigManager.deployUrl == null || (!ConfigManager.getProjectInvolved() && CookieManager.getCookieByName(httpRequest, "webRootDir") == null)) {
ConfigManager.deployPath = httpRequest.getContextPath();
ConfigManager.deployUrl = httpRequest.getHeader("Origin");
ConfigManager.deployScheme = httpRequest.getScheme();
if(CynthiaUtil.isNull(ConfigManager.deployUrl)){
ConfigManager.deployUrl = httpRequest.getHeader("Host");
}
ConfigManager.deployUrl = ConfigManager.deployUrl.replace("http://", "");
CookieManager.addCookie(httpResponse, "webRootDir", ConfigUtil.getCynthiaWebRoot(), 60 * 60 * 24 * 14 ,null);
// }
for (String magicUrl : magicUrlSet) {
if (requestURI.contains(magicUrl)) {
nextFilter.doFilter(request, response);
return;
}
}
Key key = (Key) session.getAttribute("key");
// //线上环境结束
String userName = (String) session.getAttribute("userName");
if (key != null) {
userName = key.getUsername();
} else if (key == null && userName != null) {
Key tempKey = new Key();
tempKey.setUsername(userName);
session.setAttribute("key", tempKey);
} else if (key == null && userName == null) {
if (ConfigManager.getEnableSso()) {
Cookie idCookie = CookieManager.getCookieByName(httpRequest,"id");
if (idCookie != null) {
String userId = trimSafe(idCookie.getValue()).split("\\.")[0];
UserInfo userInfo = ProjectInvolveManager.getInstance().getUserInfoById(userId);
if (userInfo != null) {
userName = trimSafe(userInfo.getUserName());
}
}
}else {
Cookie userNameCookie = CookieManager.getCookieByName(httpRequest,"login_username");
if (userNameCookie != null) {
userName = trimSafe(userNameCookie.getValue());
}
UserInfo userInfo = das.queryUserInfoByUserName(userName);
if (userInfo == null) {
userName = null;
}
}
if (userName == null) {
if(!CynthiaUtil.isNull(requestURI)){
requestURI = requestURI.substring(1);
}
String redirectUrl = null;
String targetUrl = null;
// *用户登录以后需手动添加session
if("XMLHttpRequest".equals(httpRequest.getHeader("X-Requested-With"))){
//ajax请求跳转到首页
targetUrl = ConfigUtil.getCynthiaWebRoot();
redirectUrl = ConfigUtil.getLoginUrl() + ( ConfigUtil.getLoginUrl().indexOf("?") != -1 ? "&" : "?" ) + "targetUrl=" + targetUrl + "&returnUrl=" + ConfigUtil.getCynthiaWebRoot() + "user/login.do";
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpResponse.addHeader("Vary", "Origin");
httpResponse.addHeader("Access-Control-Allow-Origin", httpRequest.getHeader("Origin"));
httpResponse.addHeader("Access-Control-Allow-Credentials", "true");
httpResponse.addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
httpResponse.addHeader("Access-Control-Allow-Headers", "host, user-agent, accept, content-type, x-real-ip, x-forwarded-ip, x-forwarded-for, x-xsrf-token, x-requested-with");
httpResponse.getWriter().println(redirectUrl);
} else {
targetUrl = ConfigUtil.getTargetUrl(httpRequest);
redirectUrl = ConfigUtil.getLoginUrl() + ( ConfigUtil.getLoginUrl().indexOf("?") != -1 ? "&" : "?" ) + "targetUrl=" + targetUrl + "&returnUrl=" + ConfigUtil.getCynthiaWebRoot() + "user/login.do";
httpResponse.sendRedirect(redirectUrl);
}
return;
}else {
Key tempKey = new Key();
tempKey.setUsername(userName);
session.setAttribute("userName", userName);
session.setAttribute("key", tempKey);
}
}
Long kid = (Long) session.getAttribute("kid");
if (kid == null) {
kid = ConfigUtil.magic;
session.setAttribute("kid", kid);
}
if (!authUserRole(dataAndEventId, userName) && httpRequest.getQueryString() != null && httpRequest.getQueryString().indexOf("previewFlow") == -1) {
httpResponse.sendRedirect(ConfigUtil.getCynthiaWebRoot() + "error.html");
return;
}
if (nextFilter != null)
nextFilter.doFilter(request, response);
}
protected boolean authUserRole(int eventId, String userName) {
if (userName == null)
return false;
if (eventId == 1)
return true;
//判断是否具有后台权限
UserInfo userInfo = das.queryUserInfoByUserName(userName);
if (userInfo == null) {
return false;
}else {
//状态正常 并且为管理员或超级管理员具有后台权限
return userInfo.getUserStat().equals(UserStat.normal) &&
(userInfo.getUserRole().equals(UserRole.admin) ||
userInfo.getUserRole().equals(UserRole.super_admin));
}
}
protected String trimSafe(String str) {
if (str == null)
return null;
return str.trim();
}
protected boolean valid(String str) {
return str != null && str.length() > 0;
}
public static String sign(String userId, HttpServletRequest request) throws Exception
{
String userdata = "";
String[] allHeaders = {"user-agent", "x-real-ip", "x-forwarded-for"};
for (String header : allHeaders) {
if (request.getHeader(header) != null) {
userdata += request.getHeader(header);
}
}
String sign = userId + "." + encode("lsh", (userId + userdata));
return sign;
}
/**
* @Title: encode
* @Description: sha-256加密
* @param key
* @param data
* @return
* @throws Exception
* @return: String
*/
public static String encode(String key, String data) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("utf-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
return Base64.encodeBase64String(sha256_HMAC.doFinal(data.getBytes("utf-8")));
}
}