package com.xyw.console.auth;
import com.xyw.console.asset.entity.SystemUserEntity;
import com.xyw.console.asset.mapper.SystemUserMapper;
import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.util.Collections;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class AuthTokenFilter extends OncePerRequestFilter {
  private final AuthTokenService tokens; private final SystemUserMapper users; private final PagePermissionService permissions;
  /** 代码作用（白话）：接收令牌、用户表和权限服务；关联文件：SecurityConfig.java。关联逻辑（调用链/数据流）：Security Filter Chain -> 本过滤器 -> 用户表/权限。 */
  public AuthTokenFilter(AuthTokenService tokens, SystemUserMapper users, PagePermissionService permissions) { this.tokens=tokens; this.users=users; this.permissions=permissions; }
  /** 代码作用（白话）：跳过登录和 CSRF 令牌接口，避免公开的初始化请求被自身拦截；关联文件：AuthController.java。关联逻辑（调用链/数据流）：/api/auth/login 或 /api/auth/csrf -> Controller，不进入验签。 */
  @Override protected boolean shouldNotFilter(HttpServletRequest request) { return "/api/auth/login".equals(request.getRequestURI()) || "/api/auth/csrf".equals(request.getRequestURI()); }
  /** 代码作用（白话）：将有效 Cookie 转成 Spring Security 身份并二次核验账号状态和版本；关联文件：AuthTokenService.java、SystemUserEntity.java。关联逻辑（调用链/数据流）：请求 Cookie -> JWT -> 用户表 -> SecurityContext -> Controller。 */
  @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { try { String token=tokens.extract(request.getCookies()); if (token != null) { AuthPrincipal principal=tokens.parse(token); SystemUserEntity user=users.selectById(principal.userId()); if (user != null && "ACTIVE".equals(user.getStatus()) && user.getAuthVersion()!=null && user.getAuthVersion()==principal.authVersion()) { var authentication=new UsernamePasswordAuthenticationToken(principal, null, Collections.singleton(new SimpleGrantedAuthority("ROLE_"+principal.roleCode()))); authentication.setDetails(permissions.effectivePermissions(user)); SecurityContextHolder.getContext().setAuthentication(authentication); } } } catch (Exception ignored) { SecurityContextHolder.clearContext(); } chain.doFilter(request,response); }
}
