package com.ningdatech.pmapi.user.security.auth.common;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ningdatech.pmapi.common.model.ZwddTokenUser;
import com.ningdatech.pmapi.common.util.JwtTokenUtil;
import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.Objects;

/**
 * @Author LiuXinXin
 * @Date 2020/8/3 8:55 下午
 * @Version 1.0
 **/
public class CommonAuthProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if (!(authentication instanceof CommonAuthToken)) {
            throw new RuntimeException("CustomAuthProvider 只支持 CustomAuthToken");
        }
        CommonAuthToken authenticationToken = (CommonAuthToken) authentication;
        // 平台 目前只有省局项管跳转
        String platform = (String) authenticationToken.getPrincipal();
        // 密钥
        String credential = (String) authenticationToken.getCredentials();

        ZwddTokenUser zwddTokenUser = JwtTokenUtil.parseJwt(credential);
        if (Objects.isNull(zwddTokenUser)) {
            throw new CommonLoginException("用户信息校验失败");
        }
        String employeeCode = zwddTokenUser.getEmployeeCode();
        if (StringUtils.isBlank(employeeCode)) {
            throw new CommonLoginException("当前用户尚未创建应用账号，请联系管理员创建账号");
        }
        UserDetails user = userDetailsService.loadUserByUsername(zwddTokenUser.getEmployeeCode());

        // 将用户定义的user放入token中，这样可以在session中查询到所有自定义的用户信息
        return new CommonAuthToken(user, user.getPassword(), user.getAuthorities());
    }

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

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

}
