From c4d0c769735f68d468d1c7b83365d1c249fab6fb Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 19 Aug 2024 16:06:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:(REQ-2699)=20=E4=BF=AE=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=B2=A1=E8=A7=92=E8=89=B2=E6=97=B6=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/controller/PrivateController.java | 395 +++++++++++++++++- .../service/impl/TyrSaasAuthServiceImpl.java | 87 ++-- 2 files changed, 434 insertions(+), 48 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index cee1f2b3..a860ea30 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -10,12 +10,19 @@ import cn.axzo.framework.rocketmq.Event; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; +import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.product.ProductSearchListReq; -import cn.axzo.tyr.client.model.req.*; +import cn.axzo.tyr.client.model.req.CommonDictQueryReq; +import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; +import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; +import cn.axzo.tyr.client.model.req.PageProductFeatureRelationReq; +import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.res.CommonDictResp; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.SaasRoleRes; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.event.outer.CacheWorkspaceProductHandler; @@ -25,8 +32,26 @@ import cn.axzo.tyr.server.job.CacheProductPermissionJob; import cn.axzo.tyr.server.job.CacheRoleFeatureResourceJob; import cn.axzo.tyr.server.job.CacheRolePermissionJob; import cn.axzo.tyr.server.job.CacheSaasFeatureJob; -import cn.axzo.tyr.server.repository.dao.*; -import cn.axzo.tyr.server.repository.entity.*; +import cn.axzo.tyr.server.repository.dao.ProductModuleDao; +import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; +import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; +import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; +import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao; +import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; +import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; +import cn.axzo.tyr.server.repository.dao.SaasRoleDao; +import cn.axzo.tyr.server.repository.dao.SaasRoleGroupDao; +import cn.axzo.tyr.server.repository.dao.SaasRoleGroupRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasFeature; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPageElement; +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.SaasRoleGroupRelation; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.ProductPermissionCacheService; import cn.axzo.tyr.server.service.RolePermissionCacheService; @@ -35,6 +60,7 @@ import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; 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; import cn.axzo.tyr.server.service.WorkspaceProductService; import cn.axzo.tyr.server.service.impl.SaasFeatureResourceCacheService; @@ -44,6 +70,7 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -51,6 +78,7 @@ import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -60,6 +88,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.io.IOException; import java.util.Collection; @@ -68,6 +97,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -135,6 +165,10 @@ public class PrivateController { private SaasPageElementDao saasPageElementDao; @Autowired private SaasPageElementFeatureResourceRelationDao saasPageElementFeatureResourceRelationDao; + @Autowired + private SaasRoleUserRelationService saasRoleUserRelationService; + @Autowired + private ProductModuleDao productModuleDao; /** * 统一层级的roleGroup按照id升序,sort从1递增 @@ -763,6 +797,361 @@ public class PrivateController { // return ApiResult.ok(); } + @PostMapping("/api/private/permission/check") + public ApiResult checkPermission(@RequestBody @Validated CheckPermissionParam request) { + + SaasFeatureResourceService.ListSaasFeatureResourceCache listSaasFeatureResourceCache = SaasFeatureResourceService.ListSaasFeatureResourceCache.builder() + .terminals(Sets.newHashSet(request.getTerminal())) + .build(); + List allFeatures = saasFeatureResourceService.listCache(listSaasFeatureResourceCache).get(request.getTerminal()); + + List roles = listRole(request); + + List productPermissions = listWorkspaceProductPermission(request); + + List products = listProduct(productPermissions); + + Map> rolePermissions = listRolePermission(roles); + + return ApiResult.ok(CheckPermissionDTO.builder() + .products(products) + .roles(roles) + .featureCodeCheckResults(resolveFeatureCode(request, productPermissions, rolePermissions, roles, allFeatures)) + .build()); + } + + private FeatureCodeCheckResult resolveAdminRole(List adminRoles, + List productPermissions) { + if (CollectionUtils.isEmpty(adminRoles)) { + return FeatureCodeCheckResult.builder() + .authPermission(false) + .reasons(Lists.newArrayList("没有管理员角色")) + .build(); + + } + + List reasons = Lists.newArrayList(); + Boolean authPermission = false; + + for (Role adminRole : adminRoles) { + + List adminPermissions = productPermissions.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 FeatureCodeCheckResult.builder() + .authPermission(authPermission) + .reasons(reasons) + .build(); + } + + private FeatureCodeCheckResult resolveNormalRole(List normalRoles, + List productPermissions, + Map> rolePermissions, + String featureCode) { + if (CollectionUtils.isEmpty(normalRoles)) { + return FeatureCodeCheckResult.builder() + .authPermission(false) + .reasons(Lists.newArrayList("没有普通角色")) + .build(); + + } + + List reasons = Lists.newArrayList(); + Boolean authPermission = false; + + for (Role normalRole : normalRoles) { + List normalRolepermissions = rolePermissions.getOrDefault(normalRole.getRoleId(), Lists.newArrayList()) + .stream() + .filter(e -> Objects.equals(e.getFeatureCode(), featureCode)) + .collect(Collectors.toList()); + + Set productCooperateTypes = productPermissions.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 FeatureCodeCheckResult.builder() + .authPermission(authPermission) + .reasons(reasons) + .build(); + } + + private FeatureCodeCheckResult resolveNotAuth(List productPermissions, + String featureCode, + List allFeatures) { + // 直接配置成免授权的权限点 + List notAuthFeatures = allFeatures.stream() + .filter(SaasFeatureResourceService.SaasFeatureResourceCache::isNotAuth) + .collect(Collectors.toList()); + + // 子节点是免授权的权限点 + Set 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 notAuthFeatureIds = notAuthFeatures.stream() + .map(SaasFeatureResourceService.SaasFeatureResourceCache::getFeatureId) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(parentNotAuthFeatureIds) && CollectionUtils.isEmpty(notAuthFeatureIds)) { + return FeatureCodeCheckResult.builder() + .authPermission(false) + .reasons(Lists.newArrayList("没有免授权权限点")) + .build(); + } + + Set productFeatureIds = productPermissions.stream() + .filter(e -> Objects.equals(e.getFeatureCode(), featureCode)) + .map(ProductPermissionCacheService.PermissionDTO::getFeatureId) + .collect(Collectors.toSet()); + + + + if (!Sets.difference(notAuthFeatureIds, productFeatureIds).isEmpty()) { + return FeatureCodeCheckResult.builder() + .authPermission(true) + .reasons(Lists.newArrayList("权限点是免授权")) + .build(); + } else if (!Sets.difference(parentNotAuthFeatureIds, productFeatureIds).isEmpty()) { + return FeatureCodeCheckResult.builder() + .authPermission(true) + .reasons(Lists.newArrayList("权限点的子节点是免授权")) + .build(); + } else { + return FeatureCodeCheckResult.builder() + .authPermission(false) + .reasons(Lists.newArrayList("权限点不是免授权")) + .build(); + } + } + + private List resolveFeatureCode(CheckPermissionParam checkPermissionParam, + List productPermissions, + Map> rolePermissions, + List roles, + List allFeatures) { + Map> productPermissionMap = productPermissions.stream() + .map(WorkspaceProductService.ProductPermission::getPermissions) + .flatMap(Collection::stream) + .collect(Collectors.groupingBy(ProductPermissionCacheService.PermissionDTO::getFeatureCode)); + List adminRoles = roles.stream() + .filter(e -> RoleTypeEnum.isAdmin(e.getRoleType())) + .collect(Collectors.toList()); + + List normalRoles = roles.stream() + .filter(e -> !RoleTypeEnum.isAdmin(e.getRoleType())) + .collect(Collectors.toList()); + + + return checkPermissionParam.getFeatureCodes().stream() + .map(featureCode -> { + List permissions = productPermissionMap.get(featureCode); + if (CollectionUtils.isEmpty(permissions)) { + return FeatureCodeCheckResult.builder() + .featureCode(featureCode) + .authPermission(false) + .reasons(Lists.newArrayList("项目没有配置产品及权限")) + .build(); + } + + FeatureCodeCheckResult adminRoleCheckResult = resolveAdminRole(adminRoles, permissions); + + FeatureCodeCheckResult normalRoleCheckResult = resolveNormalRole(normalRoles, permissions, rolePermissions, featureCode); + + FeatureCodeCheckResult notAuthCheckResult = resolveNotAuth(permissions, featureCode, allFeatures); + + Boolean authPermission = BooleanUtils.isTrue(adminRoleCheckResult.getAuthPermission()) + || BooleanUtils.isTrue(normalRoleCheckResult.getAuthPermission()) + || BooleanUtils.isTrue(notAuthCheckResult.getAuthPermission()); + + List adminRoleReasons = adminRoleCheckResult.getReasons(); + List normalRoleReasons = adminRoleCheckResult.getReasons(); + List notAuthReasons = notAuthCheckResult.getReasons(); + + adminRoleReasons.addAll(normalRoleReasons); + adminRoleReasons.addAll(notAuthReasons); + + return FeatureCodeCheckResult.builder() + .featureCode(featureCode) + .authPermission(authPermission) + .reasons(adminRoleReasons) + .build(); + }) + .collect(Collectors.toList()); + } + + private Map> listRolePermission(List roles) { + + if (CollectionUtils.isEmpty(roles)) { + return Collections.emptyMap(); + } + + RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder() + .roleIds(roles.stream().map(Role::getRoleId).collect(Collectors.toSet())) + .build(); + return rolePermissionCacheService.list(listRolePermissionParam); + } + + private List listProduct(List productPermissions) { + + if (CollectionUtils.isEmpty(productPermissions)) { + return Collections.emptyList(); + } + + List productIds = productPermissions.stream() + .map(WorkspaceProductService.ProductPermission::getProductId) + .collect(Collectors.toList()); + + return productModuleDao.listByIds(productIds).stream() + .filter(productModule -> Objects.equals(productModule.getIsDelete(),0L)) + .map(e -> Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .build()) + .collect(Collectors.toList()); + } + + private List listWorkspaceProductPermission(CheckPermissionParam request) { + WorkspaceProductService.ListWorkspaceProductPermissionCacheParam listWorkspaceProductPermissionCacheParam = WorkspaceProductService.ListWorkspaceProductPermissionCacheParam + .builder() + .workspaceIds(Sets.newHashSet(request.getWorkspaceId())) + .build(); + return workspaceProductService.listWorkspaceProductPermissionCached(listWorkspaceProductPermissionCacheParam).stream() + .map(WorkspaceProductService.WorkspaceProductPermission::getProductPermissions) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + private List 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) + .build(); + + return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() + .filter(e -> e.getSaasRole() != null) + .collect(Collectors.toList()) + .stream() + .map(e -> Role.builder() + .roleId(e.getRoleId()) + .roleName(e.getSaasRole().getName()) + .cooperateType(e.getSaasRole().getProductUnitType()) + .roleType(e.getSaasRole().getRoleType()) + .build()) + .collect(Collectors.toList()); + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class CheckPermissionParam { + + @NotNull(message = "ouId不能为空") + private Long ouId; + + @NotNull(message = "workspaceId不能为空") + private Long workspaceId; + + @NotEmpty(message = "featureCodes不能为空") + private Set featureCodes; + + @NotNull(message = "personId不能为空") + private Long personId; + + @NotBlank(message = "terminal不能为空") + private String terminal; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class CheckPermissionDTO { + + private List products; + + private List roles; + + private List featureCodeCheckResults; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Product { + + private Long productId; + + private String productName; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Role { + + private Long roleId; + + private String roleName; + + private String roleType; + + private Integer cooperateType; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class FeatureCodeCheckResult { + private String featureCode; + + private List reasons; + + private Boolean authPermission; + } + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index d5eea5c0..231c617d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -13,8 +13,6 @@ import cn.axzo.tyr.client.common.enums.WorkspaceJoinType; import cn.axzo.tyr.client.model.enums.DelegatedType; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest; -import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq; import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.client.model.req.IdentityAuthReq; @@ -28,7 +26,6 @@ import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.QueryPermissionByIdsReq; -import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; import cn.axzo.tyr.client.model.req.WorkspacePermissionIdentityReq; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; @@ -39,8 +36,6 @@ 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.client.model.vo.SaasPermissionGroupVO; -import cn.axzo.tyr.client.model.vo.SaasRoleVO; import cn.axzo.tyr.server.model.FilterRoleAuth; import cn.axzo.tyr.server.model.PermissionCacheKey; import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; @@ -75,7 +70,6 @@ import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.service.WorkspaceProductService; import cn.axzo.tyr.server.util.FeatureCodeUtil; import cn.axzo.tyr.server.util.KeyUtil; -import cn.axzo.tyr.server.utils.RpcExternalUtil; import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.utils.LogUtil; import cn.hutool.core.collection.CollectionUtil; @@ -908,59 +902,52 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { * @return KEY :role Id ; VALUE: feature id ; */ public Map> filterAuthByRoleAndProduct(List filterRoleAuths) { - List roleIds = filterRoleAuths.stream().map(FilterRoleAuth::getRoleId).distinct().collect(Collectors.toList()); + Set roleIds = filterRoleAuths.stream().map(FilterRoleAuth::getRoleId).collect(Collectors.toSet()); + RoleService.ListSaasRoleParam listSaasRoleParam = RoleService.ListSaasRoleParam.builder() + .roleIds(Lists.newArrayList(roleIds)) + .build(); + Map roles = roleService.list(listSaasRoleParam).stream() + .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); + RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder() + .roleIds(roleIds) + .build(); + Map> rolePermissions = rolePermissionCacheService.list(listRolePermissionParam); - List query = roleService.query(QuerySaasRoleReq.builder() - .ids(roleIds) - .includePermissionGroup(true) - .build()); - Map roleMap = query.stream().collect(Collectors.toMap(SaasRoleVO::getId, Function.identity(), (a, b) -> a)); // find product by workspace Set workspaceId = filterRoleAuths.stream().map(FilterRoleAuth::getWorkspaceId).collect(Collectors.toSet()); - List servicePkgDetailRes = RpcExternalUtil.rpcProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(workspaceId), "find product ", workspaceId); - Map> workspaceMap = servicePkgDetailRes.stream().collect(Collectors.toMap(ServicePkgDetailRes::getSpaceId, ServicePkgDetailRes::getProducts, (a, b) -> a)); - // find permission point by product - List productIds = servicePkgDetailRes.stream().map(ServicePkgDetailRes::getProducts).flatMap(List::stream).map(ServicePkgProduct::getProductId).distinct().collect(Collectors.toList()); - List productsDetail = RpcExternalUtil.rpcApiResultProcessor(() -> productFeatureRelationService.featureListByProduct(productIds), " find permission point by product ", productIds); - Map>> productGroup = productsDetail.stream().collect(Collectors.groupingBy(ProductFeatureRelationVO::getProductModuleId, Collectors.groupingBy(ProductFeatureRelationVO::getDictCode))); - - Map featureRelationVoMap = productsDetail.stream().collect(Collectors.toMap(ProductFeatureRelationVO::getFeatureId, Function.identity(), (v1, v2) -> v1)); + WorkspaceProductService.ListWorkspaceProductPermissionCacheParam listWorkspaceProductPermission = WorkspaceProductService.ListWorkspaceProductPermissionCacheParam.builder() + .workspaceIds(workspaceId) + .build(); + Map> workspaceProductPermissions = workspaceProductService.listWorkspaceProductPermissionCached(listWorkspaceProductPermission) + .stream() + .collect(Collectors.toMap(WorkspaceProductService.WorkspaceProductPermission::getWorkspaceId, + WorkspaceProductService.WorkspaceProductPermission::getProductPermissions)); // intersection auth from role and product Map> map = filterRoleAuths.stream().collect(Collectors.toMap(FilterRoleAuth::getRoleId, e -> { Long roleId = e.getRoleId(); - SaasRoleVO saasRole = roleMap.get(e.getRoleId()); + SaasRoleRes saasRole = roles.get(e.getRoleId()); if (null == saasRole) { LogUtil.error(" find role info error,role id:{}", roleId); return Collections.emptySet(); } + Set rolePermissionIds = rolePermissions.get(roleId) + .stream() + .map(RolePermissionCacheService.PermissionDTO::getFeatureId) + .collect(Collectors.toSet()); - List servicePkgProducts = workspaceMap.get(e.getWorkspaceId()); - Set allFeatureIds = servicePkgProducts.stream().map(ServicePkgProduct::getProductId).distinct().map(productId -> - { + Set productPermissionIds = workspaceProductPermissions.get(e.getWorkspaceId()).stream() + .map(WorkspaceProductService.ProductPermission::getPermissions) + .flatMap(Collection::stream) + .filter(productPermission -> Objects.equals(productPermission.getCooperateType(), String.valueOf(saasRole.getProductUnitType()))) + .map(ProductPermissionCacheService.PermissionDTO::getFeatureId) + .collect(Collectors.toSet()); - Map> productUnitMap = productGroup.get(productId); - if (null == productUnitMap) { - return null; - } - List productFeatureRelationVO = productUnitMap.get(String.valueOf(saasRole.getProductUnitType())); - if (CollectionUtil.isEmpty(productFeatureRelationVO)) { - return null; - } - - return productFeatureRelationVO.stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toSet()); - } - ).filter(Objects::nonNull).flatMap(Set::stream).collect(Collectors.toSet()); - - - List currentPermissionId = saasRole.getPermissionGroup().stream().map(SaasPermissionGroupVO::getFeature).flatMap(List::stream).map(PermissionPointTreeNode::getPermissionPointId).distinct().collect(Collectors.toList()); - - - return new HashSet<>(CollectionUtil.intersection(allFeatureIds, currentPermissionId)); + return new HashSet<>(CollectionUtil.intersection(productPermissionIds, rolePermissionIds)); }, (oldFeatureLists, newFeatureLists) -> { @@ -972,7 +959,10 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { for (Map.Entry> entry : map.entrySet()) { Set featureInfos = org.apache.commons.collections4.CollectionUtils.emptyIfNull(entry.getValue()).stream().map(e -> ListPermissionFromRoleGroupResp.FeatureInfo.builder() .featureId(e) - .relationType(Optional.ofNullable(featureRelationVoMap.get(e)).map(ProductFeatureRelationVO::getType).orElse(null)) + // 因为CMS、CMP端saas_feature_resouce表的id从100000开始自增 + // 不会跟saas_feature有冲突,项企分离后,旧的saas_feature表不会再使用,所以这里直接根据featureId < 100000 + // 来判断relationType是saas_feature还是saas_feature_resource,不增加到缓存里是减少io量 + .relationType(e < 100000 ? OLD_FEATURE : NEW_FEATURE) .build()).collect(Collectors.toSet()); featureMap.put(entry.getKey(), featureInfos); } @@ -1545,6 +1535,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { List saasRoles = workspaceRoles.get(workspaceOuPair.buildOuWorkspaceKey()); + if (CollectionUtils.isEmpty(saasRoles)) { + return IdentityAuthRes.WorkspacePermission.builder() + .workspaceId(workspaceOuPair.getWorkspaceId()) + .ouId(workspaceOuPair.getOuId()) + .build(); + } + return buildPermissionsV2(workspaceOuPair, productPermissions, saasRoles, rolePermissions, allFeatures); }) .collect(Collectors.toList()); @@ -1646,10 +1643,10 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private Set buildNoAuthPermission(List productPermissions, - List allFeatuers) { + List allFeatures) { // 因为有权授权权限的权限点,就需要有所有上层权限点的权限 - Set notAuthFeatureIds = allFeatuers.stream() + Set notAuthFeatureIds = allFeatures.stream() .filter(SaasFeatureResourceService.SaasFeatureResourceCache::isNotAuth) .map(e -> Optional.ofNullable(e.getParentIds()) .map(f -> {