package com.house365.web.interceptor;

import com.google.common.base.Strings;
import com.house365.rest.exception.ServiceException;
import com.house365.web.util.UrlSortUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * 对外核心业务URL参数拦截
 * <p/>
 * 核心业务抽奖模块加密处理逻辑
 *
 * @author jiangzhou
 * @version [版本号, 2015年10月25日]
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class UrlParamAuthInterceptor extends HandlerInterceptorAdapter {
    /**
     * 日志记录器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger("InterfaceLog");

    /**
     * 获取私钥key
     */
    private static final String PRIVATE_KEY = "00BE62C08DE8A6366D467D6555C268HH";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取接口所有请求参数 微信端请求需通过签名校验
        String url = request.getQueryString();
        if (request.getRequestURI().contains("/rest/interface")) {
            String serviceCode = request.getParameter("serviceCode") == null ? "" : request.getParameter("serviceCode");
            if ("wechat".equalsIgnoreCase(serviceCode) && !"127.0.0.1".equalsIgnoreCase(
                    request.getRemoteAddr()) && !"localhost".equalsIgnoreCase(request.getRemoteAddr())) {
                String sign = request.getParameter("sign");
                if (Strings.isNullOrEmpty(sign)) {
                    LOGGER.error("非法来源请求");
                    throw new ServiceException("非法来源请求");
                }
                // 兼顾两种编码方式的hash值
                String encryptUrlDecoded = encrypt(url, true);
                String encryptUrl = encrypt(url, false);
                if (sign.equals(encryptUrl) || sign.equals(encryptUrlDecoded)) {
                    return true;
                } else {
                    LOGGER.error("非法来源请求");
                    throw new ServiceException("非法来源请求");
                }
            }
        }
        return true;
    }

    /**
     * 功能描述: 接口参数排序加密算法<br>
     * 〈功能详细描述〉
     *
     * @param url
     * @return
     * @throws UnsupportedEncodingException
     * @author jiangzhou
     * @version [版本号, 2015年10月31日]
     * @since [产品/模块版本](可选)
     */
    public String encrypt(String url, boolean isUrlDecoded) throws UnsupportedEncodingException {
        if (isUrlDecoded) {
            url = URLDecoder.decode(url, "UTF-8");
        }
        // url参数排序
        String sortUrl = UrlSortUtils.sort(url);
        // 拼接秘钥
        sortUrl += "&key=" + PRIVATE_KEY;
        // MD5加密
        String encryptUrl = DigestUtils.md5Hex(sortUrl).toUpperCase();
        return encryptUrl;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        UrlParamAuthInterceptor ok = new UrlParamAuthInterceptor();
        //        String str = "serviceCode=Cm&serviceName=GetUploadUserPhotoCredits&userId=2447&userCityKey=nj&useridType=1&userPhoto=http://img12.house365.com/njbbsavatar/2014/12/16/2447_avatar_middle.jpg";
        String str = "api_key=iPhone&channl=app&city=nj&client=tf&inviteCode=509746&serviceCode=Cm&serviceName=RecordUserInvitation&userCityKey=nj&userId=1478287&useridType=1&v=6.1.7&version=6.1.7";
        String std = ok.encrypt(str, true);
        System.out.println(std);

    }
}
