/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.spring.pathmatch.SaPatternsRequestConditionHolder;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.strategy.SaStrategy;
import com.yiring.auth.util.Auths;
import jakarta.annotation.PostConstruct;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 路由拦截器鉴权
 *
 * @author Jim
 * @version 0.1
 * 2022/1/28 20:35
 */

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {

    /**
     * 重写路由匹配算法，切换为 ant_path_matcher 模式，使之可以支持 `**` 之后再出现内容
     */
    @PostConstruct
    public void customRouteMatcher() {
        SaStrategy.instance.routeMatcher = SaPatternsRequestConditionHolder::match;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 路由拦截器
        // 可搭配使用注解实现鉴权: https://sa-token.dev33.cn/doc.html#/use/at-check
        registry
            .addInterceptor(
                new SaInterceptor(handle -> {
                    // 登录认证 -- 拦截所有路由，并排除 /auth/** 用于开放授权相关, 以及 swagger 相关
                    SaRouter
                        .match("/**")
                        .notMatchMethod(SaHttpMethod.OPTIONS.name())
                        // .notMatch("/**")
                        .notMatch("/example/**")
                        .notMatch("/auth/**")
                        .notMatch("/favicon.ico", "/**/*.html", "/**/*.js", "/**/*.css")
                        .notMatch("/v2/api-docs/**", "/v3/api-docs/**", "/swagger-resources/**")
                        .check(r -> StpUtil.checkLogin());

                    // 管理员权限才可访问的路由地址
                    SaRouter.match("/sys/**", r -> StpUtil.checkRoleOr(Auths.ADMIN_ROLES.toArray(new String[0])));
                })
            )
            .addPathPatterns("/**");
    }
}
