package com.ho.user.config.shiro;


import com.alibaba.fastjson.JSON;
import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.DataResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @ClassName: CustomAccessControlFilter
 * @Author:
 * @CreateDate: 2019/9/6 23:22
 * @UpdateUser:
 * @UpdateDate: 2019/9/6 23:22
 * @Version: 0.0.1
 */
@Slf4j
public class CustomAccessControlFilter extends AccessControlFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        try {
            Subject subject = getSubject(servletRequest, servletResponse);
            log.info(request.getMethod());
            log.info(request.getRequestURL().toString());
            String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
            log.info("token:" +token);
            if (StringUtils.isEmpty(token)) {
                //这个地方抛异常不会被ControllerAdvise捕获,所以使用response
                //throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
                customRsponse(BaseResponseCode.TOKEN_ERROR.getCode(), BaseResponseCode.TOKEN_ERROR.getMsg(), servletResponse);
                return false;
            }
            CustomPasswordToken customPasswordToken = new CustomPasswordToken(token);
            getSubject(servletRequest, servletResponse).login(customPasswordToken);
        }
        //只捕获认证异常
        catch (AuthenticationException e){
            log.error("AuthenticationException !!" + e.getMessage());
            customRsponse(BaseResponseCode.TOKEN_PAST_DUE.getCode(), BaseResponseCode.TOKEN_PAST_DUE.getMsg(), servletResponse);
            return false;
        }
        return true;
    }

    private void customRsponse(int code, String msg, ServletResponse response) {
        try {
            DataResult result = DataResult.getResult(code, msg);

            response.setContentType("application/json; charset=utf-8");
            response.setCharacterEncoding("UTF-8");

            String userJson = JSON.toJSONString(result);
            OutputStream out = response.getOutputStream();
            out.write(userJson.getBytes("UTF-8"));
            out.flush();
        } catch (IOException e) {
            log.error("eror={}", e);
        }
    }

}
