
package cn.orionsec.ops.interceptor;

import cn.orionsec.kit.lang.constant.StandardContentType;
import cn.orionsec.kit.lang.define.wrapper.HttpWrapper;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.web.servlet.web.Servlets;
import cn.orionsec.ops.annotation.IgnoreAuth;
import cn.orionsec.ops.constant.Const;
import cn.orionsec.ops.constant.ResultCode;
import cn.orionsec.ops.constant.common.EnableType;
import cn.orionsec.ops.constant.system.SystemEnvAttr;
import cn.orionsec.ops.entity.dto.user.UserDTO;
import cn.orionsec.ops.service.api.PassportService;
import cn.orionsec.ops.utils.Currents;
import cn.orionsec.ops.utils.UserHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class AuthenticateInterceptor implements HandlerInterceptor {

    @Resource
    private PassportService passportService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 是否跳过
        final boolean ignore = ((HandlerMethod) handler).hasMethodAnnotation(IgnoreAuth.class);
        HttpWrapper<?> rejectWrapper = null;
        String loginToken = Currents.getLoginToken(request);
        if (!Strings.isEmpty(loginToken)) {
            String ip = null;
            // 如果开启用户 ip 绑定 则获取 ip
            if (EnableType.of(SystemEnvAttr.LOGIN_IP_BIND.getValue()).getValue()) {
                ip = Servlets.getRemoteAddr(request);
            }
            // 获取用户登录信息
            UserDTO user = passportService.getUserByToken(loginToken, ip);
            if (user != null) {
                if (Const.DISABLE.equals(user.getUserStatus())) {
                    rejectWrapper = HttpWrapper.of(ResultCode.USER_DISABLED);
                } else {
                    UserHolder.set(user);
                }
            } else {
                rejectWrapper = HttpWrapper.of(ResultCode.UNAUTHORIZED);
            }
        } else if (!ignore) {
            rejectWrapper = HttpWrapper.of(ResultCode.UNAUTHORIZED);
        }
        // 匿名接口直接返回
        if (ignore) {
            return true;
        }
        // 驳回接口设置返回
        if (rejectWrapper != null) {
            response.setContentType(StandardContentType.APPLICATION_JSON);
            Servlets.transfer(response, rejectWrapper.toJsonString().getBytes());
            return false;
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserHolder.remove();
    }

}
