package cn.palmte.work.shiro;


import cn.palmte.work.model.Admin;
import cn.palmte.work.service.AdminService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;
import java.util.List;


/**
 * Created by wang.lin@esstx.cn on 2018/4/17.
 */
public class ShiroAuthorizingRealm extends AuthorizingRealm {

    private final static Logger logger = LoggerFactory.getLogger(ShiroAuthorizingRealm.class);
    private static final String AUTHORITIES = "authorities";

    @Autowired
    private AdminService adminService;

    //shiro的权限配置方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        logger.debug("权限配置-->doGetAuthorizationInfo");

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        logger.debug("----------------------------->" + principals.getPrimaryPrincipal());
        // 获取当前登录的用户名
        ShiroPrincipal subject = (ShiroPrincipal) super.getAvailablePrincipal(principals);
        String adminName = subject.getAdminName();
        String adminId = subject.getId();
        HttpSession session = getSession();
        try {
            if (!subject.isAuthorized()) {
                // 根据用户名称，获取该用户所有的权限列表
                List<String> authorities = adminService.getAuthoritiesName(adminId);
                List<String> rolelist = adminService.getRolesName(adminId);
//                List<String> urls = adminService.getAuthoritieUrls(adminId);
                //subject.setAuthorities(authorities);
                session.setAttribute(AUTHORITIES, authorities);
                subject.setRoles(rolelist);
//                subject.setUrls(urls);
                subject.setAuthorized(true);
                logger.debug("用户【" + adminName + "】授权初始化成功......");
                logger.debug("用户【" + adminName + "】 角色列表为：" + subject.getRoles());
                logger.debug("用户【" + adminName + "】 权限列表为：" + authorities);
            }
        } catch (RuntimeException e) {
            throw new AuthorizationException("用户【" + adminName + "】授权失败");
        }
        // 给当前用户设置权限

        List<String> authorities = null;
        if (session.getAttribute(AUTHORITIES) != null) {
            authorities = (List<String>) session.getAttribute(AUTHORITIES);
        }
        authorizationInfo.addStringPermissions(authorities);
        authorizationInfo.addRoles(subject.getRoles());
        return authorizationInfo;
    }

    //shiro的身份验证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();

        if (username == null) {
            logger.warn("用户名不能为空");
            throw new AccountException("用户名不能为空");
        }

        Admin admin = null;
        try {
            admin = adminService.getAdminByUsername(username);
        } catch (Exception ex) {
            logger.warn("获取用户失败\n" + ex.getMessage());
        }
        if (admin == null) {
            logger.warn("用户不存在");
            throw new UnknownAccountException("用户不存在!");
        }
        ShiroPrincipal subject = new ShiroPrincipal(admin);
        String adminId = String.valueOf(admin.getId());
        List<String> authorities = adminService.getAuthoritiesName(adminId);
        List<String> rolelist = adminService.getRolesName(adminId);
//        List<String> urls = adminService.getAuthoritieUrls(adminId);
//        subject.setUrls(urls);
        subject.setRoles(rolelist);
        //subject.setAuthorities(authorities);
        HttpSession session = getSession();
        session.setAttribute(AUTHORITIES, authorities);
        subject.setAuthorized(true);
        return new SimpleAuthenticationInfo(subject, admin.getPassword(), getName());
    }

    private HttpSession getSession() {
        return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getSession();
    }

}
