package org.springblade.common.auth.security;

import java.io.IOException;
import java.util.Enumeration;
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 lombok.Setter;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;

public class XssParamSecurityFilter implements Filter {

    @Value("${spring.application.name}")
    @Setter
    private String appName;

    /**
     * 防XSS攻击Filter，对传递的参数进行HTML语法的转义
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (appName != null && appName.equalsIgnoreCase("gateway-service")) {
            chain.doFilter(request, response);
            return;
        }
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        if (request.getContentType() != null && !request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)
                && !httpRequest.getMethod().equalsIgnoreCase(HttpMethod.GET.name())) {
            chain.doFilter(request, response);
            return;
        }
        SecurityHttpRequestWrapper requestWrapper = new SecurityHttpRequestWrapper(httpRequest);

        //用于服务器内部传递参数
        Enumeration<String> paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = paramNames.nextElement();
            String paramValue = request.getParameter(paramName);
            String escapedValue = StringEscapeUtils.escapeHtml4(paramValue);
            request.setAttribute(paramName, escapedValue);
        }

        chain.doFilter(requestWrapper, httpResponse);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

}
