package com.cpop.core.gateway.sys;

import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.CpopAuthenticationException;
import com.cpop.core.gateway.miniProgram.MiniProgramAuthenticationToken;
import com.cpop.core.service.CoreService;
import com.cpop.core.utils.PasswordEncoder;
import com.cpop.core.utils.SpringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Map;

/**
 * @author DB
 * @createTime 2023/10/19 9:36
 * @description
 */
public class SysAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 这个获取表单输入中返回的用户名;
        String principal = (String) authentication.getPrincipal();
        // 这个是表单中输入的密码与用户类型
        Map<String, Object> credentials = (Map<String, Object>) authentication.getCredentials();
        UserType userType = (UserType) credentials.get("userType");
        //认证用户名密码
        LoginUser loginUser = SpringUtils.getBean(CoreService.class).loadUserByUsername(principal, userType);
        //账号密码校验
        boolean password = SpringUtils.getBean(PasswordEncoder.class).matches((String) credentials.get("password"), loginUser.getUser().getPassword());
        if (!password){
            throw new BadCredentialsException("用户名密码错误!");
        }
        SysAuthenticationToken result = new SysAuthenticationToken(principal, loginUser);
        result.setDetails(loginUser);
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        //providerManager会遍历所有;securityConfig中注册的provider集合;根据此方法返回true或false来决定由哪个provider;去校验请求过来的authentication
        return (SysAuthenticationToken.class.isAssignableFrom(authentication));
    }
}
