feat:(REQ-2699) 新增菜单编码权限的check接口

This commit is contained in:
lilong 2024-08-29 11:27:30 +08:00
parent 38e711217c
commit ec757f3ed1

View File

@ -55,7 +55,9 @@ import cn.axzo.tyr.server.repository.entity.SaasRoleGroup;
import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation;
import cn.axzo.tyr.server.service.ProductFeatureRelationService;
import cn.axzo.tyr.server.service.ProductPermissionCacheService;
import cn.axzo.tyr.server.service.ProductSaasFeatureResourceCacheService;
import cn.axzo.tyr.server.service.RolePermissionCacheService;
import cn.axzo.tyr.server.service.RoleSaasFeatureResourceCacheService;
import cn.axzo.tyr.server.service.RoleService;
import cn.axzo.tyr.server.service.SaasCommonDictService;
import cn.axzo.tyr.server.service.SaasFeatureResourceService;
@ -172,6 +174,8 @@ public class PrivateController {
private ProductModuleDao productModuleDao;
@Autowired
private CacheWorkspaceProductJob cacheWorkspaceProductJob;
@Autowired
private RoleSaasFeatureResourceCacheService roleSaasFeatureResourceCacheService;
/**
* 统一层级的roleGroup按照id升序sort从1递增
@ -820,11 +824,21 @@ public class PrivateController {
.build();
List<SaasFeatureResourceService.SaasFeatureResourceCache> allFeatures = saasFeatureResourceService.listCache(listSaasFeatureResourceCache).get(request.getTerminal());
List<Role> roles = listRole(request);
List<Role> roles = listRole(ListRoleUserRelationParam.builder()
.personId(request.getPersonId())
.workspaceOuPairs(Lists.newArrayList(ListRoleUserRelationParam.WorkspaceOuPair.builder()
.workspaceId(request.getWorkspaceId())
.ouId(request.getOuId())
.build()))
.needRole(true)
.build());
List<WorkspaceProductService.ProductPermission> productPermissions = listWorkspaceProductPermission(request);
List<Product> products = listProduct(productPermissions);
List<Long> productIds = productPermissions.stream()
.map(WorkspaceProductService.ProductPermission::getProductId)
.collect(Collectors.toList());
List<Product> products = listProduct(productIds);
Map<Long, List<RolePermissionCacheService.PermissionDTO>> rolePermissions = listRolePermission(roles);
@ -835,6 +849,75 @@ public class PrivateController {
.build());
}
@PostMapping("/api/private/featureResource/check")
public ApiResult<CheckFeatureResourceDTO> checkFeatureResource(@RequestBody @Validated CheckFeatureResourceParam request) {
SaasFeatureResourceService.ListSaasFeatureResourceCache listSaasFeatureResourceCache = SaasFeatureResourceService.ListSaasFeatureResourceCache.builder()
.terminals(Sets.newHashSet(request.getTerminal()))
.build();
List<SaasFeatureResourceService.SaasFeatureResourceCache> allFeatures = saasFeatureResourceService.listCache(listSaasFeatureResourceCache).get(request.getTerminal());
List<Role> roles = listRole(ListRoleUserRelationParam.builder()
.personId(request.getPersonId())
.workspaceOuPairs(Lists.newArrayList(ListRoleUserRelationParam.WorkspaceOuPair.builder()
.workspaceId(request.getWorkspaceId())
.ouId(request.getOuId())
.build()))
.needRole(true)
.build());
List<WorkspaceProductService.ProductFeatureSource> productFeatureSources = listWorkspaceProductFeatureResource(request);
List<Long> productIds = productFeatureSources.stream()
.map(WorkspaceProductService.ProductFeatureSource::getProductId)
.collect(Collectors.toList());
List<Product> products = listProduct(productIds);
Map<Long, List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO>> roleFeatureResources = listRoleFeatureResource(roles);
return ApiResult.ok(CheckFeatureResourceDTO.builder()
.products(products)
.roles(roles)
.uniCodeCheckResults(resolveUniCode(request, productFeatureSources, roleFeatureResources, roles, allFeatures))
.build());
}
private UniCodeCheckResult resolveAdminRoleFeature(List<Role> adminRoles,
List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> productFeatureResources) {
if (CollectionUtils.isEmpty(adminRoles)) {
return UniCodeCheckResult.builder()
.authPermission(false)
.reasons(Lists.newArrayList("没有管理员角色"))
.build();
}
List<String> reasons = Lists.newArrayList();
Boolean authPermission = false;
for (Role adminRole : adminRoles) {
List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> adminPermissions = productFeatureResources.stream()
.filter(e -> Objects.equals(e.getCooperateType(), adminRole.getCooperateType().toString()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(adminPermissions)) {
reasons.add("角色Id:" + adminRole.getRoleId()
+ ";角色名字:" + adminRole.getRoleName()
+ ";单位类型:" + adminRole.getCooperateType() + ";是管理员角色有该权限code权限");
authPermission = true;
} else {
reasons.add("角色Id:" + adminRole.getRoleId()
+ ";角色名字:" + adminRole.getRoleName()
+ ";单位类型:" + adminRole.getCooperateType() + ";没有该权限code权限");
}
}
return UniCodeCheckResult.builder()
.authPermission(authPermission)
.reasons(reasons)
.build();
}
private FeatureCodeCheckResult resolveAdminRole(List<Role> adminRoles,
List<ProductPermissionCacheService.PermissionDTO> productPermissions) {
if (CollectionUtils.isEmpty(adminRoles)) {
@ -919,6 +1002,54 @@ public class PrivateController {
.build();
}
private UniCodeCheckResult resolveNormalRoleFeature(List<Role> normalRoles,
List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> productFeatureResources,
Map<Long, List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO>> rolePermissions,
String uniCode) {
if (CollectionUtils.isEmpty(normalRoles)) {
return UniCodeCheckResult.builder()
.authPermission(false)
.reasons(Lists.newArrayList("没有普通角色"))
.build();
}
List<String> reasons = Lists.newArrayList();
Boolean authPermission = false;
for (Role normalRole : normalRoles) {
List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO> normalRolepermissions = rolePermissions.getOrDefault(normalRole.getRoleId(), Lists.newArrayList())
.stream()
.filter(e -> Objects.equals(e.getUniCode(), uniCode))
.collect(Collectors.toList());
Set<String> productCooperateTypes = productFeatureResources.stream()
.map(e -> e.getCooperateType())
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(normalRolepermissions)) {
reasons.add("角色Id:" + normalRole.getRoleId()
+ ";角色名字:" + normalRole.getRoleName()
+ ";单位类型:" + normalRole.getCooperateType() + ";没有该权限code权限");
} else if (productCooperateTypes.contains(normalRole.getCooperateType().toString())) {
reasons.add("角色Id:" + normalRole.getRoleId()
+ ";角色名字:" + normalRole.getRoleName()
+ ";单位类型:" + normalRole.getCooperateType() + ";有该权限code权限;有该权限的产品的单位类型有"
+ JSON.toJSONString(productCooperateTypes));
authPermission = true;
} else {
reasons.add("角色Id:" + normalRole.getRoleId()
+ ";角色名字:" + normalRole.getRoleName()
+ ";单位类型:" + normalRole.getCooperateType() + ";有该权限code权限;有该权限的产品的单位类型有"
+ JSON.toJSONString(productCooperateTypes));
}
}
return UniCodeCheckResult.builder()
.authPermission(authPermission)
.reasons(reasons)
.build();
}
private FeatureCodeCheckResult resolveNotAuth(List<ProductPermissionCacheService.PermissionDTO> productPermissions,
String featureCode,
List<SaasFeatureResourceService.SaasFeatureResourceCache> allFeatures) {
@ -974,6 +1105,61 @@ public class PrivateController {
}
}
private UniCodeCheckResult resolveNotAuthFeature(List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> productFeatureResources,
String uniCode,
List<SaasFeatureResourceService.SaasFeatureResourceCache> allFeatures) {
// 直接配置成免授权的权限点
List<SaasFeatureResourceService.SaasFeatureResourceCache> notAuthFeatures = allFeatures.stream()
.filter(SaasFeatureResourceService.SaasFeatureResourceCache::isNotAuth)
.collect(Collectors.toList());
// 子节点是免授权的权限点
Set<Long> parentNotAuthFeatureIds = notAuthFeatures.stream()
.map(e -> Optional.ofNullable(e.getParentIds())
.map(f -> {
f.add(e.getFeatureId());
return f;
})
.orElseGet(() -> Sets.newHashSet(e.getFeatureId())))
.flatMap(Collection::stream)
.collect(Collectors.toSet());
Set<Long> notAuthFeatureIds = notAuthFeatures.stream()
.map(SaasFeatureResourceService.SaasFeatureResourceCache::getFeatureId)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(parentNotAuthFeatureIds) && CollectionUtils.isEmpty(notAuthFeatureIds)) {
return UniCodeCheckResult.builder()
.authPermission(false)
.reasons(Lists.newArrayList("没有免授权权限点"))
.build();
}
Set<Long> productFeatureIds = productFeatureResources.stream()
.filter(e -> Objects.equals(e.getUniCode(), uniCode))
.map(ProductSaasFeatureResourceCacheService.FeatureResourceDTO::getFeatureId)
.collect(Collectors.toSet());
if (!Sets.intersection(notAuthFeatureIds, productFeatureIds).isEmpty()) {
return UniCodeCheckResult.builder()
.authPermission(true)
.reasons(Lists.newArrayList("权限点是免授权"))
.build();
} else if (!Sets.intersection(parentNotAuthFeatureIds, productFeatureIds).isEmpty()) {
return UniCodeCheckResult.builder()
.authPermission(true)
.reasons(Lists.newArrayList("权限点的子节点是免授权"))
.build();
} else {
return UniCodeCheckResult.builder()
.authPermission(false)
.reasons(Lists.newArrayList("权限点不是免授权"))
.build();
}
}
private List<FeatureCodeCheckResult> resolveFeatureCode(CheckPermissionParam checkPermissionParam,
List<WorkspaceProductService.ProductPermission> productPermissions,
Map<Long, List<RolePermissionCacheService.PermissionDTO>> rolePermissions,
@ -1037,6 +1223,68 @@ public class PrivateController {
.collect(Collectors.toList());
}
private List<UniCodeCheckResult> resolveUniCode(CheckFeatureResourceParam checkFeatureResourceParam,
List<WorkspaceProductService.ProductFeatureSource> productFeatureSources,
Map<Long, List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO>> roleFeatureResources,
List<Role> roles,
List<SaasFeatureResourceService.SaasFeatureResourceCache> allFeatures) {
Map<String, List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO>> productFeatureResourceMap = productFeatureSources.stream()
.map(WorkspaceProductService.ProductFeatureSource::getFeatureResources)
.flatMap(Collection::stream)
.collect(Collectors.groupingBy(ProductSaasFeatureResourceCacheService.FeatureResourceDTO::getUniCode));
List<Role> adminRoles = roles.stream()
.filter(e -> RoleTypeEnum.isAdmin(e.getRoleType()))
.collect(Collectors.toList());
List<Role> normalRoles = roles.stream()
.filter(e -> !RoleTypeEnum.isAdmin(e.getRoleType()))
.collect(Collectors.toList());
return checkFeatureResourceParam.getUniCodes().stream()
.map(uniCode -> {
List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> featureResources = productFeatureResourceMap.get(uniCode);
if (CollectionUtils.isEmpty(featureResources)) {
return UniCodeCheckResult.builder()
.uniCode(uniCode)
.authPermission(false)
.reasons(Lists.newArrayList("项目没有配置产品及权限"))
.build();
}
if (CollectionUtils.isEmpty(roles)) {
return UniCodeCheckResult.builder()
.uniCode(uniCode)
.authPermission(false)
.reasons(Lists.newArrayList("用户在项目里没有任何角色"))
.build();
}
UniCodeCheckResult adminRoleCheckResult = resolveAdminRoleFeature(adminRoles, featureResources);
UniCodeCheckResult normalRoleCheckResult = resolveNormalRoleFeature(normalRoles, featureResources, roleFeatureResources, uniCode);
UniCodeCheckResult notAuthCheckResult = resolveNotAuthFeature(featureResources, uniCode, allFeatures);
Boolean authPermission = BooleanUtils.isTrue(adminRoleCheckResult.getAuthPermission())
|| BooleanUtils.isTrue(normalRoleCheckResult.getAuthPermission())
|| BooleanUtils.isTrue(notAuthCheckResult.getAuthPermission());
List<String> adminRoleReasons = adminRoleCheckResult.getReasons();
List<String> normalRoleReasons = normalRoleCheckResult.getReasons();
List<String> notAuthReasons = notAuthCheckResult.getReasons();
adminRoleReasons.addAll(normalRoleReasons);
adminRoleReasons.addAll(notAuthReasons);
return UniCodeCheckResult.builder()
.uniCode(uniCode)
.authPermission(authPermission)
.reasons(adminRoleReasons)
.build();
})
.collect(Collectors.toList());
}
private Map<Long, List<RolePermissionCacheService.PermissionDTO>> listRolePermission(List<Role> roles) {
if (CollectionUtils.isEmpty(roles)) {
@ -1049,15 +1297,23 @@ public class PrivateController {
return rolePermissionCacheService.list(listRolePermissionParam);
}
private List<Product> listProduct(List<WorkspaceProductService.ProductPermission> productPermissions) {
private Map<Long, List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO>> listRoleFeatureResource(List<Role> roles) {
if (CollectionUtils.isEmpty(productPermissions)) {
return Collections.emptyList();
if (CollectionUtils.isEmpty(roles)) {
return Collections.emptyMap();
}
List<Long> productIds = productPermissions.stream()
.map(WorkspaceProductService.ProductPermission::getProductId)
.collect(Collectors.toList());
RoleSaasFeatureResourceCacheService.ListRoleSaasFeatureResourceParam listRolePermissionParam = RoleSaasFeatureResourceCacheService.ListRoleSaasFeatureResourceParam.builder()
.roleIds(roles.stream().map(Role::getRoleId).collect(Collectors.toSet()))
.build();
return roleSaasFeatureResourceCacheService.list(listRolePermissionParam);
}
private List<Product> listProduct(List<Long> productIds) {
if (CollectionUtils.isEmpty(productIds)) {
return Collections.emptyList();
}
return productModuleDao.listByIds(productIds).stream()
.filter(productModule -> Objects.equals(productModule.getIsDelete(),0L))
@ -1079,16 +1335,18 @@ public class PrivateController {
.collect(Collectors.toList());
}
private List<Role> listRole(CheckPermissionParam request) {
ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder()
.personId(request.getPersonId())
.workspaceOuPairs(Lists.newArrayList(ListRoleUserRelationParam.WorkspaceOuPair.builder()
.workspaceId(request.getWorkspaceId())
.ouId(request.getOuId())
.build()))
.needRole(true)
private List<WorkspaceProductService.ProductFeatureSource> listWorkspaceProductFeatureResource(CheckFeatureResourceParam request) {
WorkspaceProductService.ListWorkspaceProductFeatureSourceCacheParam listWorkspaceProductFeatureSourceCacheParam = WorkspaceProductService.ListWorkspaceProductFeatureSourceCacheParam
.builder()
.workspaceIds(Sets.newHashSet(request.getWorkspaceId()))
.build();
return workspaceProductService.listWorkspaceProductFeatureResourceCached(listWorkspaceProductFeatureSourceCacheParam).stream()
.map(WorkspaceProductService.WorkspaceProductFeatureSource::getProductFeatureSources)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
private List<Role> listRole(ListRoleUserRelationParam listRoleUserRelationParam) {
return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream()
.filter(e -> e.getSaasRole() != null)
.collect(Collectors.toList())
@ -1124,6 +1382,28 @@ public class PrivateController {
private String terminal;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CheckFeatureResourceParam {
@NotNull(message = "ouId不能为空")
private Long ouId;
@NotNull(message = "workspaceId不能为空")
private Long workspaceId;
@NotEmpty(message = "uniCodes不能为空")
private Set<String> uniCodes;
@NotNull(message = "personId不能为空")
private Long personId;
@NotBlank(message = "terminal不能为空")
private String terminal;
}
@Data
@Builder
@NoArgsConstructor
@ -1137,6 +1417,19 @@ public class PrivateController {
private List<FeatureCodeCheckResult> featureCodeCheckResults;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CheckFeatureResourceDTO {
private List<Product> products;
private List<Role> roles;
private List<UniCodeCheckResult> uniCodeCheckResults;
}
@Data
@Builder
@NoArgsConstructor
@ -1175,6 +1468,18 @@ public class PrivateController {
private Boolean authPermission;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class UniCodeCheckResult {
private String uniCode;
private List<String> reasons;
private Boolean authPermission;
}
@Data
@Builder
@NoArgsConstructor