package com.chinaweal.aiccs.config;

import com.chinaweal.youfool.framework.springboot.user.shiro.JWTRestfulFilter;
import com.chinaweal.youfool.framework.springboot.user.shiro.RestShiroFilterFactoryBean;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro配置
 * 这边只做配置，增加一个不做任何判断的拦截器ShiroFilter,鉴权改由SSOFilter处理。
 *
 * @author itluck
 */
@Configuration
public class ShiroConfig {

    @Value("${spring.profiles.active}")
    private String env;

    @Bean
    public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new RestShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);

        Map<String, Filter> filterMap = factoryBean.getFilters();
        //注：restful如: /xxx==GET = jwtRestful[org:dept:list]这里的 getUrl，getMethod 和 getPerms 分别对应 /xxx，GET 和 org:dept:list。
        filterMap.put("jwtRestful", new JWTRestfulFilter());
        filterMap.put("default", new ShiroFilter());
        factoryBean.setFilters(filterMap);

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 设置无权限时跳转的 url;
        filterChainDefinitionMap.put("/security/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/oauth2/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/toincludeabn/saveClue_SSJ", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/toincludeabn/registration", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/getCode", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/captcha", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/captchadl", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/login", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/loginByCode", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/loginByPwd", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/devops/login", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/test/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/info", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/checkSSOLogin", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/doc.html", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/druid/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/swagger-resources/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/v2/api-docs*", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/webjars/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/casLogin", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/casLogin_Unite", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/casLogin_LangChao", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/user/isHaveUser", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/abnormal/repair/api/**", DefaultFilter.anon.name());
        filterChainDefinitionMap.put("/ims/v1/**", DefaultFilter.anon.name());

        filterChainDefinitionMap.put("/**", DefaultFilter.anon.name());
//        if ("prod172".equals(env)) {
//            filterChainDefinitionMap.put("/**", "default");
//        } else {
//            filterChainDefinitionMap.put("/**", DefaultFilter.anon.name());
//        }
        factoryBean.setFilters(filterMap);
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return factoryBean;
    }
//        动态加载权限配置
//    @PostConstruct
//    public void loadShiro() throws Exception {
//    }

    /**
     * 注入 securityManager
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //securityManager.setRealm(userRealm);
        /*
         * 关闭shiro自带的session，详情见文档
         * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
         */
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }

    /**
     * 添加注解支持
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        // 强制使用cglib，防止重复代理和可能引起代理出错的问题
        // https://zhuanlan.zhihu.com/p/29161098
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
}
