package cn.reghao.autodop.dmaster.rbac.security;

import cn.reghao.jdkutil.security.Cryptor;
import cn.reghao.jdkutil.security.Md5Cryptor;
import cn.reghao.autodop.dmaster.rbac.model.po.User;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import java.security.NoSuchAlgorithmException;

/**
 * 认证用户名/密码登录的 provider
 *
 * @author reghao
 * @date 2019-04-09 09:07:40
 */
public class UsernamePasswordAuthProvider implements AuthenticationProvider {
    private final UserDetailsServiceImpl userDetailsService;
    private final Cryptor cryptor;

    public UsernamePasswordAuthProvider(UserDetailsServiceImpl userDetailsService)
            throws NoSuchAlgorithmException {
        this.userDetailsService = userDetailsService;
        this.cryptor = new Md5Cryptor();
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        // TODO 缓存中查找
        // 从数据库中获取用户认证信息
        User user = (User) userDetailsService.loadUserByUsername(username);
        String encryptedPwd = cryptor.encrypt(password + user.getSalt());
        if (!user.getPassword().equals(encryptedPwd)) {
            // TODO 禁用 DaoAuthenticationProvider，当前 provider 认证失败后即返回给前端
            throw new UsernamePasswordException("用户名/密码错误");
        }

        return new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
}
