package com.wecloud.im.security.signature;

import lombok.extern.slf4j.Slf4j;

import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authc.AuthenticationException;

/**
 * 签名检验员
 * @Author luozh
 * @Date 2022年04月14日 17:31
 * @Version 1.0
 */
@Slf4j
public class SignatureChecker {

    /**
     * 时间戳请求最小限制(600s)
     * 设置的越小，安全系数越高，但是要注意一定的容错性
     */
    private static final long MAX_REQUEST = 10 * 60 * 1000L;

    /**
     * 签名校验
     * @Author luozh
     * @Date 2022年04月14日 05:32:32
     * @param request 请求信息
     * @param clientSignature 签名
     * @param appSecret app秘钥
     * @Return appKey
     */
    public static void check(HttpServletRequest request, String clientSignature, String appSecret) {
        // 获取请求头
        Map<String, String> headers = getHeaderMap(request);
        // resourcePath
        String resourcePath = request.getRequestURI();
        // request methos
        String requestMethod = request.getMethod();

        String canonicalString = SignUtils.buildCanonicalString(requestMethod, resourcePath, headers);
        log.info("服务端api签名字符串: {}", canonicalString);
        log.info("服务端api appSecret: {}", appSecret);
        String serverSignature = new HmacSHA256Signature().computeSignature(appSecret, canonicalString);
        log.info("服务端api签名结果: {}", serverSignature);


        if (!serverSignature.equals(clientSignature)) {
            // 返回给用户的response中告诉用户正确的用于验证加密的签名字符串
            throw new AuthenticationException("token 错误");
        }
    }

    public static Map<String, String> getHeaderMap(HttpServletRequest servletRequest) {
        Map<String, String> headerMap = new LinkedHashMap<>();
        Enumeration<String> names = servletRequest.getHeaderNames();
        while (names.hasMoreElements()) {
            String key = names.nextElement();
            headerMap.put(key, servletRequest.getHeader(key));
        }

        return headerMap;
    }

}
