package jnpf.listener; import com.alibaba.fastjson.JSONObject; import com.baomidou.lock.LockInfo; import com.baomidou.lock.LockTemplate; import jnpf.base.UserInfo; import jnpf.base.model.module.ModuleModel; import jnpf.constant.EventConst; import jnpf.event.ProjectEventListener; import jnpf.flowable.TemplateApi; import jnpf.flowable.WorkFlowApi; import jnpf.module.ProjectEventInstance; import jnpf.permission.RoleApi; import jnpf.permission.entity.RoleEntity; import jnpf.permission.model.authorize.AuthorizeVO; import jnpf.permissions.PermissionInterfaceImpl; import jnpf.util.JsonUtil; import jnpf.util.StringUtil; import jnpf.util.UserProvider; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; import static jnpf.util.Constants.ADMIN_KEY; /** * 接口权限初始化 */ @Slf4j @Component public class InterfacePermissionListener { @Autowired private RoleApi roleApi; @Autowired private LockTemplate lockTemplate; @Autowired private WorkFlowApi workFlowApi; @ProjectEventListener(channel = EventConst.EVENT_INIT_LOGIN_PERMISSION) public void initPermission(ProjectEventInstance eventInstance) { UserInfo userInfo = UserProvider.getUser(); //远程事件 // AuthorizeVO authorizeVO = ((JSONObject)eventInstance.getSource()).toJavaObject(AuthorizeVO.class); //本地事件 AuthorizeVO authorizeVO = (AuthorizeVO) eventInstance.getSource(); initSecurityAuthorities(authorizeVO, userInfo); } /** * 初始化接口鉴权用的账号权限 * 本接口插入权限缓存, SaInterfaceImpl中框架鉴权时动态调用获取权限列表 * * @param authorizeModel * @param userInfo */ private void initSecurityAuthorities(AuthorizeVO authorizeModel, UserInfo userInfo) { if(authorizeModel.getCurrentSystem() == null) return; String sysId = authorizeModel.getCurrentSystem().getId(); if (Objects.equals(1, userInfo.getIsBackend())) { sysId += "_backend"; } //接口权限 Set authorityList = new HashSet<>(); Set roleAuthorityList = new HashSet<>(); Map moduleModelMap = new LinkedHashMap<>(); Map flowFormMap = new HashMap<>(); Map allFlowFormMap = workFlowApi.getFlowFormMap(); Map>> columnsMap = new HashMap<>(); Map>> formMap = new HashMap<>(); for (ModuleModel moduleModel : authorizeModel.getModuleList()) { // 添加菜单权限 // 添加菜单ID, 代码生成用 authorityList.add(moduleModel.getId()); // 添加菜单编码 authorityList.add(moduleModel.getEnCode()); moduleModelMap.put(moduleModel.getId(), moduleModel); //功能菜单 3:功能菜单, 9: 流程菜单 if (moduleModel.getType() == 3 || moduleModel.getType() == 9 || moduleModel.getType() == 10) { JSONObject propertyJSON = JSONObject.parseObject(Optional.of(moduleModel.getPropertyJson()).orElse("{}")); //{"iconBackgroundColor":"","isTree":0,"moduleId":"395851986114733317"} String moduleId = propertyJSON.getString("moduleId"); if (!StringUtil.isEmpty(moduleId)) { authorityList.add(moduleId); // 流程菜单 拥有流程菜单权限, 直接赋予流程下第一个表单的权限 if (moduleModel.getType() == 9) { // 表单编码 String formId = flowFormMap.get(moduleId); if (formId == null) { formId = allFlowFormMap.get(moduleId); } if (StringUtil.isNotEmpty(formId)) { flowFormMap.put(moduleId, formId); authorityList.add(formId); } else { log.error("初始化流程菜单权限失败, 流程表单不存在:" + moduleModel.getFullName()); } } } } } //按钮权限 菜单编码::按钮编码 authorizeModel.getButtonList().forEach(t -> { ModuleModel m = moduleModelMap.get(t.getModuleId()); if (m != null) { authorityList.add(m.getEnCode() + "::" + t.getEnCode()); //功能菜单的按钮权限 3:功能菜单, 9: 流程菜单 if (m.getType() == 3 || m.getType() == 9) { JSONObject propertyJSON = JSONObject.parseObject(Optional.of(m.getPropertyJson()).orElse("{}")); //{"iconBackgroundColor":"","isTree":0,"moduleId":"395851986114733317"} String moduleId = propertyJSON.getString("moduleId"); if (!StringUtil.isEmpty(moduleId)) { authorityList.add(moduleId + "::" + t.getEnCode()); // 流程菜单, 直接赋予流程下第一个表单的对应流程按钮权限 if (m.getType() == 9) { // 表单编码 String formId = flowFormMap.get(moduleId); if (StringUtil.isNotEmpty(formId)) { authorityList.add(formId + "::" + t.getEnCode()); } } } } } }); //列表权限 菜单编码::列表编码 authorizeModel.getColumnList().forEach(t -> { ModuleModel m = moduleModelMap.get(t.getModuleId()); if (m != null) { authorityList.add(m.getEnCode() + "::" + t.getEnCode()); } List> list; if (columnsMap.get(t.getModuleId()) == null) { list = new ArrayList<>(); list.add(JsonUtil.entityToMap(t)); columnsMap.put(t.getModuleId(), list); } else { list = columnsMap.get(t.getModuleId()); list.add(JsonUtil.entityToMap(t)); columnsMap.put(t.getModuleId(), list); } }); //表单权限 菜单编码::表单编码 authorizeModel.getFormsList().forEach(t -> { ModuleModel m = moduleModelMap.get(t.getModuleId()); if (m != null) { authorityList.add(m.getEnCode() + "::" + t.getEnCode()); } List> list; if (formMap.get(t.getModuleId()) == null) { list = new ArrayList<>(); list.add(JsonUtil.entityToMap(t)); formMap.put(t.getModuleId(), list); } else { list = formMap.get(t.getModuleId()); list.add(JsonUtil.entityToMap(t)); formMap.put(t.getModuleId(), list); } }); if (userInfo.getRoleIds() != null && !userInfo.getRoleIds().isEmpty() || userInfo.getIsAdministrator()) { List roles; if (userInfo.getIsAdministrator()) { roles = roleApi.getListAll(); } else { roles = roleApi.getListByIds(userInfo.getRoleIds()); } roleAuthorityList = roles.stream().filter(r -> r.getEnabledMark().equals(1)).map(r -> "ROLE_" + r.getEnCode()).collect(Collectors.toSet()); } //管理员都是用同一个缓存, 普通账号使用账号名, //权限列表:authorize_:租户_authorize_authorize_(admin|账号) //角色列表:authorize_:租户_authorize_role_(admin|账号) String account = userInfo.getIsAdministrator() ? ADMIN_KEY : userInfo.getUserId(); LockInfo lockInstance = null; try { if (!authorityList.isEmpty() || !roleAuthorityList.isEmpty()) { String loginId = UserProvider.splicingLoginId(account); // 等待其他服务初始化权限完毕 // lockInstance = lockTemplate.lock(RedisConst.REDIS_LOCK4J_PREFIX + ModuleName.OAUTH_SERVER_NAME + loginId, 10000L, 10000L); // if(lockInstance != null) { PermissionInterfaceImpl.setUserAuth(account, sysId, authorityList, roleAuthorityList, null); PermissionInterfaceImpl.setMap(account, sysId, columnsMap, formMap); // } } } catch (Exception e) { log.error("初始化接口权限失败", e); } finally { // if(lockInstance != null) { // lockTemplate.releaseLock(lockInstance); // } } } }