package com.njzscloud.common.security.permission;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.njzscloud.common.security.ex.MissingPermissionException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;

@Slf4j
@RequiredArgsConstructor
public class PermissionSecurityMetaDataSource implements FilterInvocationSecurityMetadataSource {

    // org.springframework.security.config.annotation.web.configurers.UrlAuthorizationConfigurer
    // org.springframework.security.access.vote.RoleVoter  PermissionAuthorizationConfigurer

    private final PermissionManager permissionManager;
    // private final boolean rejectPublicInvocations;


    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        HttpServletRequest request = ((FilterInvocation) object).getRequest();
        Collection<ConfigAttribute> permission = permissionManager.extractAuthorities(request);
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        String endpoint = method.toUpperCase() + " " + requestURI;

        Assert.notEmpty(permission, () -> new MissingPermissionException(StrUtil.format("请求: 【{}】 未指定权限", endpoint)));
        if (log.isDebugEnabled()) log.debug("允许访问接口：【{}】的角色：【{}】", endpoint, permission);
        return permission;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return permissionManager.getAll();
    }

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