package cn.myapps.base.web.filter;

import cn.myapps.authtime.common.service.AuthTimeServiceManager;
import cn.myapps.authtime.domain.model.DomainVO;
import cn.myapps.authtime.user.model.UserVO;
import cn.myapps.authtime.user.service.UserProcess;
import cn.myapps.base.web.WebUser;
import cn.myapps.common.Environment;
import cn.myapps.common.controller.Resource;
import cn.myapps.common.util.PropertyUtil;
import cn.myapps.common.util.Security;
import cn.myapps.common.util.SpringApplicationContextUtil;
import cn.myapps.common.util.StringUtil;
import cn.myapps.constans.Web;
import cn.myapps.designtime.common.cache.DesignTimeSerializableCache;
import cn.myapps.designtime.common.util.fs.VirtualFileSystemUtils;
import cn.myapps.runtime.mobile.security.service.SecurityServiceImpl;
import cn.myapps.runtime.security.Firewall;
import cn.myapps.runtime.security.PayloadXssRequestWrapper;
import cn.myapps.runtime.security.XssHttpServletRequestWrapper;
import cn.myapps.support.lanxin.service.LanxinOAuth2Handle;
import cn.myapps.support.weixin.WeixinServiceProxy;
import cn.myapps.util.http.CookieUtil;
import cn.myapps.util.uri.RequestIpUtil;
import com.bcxin.components.TenantContext;
import com.bcxin.saas.core.ContextConstant;
import com.bcxin.saas.core.InjectResolver;
import com.bcxin.saas.core.components.*;
import com.bcxin.saas.core.exceptions.SaasUnAuthorizeException;
import com.bcxin.saas.core.logs.OutputLogProvider;
import com.bcxin.saas.core.utils.ComponentUtils;
import com.bcxin.saas.logging.LoggerProviderImpl;
import jodd.net.HttpStatus;
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Collections;
import java.util.UUID;
import java.util.logging.SimpleFormatter;

/**
 * @author Nicholas
 */
