package com.persagy.account.manage; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.collect.Lists; import com.persagy.account.pojo.dto.SaasAccount; import com.persagy.account.pojo.dto.SaasArea; import com.persagy.account.pojo.dto.SaasGroup; import com.persagy.account.service.ISaasAccountService; import com.persagy.account.service.ISaasGroupService; import com.persagy.common.constant.SaasCommonConstant; import com.persagy.common.enums.ResponseCode; import com.persagy.common.exception.BusinessException; import com.persagy.common.utils.StringUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.crypto.digest.MD5; /** * @version * @description * @company persagy * @author zhangqiankun * @since 2021年3月18日: 上午10:20:22 */ @Component public class SaasAuthHandler { private static MD5 md5 = MD5.create(); @Autowired private ISaasGroupService saasGroupService; @Autowired private ISaasAccountService saasAccountService; @Autowired private SaasAreaProjectHandler saasAreaProjectHandler; @Autowired private RedisTemplate redisTemplate; /** * 验证此账号的集团项目权限 * * @param accountId * @param groupCode * @return * 权限鉴定通过时: * 若有返回集团编码,则此返回值必须作为代码向下执行的sql条件; * 若有返回accountType,需进行 SaasCommonConstant.STR_STATUS_2.equals(accountType) 账号类型的判断 */ public Map validGroupProjectAuth(String accountId, String groupCode) { // 获取此账号对应的集团权限 SaasAccount account = this.saasAccountService.getOne(accountId, null, null); if (account == null) { throw new BusinessException("账号信息为空"); } // 添加数据访问控制,账号类型,0-所有集团项目,1-单集团所有项目,2-其他 String accountType = account.getAccountType(); // 1时,判断是否有权限 Map result = new HashMap(2); if (SaasCommonConstant.STR_STATUS_1.equals(accountType)) { String allowGroupCode = account.getGroupCode(); if (StringUtil.isNotBlank(groupCode) && !groupCode.equals(allowGroupCode)) { throw new BusinessException("账号无该集团的访问权限"); } result.put(SaasCommonConstant.GROUP_CODE, allowGroupCode); } result.put(SaasCommonConstant.ACCOUNT_TYPE, accountType); return result; } /** * 返回允许此账号访问的集团信息 * * @param accountId * @param groupCode * @return 允许此账号访问的集团信息 */ public List getAllowGroupList(String accountId, String groupCode) { // 获取此账号对应的集团权限 SaasAccount account = this.saasAccountService.getOne(accountId, null, null); if (account == null) { throw new BusinessException("账号信息为空"); } // 添加数据访问控制,账号类型,0-所有集团项目,1-单集团所有项目,2-其他 String accountType = account.getAccountType(); // 1时,判断是否有权限 if (SaasCommonConstant.STR_STATUS_1.equals(accountType)) { String allowGroupCode = account.getGroupCode(); if (StringUtil.isNotBlank(groupCode) && !groupCode.equals(allowGroupCode)) { throw new BusinessException("账号无该集团的访问权限"); } groupCode = allowGroupCode; } return this.getAllowGroupList(accountId, groupCode, accountType); } /** * 返回允许此账号访问的集团信息 * * @param accountId * @param groupCode * @param accountType * @return 允许此账号访问的集团信息 */ public List getAllowGroupList(String accountId, String groupCode, String accountType) { List groups = null; if (SaasCommonConstant.STR_STATUS_2.equals(accountType)) { SaasGroup saasGroup = new SaasGroup(); saasGroup.setGroupCode(groupCode); saasGroup.setValid(SaasCommonConstant.STATUS_1); groups = this.saasGroupService.queryAllowGroupInfo(saasGroup, accountId); } else { LambdaQueryWrapper queryWrapper = new SaasGroup.Builder().createQueryWrapper().validEq(SaasCommonConstant.STATUS_1).builderQueryWrapper(); groups = this.saasGroupService.list(queryWrapper); } return groups == null ? Lists.newArrayList() : groups; } /** * 返回被允许访问的区域树 * * @param accountId * @param groupCode * @return 允许此账号访问的集团信息 */ public List getAllowAreaList(String accountId, String groupCode) { // 获取此账号对应的集团权限 SaasAccount account = this.saasAccountService.getOne(accountId, null, null); if (account == null) { throw new BusinessException("账号信息为空"); } // 添加数据访问控制,账号类型,0-所有集团项目,1-单集团所有项目,2-其他 String accountType = account.getAccountType(); // 1时,判断是否有权限 if (SaasCommonConstant.STR_STATUS_1.equals(accountType)) { String allowGroupCode = account.getGroupCode(); if (StringUtil.isNotBlank(groupCode) && !groupCode.equals(allowGroupCode)) { throw new BusinessException("账号无该集团的访问权限"); } groupCode = allowGroupCode; } return this.getAllowAreaList(accountId, groupCode, accountType); } /** * 返回被允许访问的区域树 * * @param accountId * @param groupCode * @param accountType * @return */ public List getAllowAreaList(String accountId, String groupCode, String accountType) { List topList = this.saasAreaProjectHandler.getTopAreaList(groupCode); if (SaasCommonConstant.STR_STATUS_2.equals(accountType)) { // 其他类型时,需要根据权限表数据,去匹配区域树 this.saasAreaProjectHandler.queryAllowAreaTree(topList, accountId, groupCode); } else { this.saasAreaProjectHandler.querySaasAreaTree(topList, false); } return topList; } /** * 验证此账号的菜单权限 * * @param accountId * @param groupCode * @return * 权限鉴定通过时: * 有accountbelong 账号所属字段 * 若有返回集团编码,则此返回值必须作为代码向下执行的sql条件; * 若有返回accountType,需进行 SaasCommonConstant.STR_STATUS_2.equals(accountType) 账号类型的判断 */ public Map validSaasMenuAuth(String accountId, String groupCode) { // 获取此账号对应的集团权限 SaasAccount account = this.saasAccountService.getOne(accountId, null, null); if (account == null) { throw new BusinessException("账号信息为空"); } // 添加数据访问控制,账号类型,0-所有集团项目,1-单集团所有项目,2-其他 String accountType = account.getAccountType(); // 1时,判断是否有权限 Map result = new HashMap(2); if (SaasCommonConstant.STR_STATUS_1.equals(accountType)) { String allowGroupCode = account.getGroupCode(); if (StringUtil.isNotBlank(groupCode) && !groupCode.equals(allowGroupCode)) { throw new BusinessException("账号无该集团的访问权限"); } result.put(SaasCommonConstant.GROUP_CODE, allowGroupCode); } result.put(SaasCommonConstant.ACCOUNT_TYPE, accountType); result.put(SaasCommonConstant.ACCOUNT_BELONG, account.getAccountBelong()); return result; } /** * 申请授权码 */ public String getCode(String clientId, String redirectUrl) { // 验证客户端ID是否存在 Boolean member = this.redisTemplate.opsForSet().isMember(SaasCommonConstant.SAAS_CLIENT_ID_REDIS_KEY, clientId); if (!BooleanUtil.isTrue(member)) { throw new BusinessException(ResponseCode.A0001.getCode(), "非法客户端"); } // 生成新的授权码,并验证授权码是否已存在 String redisKey = this.getCodeRediskey(clientId, redirectUrl); JSONObject temp = new JSONObject(); temp.put("time", System.currentTimeMillis()); temp.put("redirectUrl", redirectUrl); String code = md5.digestHex(temp.toJSONString()); Boolean setIfAbsent = this.redisTemplate.opsForValue().setIfAbsent(redisKey, code, 300000L, TimeUnit.MILLISECONDS); if (!BooleanUtil.isTrue(setIfAbsent)) { throw new BusinessException(ResponseCode.A0302.getCode(), ResponseCode.A0302.getDesc()); } return code; } /** * 客户端ID * @param clientId 不可为空 * @param redirectUrl 可为空 * @return */ public String getCodeRediskey(String clientId, String redirectUrl) { if (StringUtil.isBlank(redirectUrl)) { redirectUrl = ""; } return clientId + SaasCommonConstant.UNDERLINE_JOIN_SYMBOL + md5.digestHex(redirectUrl); } }