feat: (feature/REQ-2595) 修改项目下有权限的人支持权限标签过滤

This commit is contained in:
lilong 2024-10-25 10:40:24 +08:00
parent 9a9ab39fcc
commit ad7224a332
10 changed files with 154 additions and 438 deletions

View File

@ -101,6 +101,7 @@ public interface TyrSaasAuthApi {
/**
*
* 通过资源ID资源类型角色分类 查询权限
* 该分类下不能有管理员角色原始代码没有实现管理员角色的权限
* @param listPermissionFromRoleGroupReq
* @return
*/

View File

@ -3,7 +3,6 @@ package cn.axzo.tyr.client.model.req;
import cn.axzo.framework.auth.domain.TerminalInfo;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -81,23 +80,6 @@ public class IdentityAuthReq {
*/
private Integer versionMax;
public IdentityAuthRes toEmpty() {
IdentityAuthRes result = new IdentityAuthRes();
result.setIdentity(this.getIdentityId());
result.setIdentityType(this.getIdentityType());
result.setPersonId(this.getPersonId());
List<IdentityAuthRes.WorkspacePermission> permissions = this.getWorkspaceOusPairs().stream()
.map(workspaceOuPair -> IdentityAuthRes.WorkspacePermission.builder()
.workspaceId(workspaceOuPair.getWorkspaceId())
.ouId(workspaceOuPair.getOuId())
.build())
.collect(Collectors.toList());
result.setPermissions(permissions);
return result;
}
public void distinctOUWorkspacePair() {
if (CollectionUtil.isEmpty(this.workspaceOusPairs)) {
return;

View File

@ -1,5 +1,6 @@
package cn.axzo.tyr.client.model.req;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -7,6 +8,7 @@ import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;
/**
@ -40,4 +42,5 @@ public class ListIdentityFromPermissionReq {
*/
private String terminal;
private Set<RolePermissionTagEnum> tags;
}

View File

@ -2,6 +2,7 @@ package cn.axzo.tyr.client.model.req;
import cn.axzo.tyr.client.common.enums.SaasPositionEnum;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -9,6 +10,7 @@ import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;
/**
* 通过角色分组及分类查询人员的权限

View File

@ -1,8 +1,10 @@
package cn.axzo.tyr.client.model.req;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Set;
/**
* OU和workspace对
@ -28,4 +30,6 @@ public class OUWorkspacePair {
/** 参建类型 - 直接依赖角色标签 不需要传了 **/
@Deprecated
private Integer workspaceJoinType;
private Set<RolePermissionTagEnum> tags;
}

View File

@ -1,9 +1,11 @@
package cn.axzo.tyr.client.model.req;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;
/**
* @version V1.0
@ -20,4 +22,6 @@ public class WorkspacePermissionIdentityReq {
/** 权限点CODE **/
@NotNull
private List<String> featureCodes;
private Set<RolePermissionTagEnum> tags;
}

View File

@ -1,6 +1,7 @@
package cn.axzo.tyr.client.model.res;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -88,6 +89,12 @@ public class ListPermissionFromRoleGroupResp {
private Long featureId;
/** 0saas_feature,1:saas_feature_resource **/
private Integer relationType;
private Set<RolePermissionTagEnum> tags;
}
public String buildOuWorkspaceKey() {
return this.getOuId() + "_" + this.getWorkspaceId();
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.tyr.server.model;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import cn.axzo.tyr.server.service.impl.TyrSaasAuthServiceImpl;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -7,6 +8,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Set;
/**
* 通过工作台过滤角色的权限
@ -24,4 +26,7 @@ public class FilterRoleAuth {
private Long workspaceId;
private Long ouId;
private Set<RolePermissionTagEnum> tags;
}

View File

@ -49,10 +49,4 @@ public interface TyrSaasAuthService {
* @return
*/
List<ListPermissionFromRoleGroupResp> listAuthByResourceAndRoleGroup(ListPermissionFromRoleGroupReq listPermissionFromRoleGroupReq);
/**
* 增加统一的开关权限是否从数据库查询
* @return
*/
boolean permissionFromDB();
}

View File

@ -12,7 +12,6 @@ import cn.axzo.tyr.client.model.enums.DelegatedType;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum;
import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq;
import cn.axzo.tyr.client.model.req.FeatureIdPair;
import cn.axzo.tyr.client.model.req.IdentityAuthReq;
import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq;
import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq;
@ -21,9 +20,7 @@ import cn.axzo.tyr.client.model.req.ListPermissionFromRoleGroupReq;
import cn.axzo.tyr.client.model.req.ListRoleReq;
import cn.axzo.tyr.client.model.req.OUWorkspacePair;
import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq;
import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq;
import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq;
import cn.axzo.tyr.client.model.req.QueryPermissionByIdsReq;
import cn.axzo.tyr.client.model.req.WorkspacePermissionIdentityReq;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp;
@ -31,23 +28,16 @@ import cn.axzo.tyr.client.model.res.ListPermissionFromRoleGroupResp;
import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp;
import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp;
import cn.axzo.tyr.client.model.res.SaasRoleRes;
import cn.axzo.tyr.client.model.res.SimplePermissionPointResp;
import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO;
import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam;
import cn.axzo.tyr.server.model.FilterRoleAuth;
import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao;
import cn.axzo.tyr.server.repository.entity.ProductFeatureInfo;
import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery;
import cn.axzo.tyr.server.repository.entity.RolePermission;
import cn.axzo.tyr.server.repository.entity.SaasFeature;
import cn.axzo.tyr.server.repository.entity.SaasFeatureResource;
import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation;
import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation;
import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation;
import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation;
import cn.axzo.tyr.server.repository.entity.SaasRole;
import cn.axzo.tyr.server.repository.entity.SaasRoleGroup;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser;
import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper;
import cn.axzo.tyr.server.repository.mapper.TyrSaasAuthMapper;
@ -57,7 +47,6 @@ import cn.axzo.tyr.server.service.RolePermissionCacheService;
import cn.axzo.tyr.server.service.RoleService;
import cn.axzo.tyr.server.service.SaasFeatureResourceService;
import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService;
import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService;
import cn.axzo.tyr.server.service.SaasRoleGroupService;
import cn.axzo.tyr.server.service.SaasRoleUserRelationService;
import cn.axzo.tyr.server.service.TyrSaasAuthService;
@ -68,7 +57,6 @@ import cn.azxo.framework.common.model.CommonResponse;
import cn.azxo.framework.common.utils.LogUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
@ -84,7 +72,6 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@ -123,7 +110,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
private final TyrSaasAuthMapper saasAuthMapper;
private final RoleService roleService;
private final RoleUserService roleUserService;
private final ServicePkgClient servicePkgClient;
@Qualifier("authExecutor")
@Autowired
@ -135,20 +121,10 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
private final WorkspaceProductService workspaceProductService;
private final SaasFeatureResourceService saasFeatureResourceService;
private final SaasPageElementFeatureResourceRelationService saasPageElementFeatureResourceRelationService;
private final SaasPgroupPermissionRelationService saasPgroupPermissionRelationService;
private final FeatureCodeUtil featureCodeUtil;
private final SaasPgroupRoleRelationDao saasPgroupRoleRelationDao;
private final RolePermissionCacheService rolePermissionCacheService;
private final SaasRoleUserRelationMapper saasRoleUserRelationMapper;
@Value("${permission.from.db:true}")
private boolean PERMISSION_FROM_DB;
@Override
public boolean permissionFromDB() {
return BooleanUtil.isTrue(PERMISSION_FROM_DB);
}
/**
* 通过身份查询人员权限
*
@ -440,6 +416,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
* 指定端的权限
*/
private String terminal;
private Set<RolePermissionTagEnum> tags;
}
private Set<Long> checkFeatureCodes(ListPermissionUser param) {
@ -515,17 +493,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
@Override
public ListIdentityFromPermissionResp listIdentityFromPermission(ListIdentityFromPermissionReq req) {
if (this.permissionFromDB()) {
return listIdentityFromPermissionFromDB(req);
}
try {
return listIdentityFromPermissionResp(req);
} catch (Exception ex) {
log.error("查询权限异常,执行降级处理");
return listIdentityFromPermissionFromDB(req);
}
return listIdentityFromPermissionResp(req);
}
private ListIdentityFromPermissionResp listIdentityFromPermissionResp(ListIdentityFromPermissionReq req) {
@ -535,6 +503,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
.ouId(req.getOuId())
.workspaceId(req.getWorkspaceId())
.terminal(req.getTerminal())
.tags(req.getTags())
.build();
List<ListIdentityFromPermissionResp.UserVO> userVOS = listPermissionUser(listPermissionUser);
@ -550,18 +519,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
return result;
}
private List<SaasRoleRes> listAdminRole(ListPermissionUser req) {
//超管和管理员
ListRoleReq listSaasRoleParam = ListRoleReq.builder()
.workspaceId(req.getWorkspaceId())
.ouId(req.getOuId())
.roleTypes(Lists.newArrayList(RoleTypeEnum.SUPER_ADMIN.getValue(), RoleTypeEnum.ADMIN.getValue()))
.build();
return roleService.list(listSaasRoleParam);
}
private Set<Long> resolvePermissionAdminRole(List<SaasRoleRes> adminRoles,
List<ProductPermissionCacheService.PermissionDTO> productPermissions) {
List<ProductPermissionCacheService.PermissionDTO> productPermissions,
ListPermissionUser listPermissionUser) {
if (!CollectionUtils.isEmpty(listPermissionUser.getTags()) && !listPermissionUser.getTags().contains(RolePermissionTagEnum.JOINED)) {
return Collections.emptySet();
}
Set<String> cooperateTypes = productPermissions.stream()
.map(ProductPermissionCacheService.PermissionDTO::getCooperateType)
.collect(Collectors.toSet());
@ -572,60 +536,53 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
.collect(Collectors.toSet());
}
private Set<Long> resolvePermissionNormalRole(ListPermissionUser req,
List<ProductPermissionCacheService.PermissionDTO> productPermissions,
Set<Long> featureIds) {
private Set<Long> resolvePermissionAdminLeaveRole(List<SaasRoleRes> adminRoles,
List<ProductPermissionCacheService.PermissionDTO> productPermissions,
ListPermissionUser listPermissionUser,
Set<Long> featureIds) {
// 因为通过权限id找对应的角色数据量巨大所以通过找项目的角色再找有权限的角色比较快
Set<Long> allRoleIds = saasRoleUserRelationMapper.listRoleIds(SaasRoleUserRelationMapper.ListRole.builder()
.ouId(req.getOuId())
.workspaceId(req.getWorkspaceId())
.build());
if (CollectionUtils.isEmpty(allRoleIds)) {
if (CollectionUtil.isEmpty(adminRoles)) {
log.info("no admin roles");
return Collections.emptySet();
}
List<SaasRoleRes> normalRoles = roleService.list(ListRoleReq.builder()
.roleIds(Lists.newArrayList(allRoleIds))
.roleTypes(RoleTypeEnum.listNormal())
.build());
if (CollectionUtils.isEmpty(normalRoles)) {
// 因为tag != LEAVE的权限管理员的权限直接是产品匹配的权限
if (CollectionUtils.isEmpty(listPermissionUser.getTags()) || !listPermissionUser.getTags().contains(RolePermissionTagEnum.LEAVE)) {
return Collections.emptySet();
}
RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder()
.roleIds(normalRoles.stream().map(SaasRoleRes::getId).collect(Collectors.toSet()))
.roleIds(adminRoles.stream().map(SaasRoleRes::getId).collect(Collectors.toSet()))
.featureCodes(productPermissions.stream()
.map(ProductPermissionCacheService.PermissionDTO::getFeatureCode)
.collect(Collectors.toSet()))
.build();
Map<Long, List<RolePermissionCacheService.PermissionDTO>> normalRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam);
Map<Long, List<RolePermissionCacheService.PermissionDTO>> adminRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam);
Set<Long> normalRoleIds = normalRolePermissionMap.entrySet().stream()
Set<Long> adminRoleIds = adminRolePermissionMap.entrySet().stream()
.filter(e -> !CollectionUtils.isEmpty(e.getValue()))
.filter(e -> e.getValue().stream().anyMatch(p -> featureIds.contains(p.getFeatureId())))
.filter(e -> StringUtils.isBlank(req.getTerminal())
|| e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), req.getTerminal())))
.filter(e -> StringUtils.isBlank(listPermissionUser.getTerminal())
|| e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), listPermissionUser.getTerminal())))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
Map<Long, SaasRoleRes> normalRoleMap = normalRoles.stream()
.filter(e -> normalRoleIds.contains(e.getId()))
Map<Long, SaasRoleRes> adminRoleMap = adminRoles.stream()
.filter(e -> adminRoleIds.contains(e.getId()))
.collect(Collectors.toMap(SaasRoleRes::getId, Function.identity()));
Map<String, Set<String>> featureCodeCooperateTypeMap = productPermissions.stream()
.collect(Collectors.groupingBy(ProductPermissionCacheService.PermissionDTO::getFeatureCode,
Collectors.mapping(ProductPermissionCacheService.PermissionDTO::getCooperateType, Collectors.toSet())));
return normalRolePermissionMap.entrySet().stream()
return adminRolePermissionMap.entrySet().stream()
.filter(e -> {
SaasRoleRes saasRoleRes = normalRoleMap.get(e.getKey());
SaasRoleRes saasRoleRes = adminRoleMap.get(e.getKey());
if (Objects.isNull(saasRoleRes)) {
return false;
}
return e.getValue().stream()
.filter(f -> StringUtils.isBlank(req.getTerminal())
|| e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), req.getTerminal())))
.filter(f -> StringUtils.isBlank(listPermissionUser.getTerminal())
|| e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), listPermissionUser.getTerminal())))
.anyMatch(f -> {
Set<String> productCooperateTypes = featureCodeCooperateTypeMap.get(f.getFeatureCode());
if (CollectionUtils.isEmpty(productCooperateTypes)) {
@ -638,19 +595,89 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
.collect(Collectors.toSet());
}
private Set<Long> resolvePermissionNormalRole(List<SaasRoleRes> allRoles,
ListPermissionUser req,
List<ProductPermissionCacheService.PermissionDTO> productPermissions,
Set<Long> featureIds) {
List<SaasRoleRes> normalRoles = allRoles.stream()
.filter(e -> !RoleTypeEnum.isAdmin(e.getRoleType()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(normalRoles)) {
return Collections.emptySet();
}
Map<Long, SaasRoleRes> normalRoleMap = normalRoles.stream()
.collect(Collectors.toMap(SaasRoleRes::getId, Function.identity()));
Map<String, Set<String>> featureCodeCooperateTypeMap = productPermissions.stream()
.collect(Collectors.groupingBy(ProductPermissionCacheService.PermissionDTO::getFeatureCode,
Collectors.mapping(ProductPermissionCacheService.PermissionDTO::getCooperateType, Collectors.toSet())));
RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder()
.roleIds(normalRoles.stream().map(SaasRoleRes::getId).collect(Collectors.toSet()))
.featureCodes(productPermissions.stream()
.map(ProductPermissionCacheService.PermissionDTO::getFeatureCode)
.collect(Collectors.toSet()))
.build();
Map<Long, List<RolePermissionCacheService.PermissionDTO>> normalRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam);
return normalRolePermissionMap.entrySet().stream()
.filter(e -> !CollectionUtils.isEmpty(e.getValue()))
.filter(e -> e.getValue().stream().anyMatch(p -> featureIds.contains(p.getFeatureId())))
.filter(e -> StringUtils.isBlank(req.getTerminal())
|| e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), req.getTerminal())))
.filter(e -> e.getValue().stream()
.anyMatch(f -> {
SaasRoleRes saasRoleRes = normalRoleMap.get(e.getKey());
if (Objects.isNull(saasRoleRes)) {
return false;
}
Set<String> productCooperateTypes = featureCodeCooperateTypeMap.get(f.getFeatureCode());
if (CollectionUtils.isEmpty(productCooperateTypes)) {
return false;
}
return productCooperateTypes.contains(String.valueOf(saasRoleRes.getProductUnitType()));
}))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
private List<ListIdentityFromPermissionResp.UserVO> getWorkspaceUserV2(ListPermissionUser req,
List<ProductPermissionCacheService.PermissionDTO> productPermissions,
Set<Long> featureIds) {
//超管和管理员
List<SaasRoleRes> adminRoles = listAdminRole(req);
// 因为通过权限id找对应的角色数据量巨大所以通过找项目的角色再找有权限的角色比较快
Set<Long> allRoleIds = saasRoleUserRelationMapper.listRoleIds(SaasRoleUserRelationMapper.ListRole.builder()
.ouId(req.getOuId())
.workspaceId(req.getWorkspaceId())
.build());
if (CollectionUtils.isEmpty(allRoleIds)) {
return Collections.emptyList();
}
Set<Long> adminPermissionRoleIds = resolvePermissionAdminRole(adminRoles, productPermissions);
Set<Long> normalPermissionRoleIds = resolvePermissionNormalRole(req, productPermissions, featureIds);
List<SaasRoleRes> allRoles = roleService.list(ListRoleReq.builder()
.roleIds(Lists.newArrayList(allRoleIds))
.build());
if (CollectionUtils.isEmpty(allRoles)) {
return Collections.emptyList();
}
//超管和管理员
List<SaasRoleRes> adminRoles = allRoles.stream()
.filter(e -> RoleTypeEnum.isAdmin(e.getRoleType()))
.collect(Collectors.toList());
Set<Long> adminPermissionRoleIds = resolvePermissionAdminRole(adminRoles, productPermissions, req);
Set<Long> normalPermissionRoleIds = resolvePermissionNormalRole(allRoles, req, productPermissions, featureIds);
Set<Long> adminLeavePermissionRoleIds = resolvePermissionAdminLeaveRole(adminRoles, productPermissions, req, featureIds);
Set<Long> roleIds = Sets.newHashSet();
roleIds.addAll(adminPermissionRoleIds);
roleIds.addAll(normalPermissionRoleIds);
roleIds.addAll(adminLeavePermissionRoleIds);
if (CollectionUtil.isEmpty(roleIds)) {
log.warn("no role matched product unit types");
@ -818,7 +845,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
* @param filterRoleAuths
* @return KEY :role Id ; VALUE: feature id ;
*/
public Map<Long, Set<ListPermissionFromRoleGroupResp.FeatureInfo>> filterAuthByRoleAndProduct(List<FilterRoleAuth> filterRoleAuths) {
private Map<Long, Set<ListPermissionFromRoleGroupResp.FeatureInfo>> filterAuthByRoleAndProduct(List<FilterRoleAuth> filterRoleAuths) {
Set<Long> roleIds = filterRoleAuths.stream().map(FilterRoleAuth::getRoleId).collect(Collectors.toSet());
ListRoleReq listSaasRoleParam = ListRoleReq.builder()
@ -904,170 +931,33 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
@Override
public List<ListIdentityFromPermissionResp> listWorkspacePermissionIdentity(WorkspacePermissionIdentityReq req) {
if (this.permissionFromDB()) {
return listWorkspacePermissionIdentityFromDB(req);
Set<String> newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCodes()));
Set<String> featureCodes = Sets.newHashSet(req.getFeatureCodes());
featureCodes.addAll(newFeatureCodes);
ListPermissionUser listPermissionUser = ListPermissionUser.builder()
.featureCodes(featureCodes)
.workspaceId(req.getWorkspaceId())
.tags(req.getTags())
.build();
List<ListIdentityFromPermissionResp.UserVO> users = listPermissionUser(listPermissionUser);
if (CollectionUtil.isEmpty(users)) {
return Collections.emptyList();
}
try {
Set<String> newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCodes()));
Set<String> featureCodes = Sets.newHashSet(req.getFeatureCodes());
featureCodes.addAll(newFeatureCodes);
ListPermissionUser listPermissionUser = ListPermissionUser.builder()
.featureCodes(featureCodes)
//按ou分组返回
List<ListIdentityFromPermissionResp> result = new ArrayList<>();
Map<Long, List<ListIdentityFromPermissionResp.UserVO>> userMap = users.stream()
.collect(Collectors.groupingBy(ListIdentityFromPermissionResp.UserVO::getOuId));
for (Map.Entry<Long, List<ListIdentityFromPermissionResp.UserVO>> entry : userMap.entrySet()) {
result.add(ListIdentityFromPermissionResp.builder()
.workspaceId(req.getWorkspaceId())
.build();
List<ListIdentityFromPermissionResp.UserVO> users = listPermissionUser(listPermissionUser);
if (CollectionUtil.isEmpty(users)) {
return Collections.emptyList();
}
//按ou分组返回
List<ListIdentityFromPermissionResp> result = new ArrayList<>();
Map<Long, List<ListIdentityFromPermissionResp.UserVO>> userMap = users.stream()
.collect(Collectors.groupingBy(ListIdentityFromPermissionResp.UserVO::getOuId));
for (Map.Entry<Long, List<ListIdentityFromPermissionResp.UserVO>> entry : userMap.entrySet()) {
result.add(ListIdentityFromPermissionResp.builder()
.workspaceId(req.getWorkspaceId())
.ouId(entry.getKey())
.users(entry.getValue())
.build());
}
return result;
} catch (Exception ex) {
log.error("查询权限异常,执行降级处理");
return listWorkspacePermissionIdentityFromDB(req);
.ouId(entry.getKey())
.users(entry.getValue())
.build());
}
}
private List<SaasRole> listFeatureRoles(Set<Long> featureIds, Integer type) {
if (CollectionUtils.isEmpty(featureIds)) {
return Collections.emptyList();
}
List<SaasPgroupPermissionRelation> relations = saasPgroupPermissionRelationService.list(PagePgroupPermissionRelationReq.builder()
.featureIds(Lists.newArrayList(featureIds))
.type(type)
.build());
if (CollectionUtils.isEmpty(relations)) {
return Collections.emptyList();
}
List<SaasPgroupRoleRelation> saasPgroupRoleRelations = saasPgroupRoleRelationDao.listByGroupIds(Lists.transform(relations, SaasPgroupPermissionRelation::getGroupId));
if (CollectionUtils.isEmpty(saasPgroupRoleRelations)) {
return Collections.emptyList();
}
return roleService.list(ListRoleReq.builder()
.roleIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getRoleId))
.build())
.stream()
.map(e -> {
SaasRole saasRole = new SaasRole();
BeanUtils.copyProperties(e, saasRole);
return saasRole;
})
.collect(Collectors.toList());
}
private List<ListIdentityFromPermissionResp.UserVO> getWorkspaceUser(Long workspaceId, Long ouId,
List<SaasProductModuleFeatureRelation> workspaceProducts) {
Set<Integer> newProductTypes = workspaceProducts.stream()
.filter(e -> Objects.equals(e.getType(), NEW_FEATURE))
.map(SaasProductModuleFeatureRelation::getDictCode)
.map(Integer::valueOf)
.collect(Collectors.toSet());
Set<Long> newMatchedFeatureIds = workspaceProducts.stream()
.filter(e -> Objects.equals(e.getType(), NEW_FEATURE))
.map(SaasProductModuleFeatureRelation::getFeatureId)
.collect(Collectors.toSet());
Set<Integer> oldProductTypes = workspaceProducts.stream()
.filter(e -> Objects.equals(e.getType(), OLD_FEATURE))
.map(SaasProductModuleFeatureRelation::getDictCode)
.map(Integer::valueOf)
.collect(Collectors.toSet());
Set<Long> oldMatchedFeatureIds = workspaceProducts.stream()
.filter(e -> Objects.equals(e.getType(), OLD_FEATURE))
.map(SaasProductModuleFeatureRelation::getFeatureId)
.collect(Collectors.toSet());
//超管和管理员
List<SaasRole> adminRoles = roleService.listAdmins(workspaceId, ouId);
if (CollectionUtil.isEmpty(adminRoles)) {
log.warn("no admin roles found for workspaceId:{}, ouId:{}", workspaceId, ouId);
}
Set<Long> superAdmins = adminRoles.stream()
.filter(r -> RoleTypeEnum.SUPER_ADMIN.getValue().equals(r.getRoleType()))
.map(SaasRole::getId)
.collect(Collectors.toSet());
//普通角色 权限点查角色 -- 不考虑 角色权限集例外
// 多版本只会存在一段时间减少代码复杂度所以查询多次
List<SaasRole> oldNormalSaasRoles = listFeatureRoles(oldMatchedFeatureIds, OLD_FEATURE);
List<SaasRole> newNormalSaasRoles = listFeatureRoles(newMatchedFeatureIds, NEW_FEATURE);
List<Long> roleIds = Lists.newArrayList();
// 超管不用区分新老版本
List<Long> adminRoleIds = adminRoles.stream()
.filter(r -> newProductTypes.contains(r.getProductUnitType()) || oldProductTypes.contains(r.getProductUnitType()))
.map(SaasRole::getId)
.collect(Collectors.toList());
List<Long> oldNormalRoleIds = oldNormalSaasRoles.stream()
.filter(r -> oldProductTypes.contains(r.getProductUnitType()))
.map(SaasRole::getId)
.collect(Collectors.toList());
List<Long> newNormalRoleIds = newNormalSaasRoles.stream()
.filter(r -> newProductTypes.contains(r.getProductUnitType()))
.map(SaasRole::getId)
.collect(Collectors.toList());
//匹配角色和产品标签
roleIds.addAll(adminRoleIds);
roleIds.addAll(oldNormalRoleIds);
roleIds.addAll(newNormalRoleIds);
if (CollectionUtil.isEmpty(roleIds)) {
log.warn("no role matched product unit types");
return Collections.emptyList();
}
//角色查人
List<SaasRoleUserRelation> relations = roleUserService.listByRoleIds(roleIds, ouId, workspaceId);
if (CollectionUtil.isEmpty(relations)) {
log.warn("no user role relation found. roleIds:{}, ouId:{} workspaceId:{}", roleIds, ouId, workspaceId);
return Collections.emptyList();
}
//ouId -> resp : ou-identityId-identityType维度去重
Map<String, ListIdentityFromPermissionResp.UserVO> distinctMap = new HashMap<>();
//组装去重
for (SaasRoleUserRelation relation : relations) {
String key = KeyUtil.buildKeyBySeparator(relation.getOuId(), relation.getIdentityId(), relation.getIdentityType());
ListIdentityFromPermissionResp.UserVO user = distinctMap.get(key);
if (user == null) {
user = ListIdentityFromPermissionResp.UserVO.builder()
.ouId(relation.getOuId())
.identityId(relation.getIdentityId())
.identityType(relation.getIdentityType())
.personalId(relation.getNaturalPersonId())
.build();
}
if (superAdmins.contains(relation.getRoleId())) {
//超管
user.setSuperAdmin(true);
}
distinctMap.put(key, user);
}
return new ArrayList<>(distinctMap.values());
return result;
}
private List<SaasRoleUserV2DTO> mockRoleUserRelationV2(IdentityAuthReq identityAuthReq) {
@ -1527,180 +1417,4 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
*/
private Integer type;
}
private List<SimplePermissionPointResp> listOldFeatures(Set<FeatureWrapper> featureWrappers) {
Set<Long> featureIds = featureWrappers.stream()
.filter(e -> Objects.equals(e.getType(), OLD_FEATURE))
.map(FeatureWrapper::getFeatureId)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(featureIds)) {
return Collections.emptyList();
}
return permissionPointService.listPermissionByIds(
QueryPermissionByIdsReq.builder()
.ids(featureIds)
.includeParent(true)
.build());
}
public ListIdentityFromPermissionResp listIdentityFromPermissionFromDB(ListIdentityFromPermissionReq req) {
ListIdentityFromPermissionResp result = new ListIdentityFromPermissionResp();
result.setOuId(req.getOuId());
result.setWorkspaceId(req.getWorkspaceId());
Set<String> newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCode()));
//code查询权限点信息
List<SaasFeature> features = permissionPointService.listNodeWithChildrenByCodes(Lists.newArrayList(newFeatureCodes), req.getTerminal());
// 兼容新老版本需要通过featureCode查询新版本的features原逻辑是查询当前菜单资源的所有子数据
ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder()
.featureCodes(newFeatureCodes)
.terminal(req.getTerminal())
.build();
List<SaasFeatureResourceResp> saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam);
if (CollectionUtil.isEmpty(features) && CollectionUtils.isEmpty(saasFeatureResources)) {
log.warn("no features data found for:{}", req.getFeatureCode());
return result;
}
//是否免授权权限点
Optional<SaasFeature> freeFeature = features.stream()
.filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType()))
.findAny();
Optional<SaasFeatureResourceResp> freeFeatureResource = saasFeatureResources.stream()
.filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType()))
.findFirst();
if (freeFeature.isPresent() || freeFeatureResource.isPresent()) {
log.warn("free feature found : featureId:{}, featureResourceId:{}",
freeFeature.map(SaasFeature::getId).orElse(null),
freeFeatureResource.map(SaasFeatureResourceResp::getId).orElse(null));
throw new ServiceException("不能查询免授权权限点人员");
}
Set<Long> featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet());
Set<Long> newFeatureIds = saasFeatureResources.stream().map(SaasFeatureResourceResp::getId).collect(Collectors.toSet());
List<FeatureIdPair> featureIdPairs = Lists.newArrayList();
if (!CollectionUtils.isEmpty(featureIds)) {
featureIdPairs.add(FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build());
}
if (!CollectionUtils.isEmpty(newFeatureIds)) {
featureIdPairs.add(FeatureIdPair.builder().featureIds(newFeatureIds).type(NEW_FEATURE).build());
}
WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder()
.workspaceIds(Sets.newHashSet(req.getWorkspaceId()))
.featureIdPairs(featureIdPairs)
.build();
List<SaasProductModuleFeatureRelation> workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam)
.stream()
.map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(workspaceProducts)) {
log.warn("no matched product feature in workspace");
return result;
}
List<ListIdentityFromPermissionResp.UserVO> matchedUsers = getWorkspaceUser(req.getWorkspaceId(), req.getOuId(), workspaceProducts);
if (CollectionUtil.isEmpty(matchedUsers)) {
return result;
}
result.setUsers(matchedUsers);
return result;
}
public List<ListIdentityFromPermissionResp> listWorkspacePermissionIdentityFromDB(WorkspacePermissionIdentityReq req) {
Set<String> newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCodes()));
req.setFeatureCodes(Lists.newArrayList(newFeatureCodes));
//code查询权限点信息
List<SaasFeature> features = permissionPointService.listNodeWithChildrenByCodes(req.getFeatureCodes(), null);
// 兼容新老版本需要通过featureCode查询新版本的features原逻辑是查询当前菜单资源的所有子数据
ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder()
.featureCodes(Sets.newHashSet(req.getFeatureCodes()))
.build();
List<SaasFeatureResourceResp> saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam);
if (CollectionUtil.isEmpty(features) && CollectionUtils.isEmpty(saasFeatureResources)) {
log.warn("no features data found for:{}", req.getFeatureCodes());
return Collections.emptyList();
}
Set<Long> featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet());
Set<Long> newFeatureIds = saasFeatureResources.stream().map(SaasFeatureResourceResp::getId).collect(Collectors.toSet());
List<FeatureIdPair> featureIdPairs = Lists.newArrayList();
if (!CollectionUtils.isEmpty(featureIds)) {
featureIdPairs.add(FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build());
}
if (!CollectionUtils.isEmpty(newFeatureIds)) {
featureIdPairs.add(FeatureIdPair.builder().featureIds(newFeatureIds).type(NEW_FEATURE).build());
}
WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder()
.workspaceIds(Sets.newHashSet(req.getWorkspaceId()))
.featureIdPairs(featureIdPairs)
.build();
List<SaasProductModuleFeatureRelation> workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam)
.stream()
.map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(workspaceProducts)) {
log.warn("no matched feature in workspace product");
return Collections.emptyList();
}
//是否免授权权限点
Set<Long> matchedOldFeatureIds = workspaceProducts.stream()
.filter(e -> Objects.equals(OLD_FEATURE, e.getType()))
.map(SaasProductModuleFeatureRelation::getFeatureId)
.collect(Collectors.toSet());
Optional<SaasFeature> freeFeature = features.stream()
.filter(f -> matchedOldFeatureIds.contains(f.getId()))
.filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType()))
.findAny();
Set<Long> matchedNewFeatureIds = workspaceProducts.stream()
.filter(e -> Objects.equals(NEW_FEATURE, e.getType()))
.map(SaasProductModuleFeatureRelation::getFeatureId)
.collect(Collectors.toSet());
Optional<SaasFeatureResourceResp> freeFeatureResource = saasFeatureResources.stream()
.filter(f -> matchedNewFeatureIds.contains(f.getId()))
.filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType()))
.findFirst();
if (freeFeature.isPresent() || freeFeatureResource.isPresent()) {
throw new ServiceException("免授权权限点调用查人接口");
}
//从相关角色查询用户-超管和普通角色
List<ListIdentityFromPermissionResp.UserVO> users = getWorkspaceUser(req.getWorkspaceId(), null, workspaceProducts);
if (CollectionUtil.isEmpty(users)) {
return Collections.emptyList();
}
//按ou分组返回
List<ListIdentityFromPermissionResp> result = new ArrayList<>();
Map<Long, List<ListIdentityFromPermissionResp.UserVO>> userMap = users.stream()
.collect(Collectors.groupingBy(ListIdentityFromPermissionResp.UserVO::getOuId));
for (Map.Entry<Long, List<ListIdentityFromPermissionResp.UserVO>> entry : userMap.entrySet()) {
result.add(ListIdentityFromPermissionResp.builder()
.workspaceId(req.getWorkspaceId())
.ouId(entry.getKey())
.users(entry.getValue())
.build());
}
return result;
}
}