diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java index 16788bd8..fa255b3e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java @@ -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; @@ -8,6 +9,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.util.Set; /** * @author likunpeng @@ -42,4 +44,9 @@ public class GetUserHasPermissionPageElementReq { @NotNull(message = "租户ID不能为空") @Min(value = 1, message = "租户ID有误") private Long workspaceId; + + /** + * 权限标签,默认是根据personId在当前项目的状态解析的 + */ + private Set tags; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java index 37a731f9..3c01026d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java @@ -5,11 +5,11 @@ import cn.axzo.framework.rocketmq.Event; import cn.axzo.maokai.common.enums.SaasCooperateShipCooperateTypeEnum; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum; +import cn.axzo.tyr.client.model.enums.PermissionGroupType; import cn.axzo.tyr.client.model.enums.PermissionType; import cn.axzo.tyr.client.model.enums.WorkspaceTypeCodeEnum; import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.req.ListSaasRoleGroupParam; -import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; @@ -21,10 +21,11 @@ import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.RolePermissionCreatedPayload; -import cn.axzo.tyr.server.model.ResourcePermission; +import cn.axzo.tyr.server.repository.dao.SaasPermissionGroupDao; import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; import cn.axzo.tyr.server.repository.dao.SaasRoleDao; import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasPermissionGroup; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation; import cn.axzo.tyr.server.repository.entity.SaasRole; @@ -47,6 +48,7 @@ import com.alibaba.excel.metadata.CellExtra; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.common.collect.Streams; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -105,6 +107,8 @@ public class PrivateRoleController { private SaasPgroupRoleRelationDao saasPgroupRoleRelationDao; @Autowired private MqProducer mqProducer; + @Autowired + private SaasPermissionGroupDao saasPermissionGroupDao; private static final String TARGET_TYPE = "saasFeatureResourceId"; @@ -664,6 +668,66 @@ public class PrivateRoleController { return "ok"; } + @PostMapping("/api/private/superAdmin/pgroupPermission/init") + public Object createSuperAdminPgroupPermission() { + ListRoleReq listRoleReq = ListRoleReq.builder() + .roleTypes(Lists.newArrayList(RoleTypeEnum.SUPER_ADMIN.getValue())) + .build(); + + List allSuperAdminRoles = roleService.list(listRoleReq).stream() + .filter(e -> e.getWorkspaceId() == 0L) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(allSuperAdminRoles)) { + return "ok"; + } + + Set hasRoleIds = saasPgroupRoleRelationDao.lambdaQuery() + .in(SaasPgroupRoleRelation::getRoleId, Lists.transform(allSuperAdminRoles, SaasRoleRes::getId)) + .list() + .stream() + .map(SaasPgroupRoleRelation::getRoleId) + .collect(Collectors.toSet()); + + List initRoles = allSuperAdminRoles.stream() + .filter(role -> !hasRoleIds.contains(role.getId())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(initRoles)) { + return "ok"; + } + + List saasPermissionGroups = initRoles.stream() + .map(role -> { + SaasPermissionGroup saasPermissionGroup = new SaasPermissionGroup(); + saasPermissionGroup.setName("通用权限"); + saasPermissionGroup.setIsCommon(PermissionGroupType.COMMON.getCode()); + saasPermissionGroup.setCreateBy(154587L); + saasPermissionGroup.setCreatorName("王今"); + saasPermissionGroup.setUpdateBy(154587L); + saasPermissionGroup.setUpdatorName("王今"); + saasPermissionGroup.setType("feature"); + return saasPermissionGroup; + }) + .collect(Collectors.toList()); + + saasPermissionGroupDao.saveBatch(saasPermissionGroups); + + List saasPgroupRoleRelations = Streams.zip(initRoles.stream(), saasPermissionGroups.stream(), + (role, pgroup) -> { + SaasPgroupRoleRelation saasPgroupRoleRelation = new SaasPgroupRoleRelation(); + saasPgroupRoleRelation.setRoleId(role.getId()); + saasPgroupRoleRelation.setGroupId(pgroup.getId()); + saasPgroupRoleRelation.setCreateBy(154587L); + saasPgroupRoleRelation.setUpdateBy(154587L); + saasPgroupRoleRelation.setCreateAt(new Date()); + saasPgroupRoleRelation.setUpdateAt(new Date()); + return saasPgroupRoleRelation; + }) + .collect(Collectors.toList()); + saasPgroupRoleRelationDao.saveBatch(saasPgroupRoleRelations); + return "ok"; + } + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java index fffb5cbd..8f4ba3bf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java @@ -25,8 +25,4 @@ public class FilterRoleAuth { private Long roleId; private Long workspaceId; - - private Long ouId; - - private Set tags; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionTagService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionTagService.java new file mode 100644 index 00000000..a4f07a0d --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionTagService.java @@ -0,0 +1,53 @@ +package cn.axzo.tyr.server.service; + +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +public interface PermissionTagService { + + List resolvePermissionTag(ResolvePermissionTagParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ResolvePermissionTagParam { + + private List personPermissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class PersonPermission { + + private Long workspaceId; + + private Long ouId; + + private Long personId; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ResolvePermissionDTO { + + private Long workspaceId; + + private Long ouId; + + private Long personId; + + private Set tags; + } +} + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 1aba5c12..08bba6c7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -48,6 +48,7 @@ import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.service.PermissionQueryService; +import cn.axzo.tyr.server.service.PermissionTagService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.ProductSaasFeatureResourceCacheService; import cn.axzo.tyr.server.service.RoleSaasFeatureResourceCacheService; @@ -109,6 +110,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final SaasRoleUserRelationService saasRoleUserRelationService; private final WorkspaceProductService workspaceProductService; private final RoleSaasFeatureResourceCacheService roleSaasFeatureResourceCacheService; + private final PermissionTagService permissionTagService; @Value("${not.auth.uniCodes:}") private Set notAuthUniCodes; @@ -715,6 +717,46 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .orElse(Collections.emptyList()); } + private void assembleTag(TreePermissionReq treePermissionReq) { + + if (CollectionUtils.isEmpty(treePermissionReq.getWorkspaceOUPairs())) { + return; + } + + List needResolveTags = treePermissionReq.getWorkspaceOUPairs().stream() + .filter(e -> CollectionUtils.isEmpty(e.getTags())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(needResolveTags)) { + return; + } + + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(needResolveTags.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(treePermissionReq.getPersonId()) + .build()) + .collect(Collectors.toList())) + .build(); + Map resolvePermissions = permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(e -> e.getOuId() + "_" + e.getWorkspaceId(), Function.identity())); + + treePermissionReq.getWorkspaceOUPairs().forEach(e -> { + if (CollectionUtils.isNotEmpty(e.getTags())) { + return; + } + + PermissionTagService.ResolvePermissionDTO resolvePermissionDTO = resolvePermissions.get(e.buildKey()); + if (Objects.isNull(resolvePermissionDTO)) { + return; + } + + e.setTags(resolvePermissionDTO.getTags()); + }); + } + /** * 用户可能只有子节点的权限,但是要构建这个菜单树,所以需要先查询这个端的所有菜单,然后根据用户的权限找到对应的父节点构建树 * @param treePermissionReq @@ -728,6 +770,8 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return Collections.emptySet(); } + assembleTag(treePermissionReq); + List saasRoleUsers = listUserPermission(treePermissionReq); if (CollectionUtils.isEmpty(saasRoleUsers)) { return Collections.emptySet(); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionTagServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionTagServiceImpl.java new file mode 100644 index 00000000..8c0eecdd --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionTagServiceImpl.java @@ -0,0 +1,85 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.maokai.api.client.OrgUserApi; +import cn.axzo.maokai.api.vo.request.OrgUserListReq; +import cn.axzo.maokai.api.vo.request.WorkspaceOuPair; +import cn.axzo.maokai.api.vo.response.OrgUserRes; +import cn.axzo.maokai.common.enums.OrgUserStatusEnum; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; +import cn.axzo.tyr.server.service.PermissionTagService; +import cn.axzo.tyr.server.utils.RpcInternalUtil; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Sets; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class PermissionTagServiceImpl implements PermissionTagService { + + @Autowired + private OrgUserApi orgUserApi; + + private static final Map ORG_USER_TAGS = Maps.newHashMap(); + + static { + // 除了用户在项目下是离场状态要取离场权限,其他为了兼容都取在场权限,因为人岗架可能会新增状态,其他删除这些状态会删除用户角色 + ORG_USER_TAGS.put(OrgUserStatusEnum.LEAVE, RolePermissionTagEnum.LEAVE); + } + + @Override + public List resolvePermissionTag(ResolvePermissionTagParam param) { + + if (CollectionUtils.isEmpty(param.getPersonPermissions())) { + return Collections.emptyList(); + } + + List personIds = param.getPersonPermissions().stream() + .map(PersonPermission::getPersonId) + .collect(Collectors.toList()); + List workspaceOuPairs = param.getPersonPermissions().stream() + .map(e -> WorkspaceOuPair.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .build()) + .collect(Collectors.toList()); + + // 因为底层接口实现没有根据personId和workspaceOu去匹配查询,可能会多返回数据,所以这里要过滤 + OrgUserListReq orgUserListReq = OrgUserListReq.builder() + .personIds(personIds) + .ouWorkspacePairs(workspaceOuPairs) + .build(); + + List orgUserRes = RpcInternalUtil.rpcApiListResultProcessor(() -> orgUserApi.listOrgUser(orgUserListReq), + "查询人员在项目的状态", orgUserListReq).getData(); + + if (CollectionUtils.isEmpty(orgUserRes)) { + return Collections.emptyList(); + } + + Set keys = param.getPersonPermissions().stream() + .map(e -> e.getOuId() + "_" + e.getWorkspaceId() + "_" + e.getPersonId()) + .collect(Collectors.toSet()); + + return orgUserRes.stream() + .filter(e -> keys.contains(e.getOuId() + "_" + e.getWorkspaceId() + "_" + e.getPersonId())) + .map(e -> ResolvePermissionDTO.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(e.getPersonId()) + .tags(Optional.ofNullable(ORG_USER_TAGS.get(e.getStatus())) + .map(Sets::newHashSet) + .orElseGet(() -> Sets.newHashSet(RolePermissionTagEnum.JOINED))) + .build()) + .collect(Collectors.toList()); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index a9a68965..4ef95240 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -318,9 +318,15 @@ public class SaasPageElementServiceImpl extends ServiceImpl workspaceOuPairs = Lists.newArrayList(IdentityAuthReq.WorkspaceOuPair.builder() + .ouId(request.getOuId()) + .workspaceId(request.getWorkspaceId()) + .tags(request.getTags()) + .build()); + IdentityAuthRes res = tyrSaasAuthService.findIdentityAuthMix(IdentityAuthReq.builder() .personId(request.getPersonId()) - .workspaceOusPairs(Lists.newArrayList(IdentityAuthReq.WorkspaceOuPair.builder().ouId(request.getOuId()).workspaceId(request.getWorkspaceId()).build())) + .workspaceOusPairs(workspaceOuPairs) .terminal(Lists.newArrayList(request.getTerminal())) .featureCode(resultRelations.stream().map(SaasPageElementFeatureResourceRelation::getPageElementCode).collect(Collectors.toSet())) .build()); 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 08d7b461..0e1fe78f 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 @@ -42,6 +42,7 @@ import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper; import cn.axzo.tyr.server.repository.mapper.TyrSaasAuthMapper; import cn.axzo.tyr.server.service.PermissionPointService; +import cn.axzo.tyr.server.service.PermissionTagService; import cn.axzo.tyr.server.service.ProductPermissionCacheService; import cn.axzo.tyr.server.service.RolePermissionCacheService; import cn.axzo.tyr.server.service.RoleService; @@ -68,6 +69,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -124,6 +126,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private final FeatureCodeUtil featureCodeUtil; private final RolePermissionCacheService rolePermissionCacheService; private final SaasRoleUserRelationMapper saasRoleUserRelationMapper; + private final PermissionTagService permissionTagService; /** * 通过身份查询人员权限 @@ -539,7 +542,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private Set resolvePermissionAdminLeaveRole(List adminRoles, List productPermissions, ListPermissionUser listPermissionUser, - Set featureIds) { + Set featureIds, + Map> allRolePermissionMap) { if (CollectionUtil.isEmpty(adminRoles)) { log.info("no admin roles"); @@ -557,7 +561,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .map(ProductPermissionCacheService.PermissionDTO::getFeatureCode) .collect(Collectors.toSet())) .build(); - Map> adminRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam); + Map> adminRolePermissionMap = adminRoles.stream() + .filter(e -> allRolePermissionMap.containsKey(e.getId())) + .collect(Collectors.toMap(SaasRoleRes::getId, e -> allRolePermissionMap.get(e.getId()))); Set adminRoleIds = adminRolePermissionMap.entrySet().stream() .filter(e -> !CollectionUtils.isEmpty(e.getValue())) @@ -598,7 +604,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private Set resolvePermissionNormalRole(List allRoles, ListPermissionUser req, List productPermissions, - Set featureIds) { + Set featureIds, + Map> allRolePermissionMap) { List normalRoles = allRoles.stream() .filter(e -> !RoleTypeEnum.isAdmin(e.getRoleType())) @@ -615,13 +622,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .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> normalRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam); + Map> normalRolePermissionMap = normalRoleMap.entrySet().stream() + .filter(e -> allRolePermissionMap.containsKey(e.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, e -> allRolePermissionMap.get(e.getKey()))); return normalRolePermissionMap.entrySet().stream() .filter(e -> !CollectionUtils.isEmpty(e.getValue())) @@ -665,14 +668,22 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Collections.emptyList(); } + RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder() + .roleIds(allRoleIds) + .featureCodes(productPermissions.stream() + .map(ProductPermissionCacheService.PermissionDTO::getFeatureCode) + .collect(Collectors.toSet())) + .build(); + Map> allRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam); + //超管和管理员 List adminRoles = allRoles.stream() .filter(e -> RoleTypeEnum.isAdmin(e.getRoleType())) .collect(Collectors.toList()); Set adminPermissionRoleIds = resolvePermissionAdminRole(adminRoles, productPermissions, req); - Set normalPermissionRoleIds = resolvePermissionNormalRole(allRoles, req, productPermissions, featureIds); - Set adminLeavePermissionRoleIds = resolvePermissionAdminLeaveRole(adminRoles, productPermissions, req, featureIds); + Set normalPermissionRoleIds = resolvePermissionNormalRole(allRoles, req, productPermissions, featureIds, allRolePermissionMap); + Set adminLeavePermissionRoleIds = resolvePermissionAdminLeaveRole(adminRoles, productPermissions, req, featureIds, allRolePermissionMap); Set roleIds = Sets.newHashSet(); roleIds.addAll(adminPermissionRoleIds); @@ -699,6 +710,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Collections.emptyList(); } + Map personTags = resolveTags(req, saasRoleUsers); + Set superAdminRoleIds = adminRoles.stream() .filter(r -> RoleTypeEnum.SUPER_ADMIN.getValue().equals(r.getRoleType())) .map(SaasRoleRes::getId) @@ -710,6 +723,29 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { // copy原代码 for (SaasRoleUserV2DTO relation : saasRoleUsers) { SaasRoleUserV2DTO.SaasRoleUser saasRoleUser = relation.getSaasRoleUser(); + + // 如果用户在岗位那边的状态没有当前权限点的标签的权限,则需要过滤掉 + PermissionTagService.ResolvePermissionDTO personTag = personTags.get(saasRoleUser.getPersonId()); + if (CollectionUtils.isEmpty(req.getTags()) + && Objects.nonNull(personTag) + && !CollectionUtils.isEmpty(personTag.getTags())) { + + List permissionDTOS = allRolePermissionMap.get(relation.getRoleId()); + + if (CollectionUtils.isEmpty(permissionDTOS)) { + continue; + } + + boolean matchedTags = permissionDTOS.stream() + .anyMatch(permission -> permission.getTags() + .stream() + .anyMatch(tag -> !Sets.intersection(permission.getTags(), personTag.getTags()).isEmpty())); + + if (BooleanUtils.isNotTrue(matchedTags)) { + continue; + } + } + String key = KeyUtil.buildKeyBySeparator(saasRoleUser.getOuId(), saasRoleUser.getIdentityId(), saasRoleUser.getIdentityType()); ListIdentityFromPermissionResp.UserVO user = distinctMap.get(key); if (user == null) { @@ -730,6 +766,24 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Lists.newArrayList(distinctMap.values()); } + private Map resolveTags(ListPermissionUser req, List saasRoleUsers) { + // 如果没有指定标签,需要根据查询出来的用户去找到当前的状态来过滤权限 + if (!CollectionUtils.isEmpty(req.getTags())) { + return Collections.emptyMap(); + } + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(saasRoleUsers.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(req.getWorkspaceId()) + .ouId(req.getOuId()) + .personId(e.getSaasRoleUser().getPersonId()) + .build()) + .collect(Collectors.toList())) + .build(); + return permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(PermissionTagService.ResolvePermissionDTO::getPersonId, Function.identity())); + } + @Override public List batchListIdentityFromPermission(List reqList) { //异步处理 @@ -758,9 +812,51 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } + private void assembleTag(IdentityAuthReq req) { + + if (CollectionUtils.isEmpty(req.getWorkspaceOusPairs())) { + return; + } + + List needResolveTags = req.getWorkspaceOusPairs().stream() + .filter(e -> CollectionUtils.isEmpty(e.getTags())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(needResolveTags)) { + return; + } + + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(needResolveTags.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(req.getPersonId()) + .build()) + .collect(Collectors.toList())) + .build(); + Map resolvePermissions = permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(e -> e.getOuId() + "_" + e.getWorkspaceId(), Function.identity())); + + req.getWorkspaceOusPairs().forEach(e -> { + if (!CollectionUtils.isEmpty(e.getTags())) { + return; + } + + PermissionTagService.ResolvePermissionDTO resolvePermissionDTO = resolvePermissions.get(e.buildOuWorkspaceKey()); + if (Objects.isNull(resolvePermissionDTO)) { + return; + } + + e.setTags(resolvePermissionDTO.getTags()); + }); + } @Override public IdentityAuthRes findIdentityAuthMix(IdentityAuthReq req) { + + assembleTag(req); + //请求参数去重: ou-workspace req.distinctOUWorkspacePair(); @@ -827,16 +923,59 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { if (!listPermissionFromRoleGroupReq.getFindFeatureInfo()) { return permissionInfo; } + + Map personPermissionTags = resolveTags(permissionInfo); + Map> authMap = filterAuthByRoleAndProduct(permissionInfo.stream().map(e -> FilterRoleAuth.builder() .roleId(NumberUtil.parseLong(e.getRoleId())) .workspaceId(e.getWorkspaceId()) .build()).collect(Collectors.toList())); - permissionInfo.forEach(e -> e.setFeatureInfos(authMap.get(NumberUtil.parseLong(e.getRoleId())))); - permissionInfo.forEach(e -> e.setSimpleFeatureInfos(org.apache.commons.collections4.CollectionUtils.emptyIfNull(authMap.get(NumberUtil.parseLong(e.getRoleId()))) - .stream().map(ListPermissionFromRoleGroupResp.FeatureInfo::getFeatureId).collect(Collectors.toSet()))); + return permissionInfo.stream() + .filter(e -> { + PermissionTagService.ResolvePermissionDTO resolvePermission = personPermissionTags.get(e.getPersonId() + "_" + e.getOuId() + "_" + e.getWorkspaceId()); + if (Objects.isNull(resolvePermission)) { + // 未解析到标签兼容历史情况 + return true; + } - return permissionInfo; + Set featureInfos = authMap.get(NumberUtil.parseLong(e.getRoleId())); + + return featureInfos.stream() + .anyMatch(permission -> permission.getTags() + .stream() + .anyMatch(tag -> !Sets.intersection(permission.getTags(), resolvePermission.getTags()).isEmpty())); + }) + .peek(e -> { + e.setFeatureInfos(authMap.get(NumberUtil.parseLong(e.getRoleId()))); + e.setSimpleFeatureInfos(org.apache.commons.collections4.CollectionUtils.emptyIfNull(authMap.get(NumberUtil.parseLong(e.getRoleId()))) + .stream().map(ListPermissionFromRoleGroupResp.FeatureInfo::getFeatureId).collect(Collectors.toSet())); + }) + .collect(Collectors.toList()); + } + + /** + * 解析用户在项目的标签: + * key:personId_ouId_workspaceId + * @param permissionInfo + * @return + */ + private Map resolveTags(List permissionInfo) { + + List personPermissions = permissionInfo.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(e.getPersonId()) + .build()) + .distinct() + .collect(Collectors.toList()); + + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(personPermissions) + .build(); + return permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(e -> e.getPersonId() + "_" + e.getOuId() + "_" + e.getWorkspaceId(), Function.identity())); } /** @@ -871,7 +1010,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { WorkspaceProductService.WorkspaceProductPermission::getProductPermissions)); // intersection auth from role and product - Map> map = filterRoleAuths.stream().collect(Collectors.toMap(FilterRoleAuth::getRoleId, e -> { + Map> map = filterRoleAuths.stream().collect(Collectors.toMap(FilterRoleAuth::getRoleId, e -> { Long roleId = e.getRoleId(); SaasRoleRes saasRole = roles.get(e.getRoleId()); if (null == saasRole) { @@ -879,11 +1018,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Collections.emptySet(); } - Set rolePermissionIds = rolePermissions.get(roleId) - .stream() - .map(RolePermissionCacheService.PermissionDTO::getFeatureId) - .collect(Collectors.toSet()); - Set productPermissionIds = workspaceProductPermissions.get(e.getWorkspaceId()).stream() .map(WorkspaceProductService.ProductPermission::getPermissions) .flatMap(Collection::stream) @@ -891,22 +1025,23 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .map(ProductPermissionCacheService.PermissionDTO::getFeatureId) .collect(Collectors.toSet()); - return new HashSet<>(CollectionUtil.intersection(productPermissionIds, rolePermissionIds)); - - + return rolePermissions.get(roleId).stream() + .filter(rolePermission -> productPermissionIds.contains(rolePermission.getFeatureId())) + .collect(Collectors.toSet()); }, (oldFeatureLists, newFeatureLists) -> { oldFeatureLists.addAll(newFeatureLists); return oldFeatureLists; })); Map> featureMap = Maps.newHashMap(); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry> entry : map.entrySet()) { Set featureInfos = org.apache.commons.collections4.CollectionUtils.emptyIfNull(entry.getValue()).stream().map(e -> ListPermissionFromRoleGroupResp.FeatureInfo.builder() - .featureId(e) + .featureId(e.getFeatureId()) + .tags(e.getTags()) // 因为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) + .relationType(e.getFeatureId() < 100000 ? OLD_FEATURE : NEW_FEATURE) .build()).collect(Collectors.toSet()); featureMap.put(entry.getKey(), featureInfos); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java b/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java index edda0de6..9e4b58aa 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java @@ -82,6 +82,26 @@ public class RpcInternalUtil { return result; } + public static ApiListResult rpcApiListResultProcessor(Supplier> supplier, String operationType, Object... param) { + + return rpcApiListResultProcessorMayThrow(supplier, operationType, (commonResponse) -> { + throw new ServiceException(commonResponse.getMsg()); + }, param); + } + + public static ApiListResult rpcApiListResultProcessorMayThrow(Supplier> supplier, String operationType, Consumer> throwConsumer, Object... param) { + AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空"); + log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param)); + ApiListResult result = supplier.get(); + log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result)); + Assert.notNull(result, "服务调用异常"); + // 200自定义处理 + if (HttpStatus.HTTP_OK != result.getCode()) { + throwConsumer.accept(result); + } + return result; + } + public static T checkAndGetData(ApiResult result) { if (result.isError()) { throw new BizException(result.getRespCode(), result.getMsg());