public class SecurityFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(SecurityFilter.class);

    private Firewall firewall = null;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hreq = (HttpServletRequest) request;
        String uri = hreq.getRequestURI();
        if (ComponentUtils.isFilterIgnored(uri) || checkIfBearerOrAnUser(uri, hreq)) {
            chain.doFilter(request, response);
            return;
        }

        ThreadContext.put(ContextConstant.EXECUTE_ACTION, ContextConstant.OP_NULL);
        ThreadContext.put(ContextConstant.BUSINESS_ID, ContextConstant.OP_NULL);

        ThreadContext.put(ContextConstant.LOG_PERSISTENCE, "true");
        ThreadContext.put(ContextConstant.LOG_TRACE_ID, UUID.randomUUID().toString());
        ThreadContext.put(ContextConstant.REQ_SESSION_ID, hreq.getRequestedSessionId());
        ThreadContext.put(ContextConstant.REQ_URI, String.format("%s %s",hreq.getMethod(), uri));
        ThreadContext.put(ContextConstant.REQ_IPADDRESS, RequestIpUtil.getIp(hreq));
        if (!DesignTimeSerializableCache.readyForHandle()) {
            ThreadContext.put(ContextConstant.LOG_PERSISTENCE, "false");
            ((HttpServletResponse) response).setStatus(HttpStatus.HttpStatus405.error405().status());
            String json = SpringApplicationContextUtil.getBean(JsonProvider.class)
                    .getJson(Resource.error(405, "组件加载中", Collections.emptyList()));
            response.getWriter().write(json);
            return;
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        ThreadContext.put(ContextConstant.REQ_TRACK_TIME, dateFormat.format(Timestamp.from(Instant.now())));

        SecondCacheProvider secondCacheProvider = SpringApplicationContextUtil.getBean(SecondCacheProvider.class);
        try {
            secondCacheProvider.setData(VirtualFileSystemUtils.KEY_FileSystemManager, true);
            try {
                Cookie cookie = CookieUtil.getCookie(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG, hreq);
                if (cookie != null && "true".equalsIgnoreCase(cookie.getValue())) {
                    FeatureOptionChecker.enable(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG, true);
                } else {
                    FeatureOptionChecker.enable(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG, false);
                }

                if (hreq.getRequestURI().contains("/macro/log")) {
                    CookieUtil.setCookie(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG, "true", (HttpServletResponse) response);
                    FeatureOptionChecker.enable(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG, true);
                }
            } catch (Exception ex) {
                logger.error("启用Debug功能发生异常", ex);
            }

            HttpServletResponse resp = (HttpServletResponse) response;
            try {
                Environment evt = Environment.getInstance();
                String requestMethod = hreq.getMethod();
                if (requestMethod.equals("GET") || requestMethod.equals("POST") || requestMethod.equals("PUT") ||
                        requestMethod.equals("DELETE") || requestMethod.equals("PATCH")) {
                    if (StringUtil.isBlank(evt.getBaseUrl()) && !hreq.getRequestURI().contains("/actuator/health")) {
                        evt.setBaseUrl(hreq.getRequestURL().toString().replaceAll(hreq.getRequestURI(), ""));
                    }
                    String queryString = hreq.getQueryString();

                    if (isLoginURI(uri, hreq)) {
                        chain.doFilter(request, response);
                        return;
                    }

                    if (firewall == null) {
                        firewall = Firewall.getInstance();
                    }
                    try {
                        if (!firewall.excute(hreq, resp)) return;
                        if (firewall != null && firewall.isStartFirewall() && firewall.isStrongMode() && !firewall.isIgnoreUri(uri.toLowerCase())) {
                            request = new XssHttpServletRequestWrapper(hreq);
                            request = new PayloadXssRequestWrapper((HttpServletRequest) request);
                        }
                    } catch (Exception e) {
                        throw new ServletException(e.getMessage());
                    }

                    String mode = hreq.getParameter("mode");
                    String handleUrl = "";

                    if (mode != null && mode.equals("email")) {
                        handleUrl = hreq.getScheme() + "://" + hreq.getServerName() + ":" + hreq.getServerPort() + uri + "?" + queryString;
                        hreq.setAttribute("handleUrl", handleUrl);
                    }
                    String ldaperrorMsg = "";

                    if (isExcludeURI(uri, hreq)) {
                        if (uri.indexOf("/domain/login") < 0) {
                            chain.doFilter(request, response);
                        } else {
                            resp.sendRedirect(hreq.getContextPath() + "/domain/index.html#/login");
                        }
                        return;
                    } else if (isDomainAdminURI(hreq)) {
                        try {
                            WebUser admin = AuthTimeServiceManager.getAdminUser(hreq);
                            if (admin == null) {
                                responseUnauthorized(resp, hreq);
                            } else {
                                try {
                                    String token = Security.getToken(admin.getId());
                                    //如果过期时间减去当前时间小于12小时，刷新token
                                    Long longValue = Security.getAdminExpiresAtFromToken(hreq);
                                    if (longValue == null || longValue - System.currentTimeMillis() < Security.REFRESH_TIME) {
                                        Cookie cookie = new Cookie(Security.ADMIN_TOKEN, token);

                                        cookie.setPath("/");
                                        resp.addCookie(cookie);
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }

                                chain.doFilter(request, response);
                            }
                        } catch (Exception e) {
                            responseUnauthorized(resp, hreq);
                        }
                    } else {
                        /**
                         * 这个不能删除, 必须确保有执行这个, 不然有很多地方调用了WebUser.getWebUserInstance 缓存对象会报错.
                         * */

                        WebUser webUser = AuthTimeServiceManager.getWebUser(hreq);
                        if (webUser == null) {
                            if (isRequireWeixinAuth(hreq)) {//微信OAUTH2
                                try {
                                    WeixinServiceProxy.auth(hreq, resp, chain);

                                    if (isRequireWeixinAuth(hreq)) {
                                        String jumpTo = hreq.getParameter("jumpTo");
                                        resp.sendRedirect(jumpTo);
                                        return;
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }

                            if (isFromApp(hreq)) {
                                if (queryString != null && queryString.indexOf("jump") >= 0 && queryString.indexOf("userId") >= 0) {
                                    String userId = request.getParameter("userId");
                                    setWebUser(userId, hreq, resp);
                                    chain.doFilter(request, response);
                                    return;
                                } else {
                                    try {
                                        new SecurityServiceImpl().sso(hreq, resp, chain);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }

                        if (webUser != null) {
                            ThreadContext.put(ContextConstant.REQ_USER_ID, webUser.getId());
                            ThreadContext.put(ContextConstant.REQ_ORG_ID, webUser.getDomainid());

                            DataPermissionScopeConfig dataPermissionScopeConfig = SpringApplicationContextUtil.getBean(DataPermissionScopeConfig.class);
                            TenantContext tenantContext = TenantContext.getInstance();
                            TenantContext.EmployeeOrgBasicInfo userInfo = tenantContext.init(
                                    dataPermissionScopeConfig,
                                    SpringApplicationContextUtil.getBean(InjectResolver.class),
                                    webUser.getDomainid(), webUser.getId()
                            );

                            try {
                                Security.addAccessToken2ResponseCookie(request, response);

                                String token = Security.getToken(userInfo.getEmployeeId());
                                //如果过期时间减去当前时间小于12小时，刷新token
                                if (Security.getUserExpiresAtFromToken(hreq) - System.currentTimeMillis() < Security.REFRESH_TIME) {
                                    Cookie cookie = new Cookie(Security.ACCESS_TOKEN, token);
                                    cookie.setPath("/");
                                    cookie.setMaxAge(7200);
                                    resp.addCookie(cookie);
                                }

                                if (isRequireWeixinAuth(hreq)) {
                                    String jumpTo = hreq.getParameter("jumpTo");
                                    resp.sendRedirect(jumpTo);
                                    return;
                                }
                            } catch (Exception e) {
                                logger.error("设置AccessToken过期问题:{}", uri, e);
                            }
                        }

                        if (uri.matches("^.*" + ((HttpServletRequest) request).getContextPath() + "/") ||
                                uri.matches("^.*/portal/good/index.html")) {
                            try {
                                String userid = Security.getUserIdFromToken(hreq);
                                if (userid == null) {
                                    userid = Security.getDebugUserIdFromToken(hreq);
                                }
                                if (userid != null) {
                                    chain.doFilter(request, response);
                                    return;
                                } else {
                                    //判断是否用war包启动
                                    String warContextPath = getWarContextPath(hreq);
                                    if (warContextPath.equals("")) {
                                        //不是
                                        resp.sendRedirect("./login/login.html");
                                        return;
                                    } else {
                                        //是
                                        resp.sendRedirect("/signon/login.html?url=" + hreq.getRequestURI());
                                        return;
                                    }
                                }
                            } catch (Exception e) {
                                resp.sendRedirect("/signon/login.html?url=" + hreq.getRequestURI());
                                return;
                            }
                        }

                        if (isForegroundURI(uri)) { // 是否为前台
                            Security.addAccessToken2ResponseCookie(request, response);
                            // 检查URI权限
                            if (webUser != null) {
                                if (mode != null && mode.equals("email")) {
                                    hreq.getRequestDispatcher("/portal/share/security/handle.jsp").forward(request, response);
                                } else if (uri.indexOf("portal/phone/main.jsp") > -1 && !StringUtil.isBlank(request.getParameter("jumpToUrl"))) {
                                    String jumpToUrl = request.getParameter("jumpToUrl");
                                    String applicationId = request.getParameter("application");
                                    String formId = jumpToUrl.substring(jumpToUrl.indexOf("_formid") + 8, jumpToUrl.indexOf("&"));
                                    jumpToUrl = request.getParameter("jumpToUrl").substring(request.getParameter("jumpToUrl").indexOf("&") + 1);
                                    String accessToken = request.getParameter(Security.ACCESS_TOKEN);
                                    if (accessToken == null) {
                                        accessToken = request.getParameter("access_token");
                                    }
                                    Cookie cookie = new Cookie(Security.ACCESS_TOKEN, accessToken);
                                    cookie.setPath("/");
                                    resp.addCookie(cookie);
                                    String docId = jumpToUrl.substring(jumpToUrl.indexOf("_docid") + 7, jumpToUrl.indexOf("&"));

                                    resp.sendRedirect(hreq.getContextPath() + "/mobile/index.html?application=" + applicationId + "&linkType=00&actionContent=" + formId + "&docId=" + docId + "#/open?linkType=00&actionContent=" + formId + "&docId=" + docId);
                                } else {
                                    try {
                                        chain.doFilter(request, response);
                                        return;
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }

                            } else { // 用户不存在
                                /**
                                 * 如果是单点登录,则直接跳转到登陆页面, 避免用户配置的跳转页面有误导致timeOut.jsp页面无限循环
                                 */
                                if (Web.AUTHENTICATION_TYPE_SSO.equals(PropertyUtil
                                        .get(Web.AUTHENTICATION_TYPE))) {
                                    String msg = hreq.getHeader("Authorization");
                                    /**
                                     * 如果Authorization的信息不为null或者不是AD单点登录,则重定向
                                     */
                                    if (!"cn.myapps.security.sso.ADUserSSO".equals(PropertyUtil.get(Web.SSO_IMPLEMENTATION))
                                            || msg != null) {
                                        if (!StringUtil.isBlank(ldaperrorMsg)) {
                                            request.setAttribute("errorMsg", ldaperrorMsg);
                                        }
                                        if ("cn.myapps.security.sso.CookieUserSSO".equals(PropertyUtil
                                                .get(Web.SSO_IMPLEMENTATION))) {
                                            hreq.getRequestDispatcher("/portal/share/security/login.jsp").forward(request, response);
                                        }
                                    }
                                } else if (mode != null && mode.equals("email")) {
                                    hreq.getRequestDispatcher("/portal/share/security/login.jsp").forward(request, response);
                                } else if (isRequireWeixinAuth(hreq)) {//微信OAUTH2
                                    try {
                                        WeixinServiceProxy.auth(hreq, resp, chain);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                } else if (isRequireLanxinAuth(hreq)) {
                                    try {
                                        LanxinOAuth2Handle.auth(hreq, resp, chain);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                } else if (isFromApp(hreq)) {
                                    if (queryString != null && queryString.indexOf("jump") >= 0) {
                                        String access_token = request.getParameter("access_token");
                                        Cookie cookie = new Cookie(Security.ACCESS_TOKEN, access_token);
                                        cookie.setPath("/");
                                        resp.addCookie(cookie);
                                    } else {
                                        try {
                                            new SecurityServiceImpl().sso(hreq, resp, chain);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                } else {
                                    //判断客户端
                                    if (CheckAgent(hreq.getHeader("User-Agent")) && StringUtils.hasLength(hreq.getHeader("Referer"))) {
                                        resp.sendRedirect("/static/signon/index.html?url=" + ((HttpServletRequest) request).getContextPath());
                                    } else {
                                        resp.setStatus(401);
                                    }
                                }
                            }
                        } else {
                            resp.sendRedirect("/static/signon/index.html?url=" + hreq.getContextPath());
                        }
                    }
                }
            } finally {
                ThreadContext.put(ContextConstant.REQ_RESPONSE_STATUS, String.valueOf(resp.getStatus()));
                VirtualFileSystemUtils.tryClose();
                OutputLogProvider.flush();


            }
        } finally {


            try {
                SpringApplicationContextUtil.getBean(ThreadContextManager.class).clear();
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            try {
                secondCacheProvider.clear();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * 是否需要蓝信认证
     *
     * @param request
     * @return
     */
    private boolean isRequireLanxinAuth(HttpServletRequest request) {
        //从蓝信客户端中访问，则不需要CAS验证
        String userAgent = request.getHeader("user-agent");
        String queryString = request.getQueryString();
        if (userAgent.contains("Lanxin") && queryString != null && queryString.indexOf("code") >= 0 && queryString.indexOf("state") >= 0) {
            return true;
        }

        return false;
    }

    /**
     * 是否需要微信认证
     *
     * @param request
     * @return
     */
    private boolean isRequireWeixinAuth(HttpServletRequest request) {
        //从微信客户端中访问，则不需要CAS验证
        String userAgent = "MicroMessenger";
        String queryString = request.getQueryString();
        String uri = request.getRequestURI();
        if (userAgent.contains("MicroMessenger") && uri.indexOf("/sso") >= 0 && queryString != null && queryString.indexOf("code") >= 0 && queryString.indexOf("state") >= 0) {
            return true;
        }
        return false;
    }

    /**
     * 是否需要App单点登录
     *
     * @param request
     * @return
     */
    private boolean isFromApp(HttpServletRequest request) {
        String queryString = request.getQueryString();
        if (queryString != null && queryString.indexOf("mode") >= 0 && queryString.indexOf("access_token") >= 0) {
            return true;
        }

        return false;
    }

    /**
     * 是否不作检验的URI
     *
     * @param uri
     * @return 是返回true, 否则返回false
     */
    private boolean isExcludeURI(String uri, HttpServletRequest request) {
        String accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCIsImV4cCI6Nzk5OTkyMDAwMCwidXNlcm5hbWUiOiJDcHFxNUc2akhUZlZTUmV5eGdXIn0.OmjyOeRc5er7cUrfGoehcMZAb-O-g79B495Xx6e_OPI";
        if (accessToken.equals(request.getHeader("accessToken"))) {
            return true;
        } else if (
                (uri.indexOf("mobile") >= 0 && uri.indexOf("mobile/index.html") > 0) || uri.indexOf("help") >= 0
                || uri.matches("^.*actuator/health$")//健康检查
                //|| uri.matches("^.*authtime/login$")
                || uri.matches("^.*.jpg$|^.*.gif$|^.*.png$|^.*.js$|^.*.css$|^.*.map$|^.*.html$|^.*.woff$")
                || uri.startsWith(request.getContextPath() + "/extend/")
                || uri.startsWith(request.getContextPath() + "/common/")
                || uri.startsWith(request.getContextPath() + "/tray/service/")
                || uri.indexOf("/uploads/") >= 0
                || uri.indexOf("/servlet/AdminServlet") >= 0
                || uri.indexOf("/dingding.html") >= 0
                || uri.indexOf("loginInDialog.action") >= 0
                || uri.equals("/")
                || uri.indexOf("/admin") >= 0
                || uri.indexOf("/checkCodeImg") >= 0
                || uri.indexOf("woff") >= 0
                //|| uri.indexOf("logout") >= 0
                || uri.indexOf("/dingding/") >= 0
                || uri.indexOf("/changelanguage") >= 0
                || uri.indexOf("desktop") >= 0
                || uri.indexOf("/core/macro/debuger/") >= 0
                || uri.indexOf("smsauth.action") >= 0
                //|| uri.indexOf("/saas/register") >= 0
                || uri.indexOf("saas/multilanguage/change") >= 0
                || uri.indexOf("saas/changeLanguageKm") >= 0
                || uri.indexOf("/weioa365/services") >= 0
                //|| uri.indexOf("/portal/document/qrcodefield/ready") >= 0
                //|| uri.indexOf("/portal/dynaform/document/fileDownload") >= 0	//微信端文件下载超时
                || uri.indexOf("/weixin/") >= 0
                || uri.indexOf("/lanxin/") >= 0
                || uri.indexOf("/portal/component/user/") >= 0
                || uri.indexOf("/rest/") >= 0
                || uri.indexOf("/monitors/workflows/") >= 0
                || uri.indexOf("/runtime/app/") >= 0
                || uri.indexOf("/macro") >= 0
                || uri.indexOf("/actuator") >= 0
                || uri.indexOf("/showjrxml/") >= 0
                || uri.indexOf("/getCustomColumnsInfos") >= 0
                || uri.indexOf("/tray/service") >= 0
                || uri.indexOf("/office/service") >= 0
                || uri.indexOf("/domain/index.html") >= 0
                //|| uri.indexOf("/config/clearcache") >= 0
                || uri.indexOf("/iwebpdf") >= 0
                || uri.indexOf("/bcxin/") >= 0
                || uri.indexOf("/runtime/database/sync") >= 0
                || uri.indexOf("/getAccessToken") >= 0
                || uri.indexOf("/runtime/sync/") >= 0
                || uri.indexOf("/notifyOverDue") >= 0
                || uri.indexOf("/accessToken") >= 0) {
            return true;
        }
        return false;

    }


	/**
	 * 是否前台URI
	 * 
	 * @param uri
	 * @return 是返回true,否则返回false
	 */
	private boolean isForegroundURI(String uri) {
		// 检查以"/portal"或"/mobile"开始的URI(*.action、*.jsp、*.html);
		return uri.indexOf("/portal/") >= 0 || uri.indexOf("/mobile/") >= 0 || uri.indexOf("/pm/")>= 0 ||
				uri.indexOf("/km/")>= 0 || uri.indexOf("/kms/")>= 0 || uri.indexOf("/kmswap/")>= 0 || uri.indexOf("/rm/") >= 0
				|| uri.indexOf("/message/")>=0
				|| uri.indexOf("/attendance/")>=0
				|| uri.indexOf("/dispatcher.html") >= 0
				|| uri.indexOf("/index.html")>=0
				|| uri.indexOf("/saas/weioa/")>=0
				|| uri.indexOf("/contacts/")>=0 || uri.indexOf("/qm/") >=0
				|| uri.indexOf("/jasperreport/") >= 0
				|| uri.indexOf("/magic-api/") >= 0
				|| uri.indexOf("/api/v2/runtime/") >= 0
				|| uri.indexOf("/bcxin/") >= 0 || uri.indexOf("/v2/sync") >= 0|| uri.indexOf("/v3/extends") >= 0
				|| (uri.indexOf("/api/runtime/")>=0|| (uri.indexOf("/api/runtime-ex/")>=0) && uri.indexOf("/workflow/storage/runtime/intervention")<0);
	}


	/**
	 * 是否loginURI
	 *
	 * @param uri
	 * @return 是返回true,否则返回false
	 */
	private boolean isLoginURI(String uri,HttpServletRequest request) {
		String login = request.getContextPath()+"/api/runtime/login.*";
		String loginhtml = request.getContextPath()+"/login.*";
		String debuglogin = request.getContextPath()+"/api/debuglogin.*";
        String health = request.getContextPath()+"/actuator/health";
        if(uri.matches("^" + debuglogin) ||uri.matches("^" + request.getContextPath() + "/login/debuglogin.html") ){
            WebUser admin = AuthTimeServiceManager.getAdminUser(request);
            if (admin == null) {
                return false;
            } else {
                return true;
            }
        } else if (uri.matches("^" + login) || uri.matches("^" + loginhtml) || uri.matches("^" + health)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断是否为域管理后台
     */
    private boolean isDomainAdminURI(HttpServletRequest request) {
        String match = request.getContextPath() + "/api/authtime/.*";
        String uri = request.getRequestURI();
        return uri.matches("^" + match) ||
                uri.indexOf("/systemMonitor") >= 0 ||
                uri.indexOf("/system/monitor/time") >= 0 ||
                uri.indexOf("/servlet/AdminServlet") >= 0 ||
                uri.indexOf("/core/monitor") >= 0 || uri.indexOf("swagger") >= 0 ||
                uri.indexOf("api-docs") >= 0 ||
                uri.indexOf("/synchronization") >= 0;
    }

    @Override
    public void destroy() {
        //LOG.debug("##################### SecurityFilter destroy! #####################");
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

    public static boolean CheckAgent(String agent) {
        boolean flag = false;

        String[] keywords = {"Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser"};

        for (String key : keywords) {
            if (agent.contains(key)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    private void responseUnauthorized(HttpServletResponse response, HttpServletRequest request) {
        response.setStatus(401);
        return;
    }

    public String getWarContextPath(HttpServletRequest request) {
        String path = PropertyUtil.getPath();
        String realPath = request.getRealPath("/");

        File designerFile = new File(realPath);
        File webappFile = designerFile.getParentFile();
        File[] oneFiles = webappFile.listFiles();
        String context = "";
        outterLoop:
        for (File oneFile : oneFiles) {
            //判断里面的一级目录
            File[] twoFiles = oneFile.listFiles();
            if (oneFile.isDirectory()) {
                for (File twoFile : twoFiles) {
                    String fileName = twoFile.getName();
                    if (fileName.equals("portal")) {
                        context = oneFile.getName();
                        break outterLoop;
                    }
                }
            }
        }
        return context;
    }

    private void setWebUser(String userId, HttpServletRequest request, HttpServletResponse response) {
        try {
            UserProcess userProcess = AuthTimeServiceManager.userRuntimeService();
            UserVO user = (UserVO) userProcess.doView(userId);
            if (user != null) {
                Security.addAccessToken2ResponseCookie(request, response);
                HttpSession session = request.getSession();
                WebUser webUser = new WebUser(user);
                DomainVO domain = user.getDomain();
                webUser.setRecordLog(domain.getLog().booleanValue());
                webUser.setServerAddr(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/");
                webUser.setEquipment(WebUser.EQUIPMENT_PHONE);
                session.setAttribute("SKINTYPE", "phone");
                session.setAttribute("visit_from_app", "true");

                String token = Security.getToken(userId);
                webUser.setACCESS_TOKEN(request, token);
                WebUser.setWebUser(webUser, request);
                Cookie cookie = new Cookie(Security.ACCESS_TOKEN, token);
                cookie.setPath("/");
                response.addCookie(cookie);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private boolean checkIfBearerOrAnUser(String uri,HttpServletRequest request) {
        boolean isBearerUser = uri.contains("/magic-api/bearer-users");

        if (isBearerUser) {
            String bearerUserId = Security.extractBearerUserId(request);
            if (StringUtil.isBlank(bearerUserId)) {
                throw new SaasUnAuthorizeException(String.format("%s API 对于的Bearer Token不能为空", uri));
            }

            return true;
        }

        if(uri.contains("/magic-api/callback")) {
            return true;
        }

        boolean isAnonymousUser = uri.contains("/magic-api/anonymous-users");

        return isAnonymousUser;
    }


}
