package com.brframework.commonsecurity.core;

import com.brframework.commonweb.core.SpringContext;
import com.brframework.commonweb.utils.ServletUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * @Author xu
 * @Date 2018/2/28 0028 上午 11:37
 * 安全架构上下文持有
 */
public class SecurityContextHolder {

    /** jwt 转换后的用户信息 */
    private final static ThreadLocal<SecuritySubject> SUBJECT = new ThreadLocal<>();


    public static SecuritySubject getSubject() {
        return SUBJECT.get();
    }

    /**
     * 加载Subject
     * @param userDetailsService
     */
    public static void loadSubject(UserDetailsService userDetailsService) {
        String auth = ServletUtils.request().getHeader("Authorization");
        //不存在Authorization
        if(StringUtils.isEmpty(auth)) {
            return;
        }

        SecurityUserDetails user = (SecurityUserDetails) userDetailsService.loadUserByUsername(auth);

        //持有subject
        SecurityContextHolder.setSubject(user.getSubject());

        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), null, user.getAuthorities());
        token.setDetails(user);
        //设置security权限
        org.springframework.security.core.context.SecurityContextHolder.getContext().setAuthentication(token);
    }

    /**
     * 加载Subject
     * @param springSecurityBeanName
     */
    public static void loadSubject(String springSecurityBeanName) {
        //获取bean
        SecurityUserDetailsService userDetailsService = SpringContext.getBean(springSecurityBeanName);
        loadSubject(userDetailsService);
    }

    public static void setSubject(SecuritySubject securitySubject) {
        SUBJECT.set(securitySubject);
    }

    public static boolean hasRole(String role){
        SecuritySubject subject = getSubject();
        for (String auth : subject.getAuthorities()) {
            if(auth.equals(role)){
                return true;
            }
        }
        return false;
    }

    /**
     * 释放
     */
    public static void destroy(){
        SUBJECT.remove();
    }
}
