package cn.reghao.bnt.web.admin.security.form;

import cn.reghao.bnt.web.admin.model.dto.AccountLoginDto;
import cn.reghao.bnt.web.admin.service.AccountLoginService;
import cn.reghao.jutil.web.ServletUtil;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 账号密码登入 filter
 * 替换 UsernamePasswordAuthenticationFilter，用于认证用户，匹配指定 URL 才会进行处理
 *
 * @author reghao
 * @date 2022-07-06 15:55:59
 */
public class AccountAuthFilter extends AbstractAuthenticationProcessingFilter {
    private final AccountLoginService accountLoginService;

    public AccountAuthFilter(String authUrl, String httpMethod, AccountLoginService accountLoginService) {
        super(new AntPathRequestMatcher(authUrl, httpMethod));
        this.accountLoginService = accountLoginService;
    }

    /**
     * 构造 Authentication 对象
     * 参照 UsernamePasswordAuthenticationFilter
     *
     * @param
     * @return
     * @date 2020-05-06 上午11:16
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        // json payload 中的 username 和 password 参数
        AccountLoginDto accountLoginDto = (AccountLoginDto) ServletUtil.getBody(request, AccountLoginDto.class);
        AccountAuthToken preAuthToken = accountLoginService.getPreAuthentication(accountLoginDto);
        // 调用 AccountAuthProvider#authenticate 方法
        return this.getAuthenticationManager().authenticate(preAuthToken);
    }
}
