package com.zhangmeng.oauth.config;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.zhangmeng.model.entity.Permission;
import com.zhangmeng.oauth.dto.UserJwt;
import com.zhangmeng.oauth.feign.AdminFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 自定义授权认证类
 *
 * @author 转身的背影在心底里沉沦
 * @date 2021年9月14日11:54:013
 * @version 1.0
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    ClientDetailsService clientDetailsService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    private AdminFeign adminFeign;

    /****
     * 自定义授权认证
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //取出身份，如果身份为空说明没有认证
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //没有认证统一采用httpbasic认证，httpbasic中存储了client_id和client_secret，开始认证client_id和client_secret
        if(authentication==null){
            ClientDetails clientDetails = clientDetailsService.loadClientByClientId(username);
            if(clientDetails!=null){
                //秘钥
                String clientSecret = clientDetails.getClientSecret();
                //静态方式
                //return new User(username,new BCryptPasswordEncoder().encode(clientSecret), AuthorityUtils.commaSeparatedStringToAuthorityList(""));
                //数据库查找方式
                return new User(username,clientSecret, AuthorityUtils.commaSeparatedStringToAuthorityList(""));
            }
        }

        if (StringUtils.isEmpty(username)) {
            return null;
        }

        // 通过数据库去查询用户通过密码授权
        com.zhangmeng.model.entity.User user = this.adminFeign.findByUserName(username);

        //根据用户查询权限列表
        List<Permission> permissions = this.adminFeign.findByUserId(user.getId());
        Set<SimpleGrantedAuthority> collect = permissions.parallelStream().filter(permission -> !org.springframework.util.StringUtils.isEmpty(permission.getTitle()))
                .map(permission -> new SimpleGrantedAuthority(permission.getTitle())).collect(Collectors.toSet());
        return new UserJwt(username,user.getPassword(),collect);
    }
}
