diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeaturePermissionReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeaturePermissionReq.java index f53c3249..f0cc84c1 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeaturePermissionReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeaturePermissionReq.java @@ -27,15 +27,15 @@ public class FeaturePermissionReq { Long workspaceId; /** - * 工作台类型 + * 工作台类型 - 废弃 */ - @NotNull + @Deprecated private Integer workspaceType; /** - * 使用{@link WorkspaceJoinType} + * 使用{@link WorkspaceJoinType} - 废弃 */ - @NotNull + @Deprecated private Integer workspaceJoinType; /** @@ -50,11 +50,12 @@ public class FeaturePermissionReq { */ String terminal; - @NotNull - @Min(value = 1) + Long identityId; - @NotNull - @Min(value = 0) + Integer identityType; + /** 人员ID - 优先于identity **/ + Long personId; + } \ No newline at end of file diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java index cd939ac3..b68981af 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java @@ -31,8 +31,8 @@ public class ListIdentityFromPermissionReq { @NotNull(message = "工作台不能为空") private Long workspaceId; - /** 参建单位类型 **/ - @NotNull(message = "参建单位类型不能为空") + /** 参建单位类型 - 废弃 直接依赖角色上类型 **/ + @Deprecated private Integer workspaceJoinType; /** diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasRoleWithUser.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasRoleWithUser.java index b86972c2..d2059e19 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasRoleWithUser.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasRoleWithUser.java @@ -57,4 +57,7 @@ public class SaasRoleWithUser { * relation 工作台Id */ private Long relationWorkspaceId; + + + private Integer productUnitType; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java index 30dd8cad..f90e8de2 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java @@ -26,5 +26,8 @@ public interface SaasRoleMapper extends BaseMapper { List listForOUWorkspace(Long ouId, Long workspaceId, Integer workspaceJoinType); List listRoleByFeatures(@Param("featureIds") Set featureIds); + + List listAdminsByWorkspace(List workspaceIds); + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index d120796d..e2b305cc 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -98,4 +98,7 @@ public interface RoleService { List queryByCodes(List codes); void changeGroupLeaderRole(List reqs); + + /** 查询超管和管理员角色 **/ + List listAdmins(Long workspaceId, Long ouId); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 57a825fe..18d797e6 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -934,4 +934,13 @@ public class RoleServiceImpl implements RoleService { saasRoleUserRelationDao.saveOrUpdateBatch(addList); saasRoleUserRelationDao.deleteById(deductList); } + + + @Override + public List listAdmins(Long workspaceId, Long ouId) { + return saasRoleDao.lambdaQuery() + .eq(Objects.nonNull(workspaceId), SaasRole::getWorkspaceId, workspaceId) + .eq(Objects.nonNull(ouId), SaasRole::getOwnerOuId, ouId) + .list(); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java index 23d02579..4857b323 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java @@ -12,6 +12,7 @@ import cn.axzo.tyr.server.service.SaasFeatureService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -41,16 +42,14 @@ public class SaasFeatureServiceImpl implements SaasFeatureService { public FeaturePermissionRes listPermissionCodes(FeaturePermissionReq req) { FeaturePermissionRes featurePermissionRes = new FeaturePermissionRes(); IdentityAuthReq authReq = new IdentityAuthReq(); - if (StringUtils.hasText(req.getTerminal())) { - authReq.setTerminal(Lists.newArrayList()); + if (StrUtil.isNotBlank(req.getTerminal())) { + authReq.setTerminal(Collections.singletonList(req.getTerminal())); } authReq.setIdentityId(req.getIdentityId()); authReq.setIdentityType(IdentityType.getIdentityType(req.getIdentityType())); IdentityAuthReq.WorkspaceOuPair workspaceOuPair = new IdentityAuthReq.WorkspaceOuPair(); workspaceOuPair.setWorkspaceId(req.getWorkspaceId()); workspaceOuPair.setOuId(req.getOuId()); - workspaceOuPair.setWorkspaceType(req.getWorkspaceType()); - workspaceOuPair.setWorkspaceJoinType(req.getWorkspaceJoinType()); authReq.setWorkspaceOusPairs(Lists.newArrayList(workspaceOuPair)); IdentityAuthRes identityAuthRes = tyrSaasAuthService.findIdentityAuthMix(authReq); 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 5d86093b..c3e2c9c0 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 @@ -596,133 +596,53 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { result.setOuId(req.getOuId()); result.setWorkspaceId(req.getWorkspaceId()); - StopWatch watch = StopWatch.create("listIdentityFromPermission"); //code查询权限点信息 - watch.start("listNodeWithChildrenByCode"); List features = permissionPointService.listNodeWithChildrenByCode(req.getFeatureCode(), req.getTerminal()); - watch.stop(); if (CollectionUtil.isEmpty(features)) { - log.warn("------trace-L-I-F-P----> no features found for:{}", req.getFeatureCode()); + log.warn("no features data found for:{}", req.getFeatureCode()); return result; } - Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); - log.info("------trace-L-I-F-P----> features need to check:{}", featureIds); - //权限匹配 - 工作台是否有指定权限 - watch.start("matchWorkspaceFeature"); - Set matchedFeatureIds = matchWorkspaceFeature(req.getWorkspaceId(), req.getWorkspaceJoinType(), featureIds); - watch.stop(); - if (CollectionUtil.isEmpty(matchedFeatureIds)) { - log.warn("------trace-L-I-F-P----> no matched feature in workspace"); - return result; - } - log.info("------trace-L-I-F-P----> matched feature in workspace:{}", matchedFeatureIds); - //是否免授权权限点 Optional freeFeature = features.stream() - .filter(f -> matchedFeatureIds.contains(f.getId())) .filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType())) .findAny(); if (freeFeature.isPresent()) { - log.warn("------trace-L-I-F-P----> free feature found :{}", freeFeature.get().getId()); - result.setFreePermission(true); + log.warn("free feature found :{}", freeFeature.get().getId()); + throw new ServiceException("不能查询免授权权限点人员"); + } + + Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); + //权限匹配 - 有该权限的工作台产品 productUnitType -> featureIds + Map> workspaceFeatureMap = matchWorkspaceFeature(req.getWorkspaceId(), featureIds); + if (CollectionUtil.isEmpty(workspaceFeatureMap)) { + log.warn("no matched product feature in workspace"); return result; } - //从相关角色查询用户-超管和普通角色 - watch.start("getUsersFromRole"); - List users = getUsersFromRole(req, matchedFeatureIds); - watch.stop(); - watch.prettyPrint(TimeUnit.MILLISECONDS); - result.setUsers(users); - return result; + List matchedUsers = getWorkspaceUser(req.getWorkspaceId(), req.getOuId(), workspaceFeatureMap); + if (CollectionUtil.isEmpty(matchedUsers)) { + return result; + } + return matchedUsers.get(0); } - private Set matchWorkspaceFeature(Long workspaceId, Integer workspaceJoinType, Set featureIds) { + private Map> matchWorkspaceFeature(Long workspaceId, Set featureIds) { //查询工作台下产品 List productList = checkAndGetData(servicePkgClient.listProductInWorkSpace(workspaceId)); if (CollectionUtil.isEmpty(productList)) { log.warn("------trace-L-I-F-P----> no product found for workspace"); - return Collections.emptySet(); + return Collections.emptyMap(); } //产品包含的权限-过滤参建类型 和 feature return productFeatureRelationService.queryOnCondition(ProductFeatureQuery.builder() .productIds(productList.stream() .map(ServicePkgProduct::getProductId) .collect(Collectors.toSet())) - .workspaceJoinType(workspaceJoinType) .featureIds(featureIds) .build()) .stream() - .map(SaasProductModuleFeatureRelation::getFeatureId) - .collect(Collectors.toSet()); - } - - private List getUsersFromRole(ListIdentityFromPermissionReq req, Set featureIds) { - Long ouId = req.getOuId(); - Long workspaceId = req.getWorkspaceId(); - StopWatch watch = StopWatch.create("getUsersFromRole"); - //查询OU-工作台下的角色-含superAdmin - watch.start("listForOUWorkspace"); - List roleList = roleService.listForOUWorkspace(ouId, workspaceId, req.getWorkspaceJoinType()); - watch.stop(); - List roleIds = roleList.stream().map(SaasRole::getId).collect(Collectors.toList()); - log.info("------trace-L-I-F-P----> roles from ou-workspace:{}", roleIds); - if (CollectionUtil.isEmpty(roleList)) { - log.info("------trace-L-I-F-P----> no role found for ou-workspace and type"); - return Collections.emptyList(); - } - - //查询角色及权限 - watch.start("roleService.getByIds"); - List rolePermissions = roleService.getByIds(roleIds, - null, Lists.newArrayList(workspaceId), Lists.newArrayList(ouId), true,null); - watch.stop(); - //计算角色实际的权限 - 匹配请求的权限 --> 实际拥有权限的角色 - watch.start("filterMatchFeature"); - List matchedRoleList = new ArrayList<>(); - for (SaasRoleVO rolePermission : rolePermissions) { - List filterFeature = rolePermission.getMatchFeature(workspaceId, ouId); - if (filterFeature.stream().anyMatch(f -> featureIds.contains(f.getPermissionPointId()))) { - log.info("------trace-L-I-F-P----> matched role:{}", rolePermission.getId()); - matchedRoleList.add(rolePermission); - } else { - log.info("------trace-L-I-F-P----> not matched role:{}", rolePermission.getId()); - } - } - watch.stop(); - - //查询角色下用户 - watch.start("roleUserService.listByRoleIds"); - List matchedRoleIds = matchedRoleList.stream().map(SaasRoleVO::getId).collect(Collectors.toList()); - //追加工作台超管 - Set superAdmins = roleList - .stream() - .filter(r -> r.getRoleType().equals(RoleTypeEnum.SUPER_ADMIN.getValue())) - .map(SaasRole::getId) - .collect(Collectors.toSet()); - matchedRoleIds.addAll(superAdmins); - log.info("------trace-L-I-F-P----> append super admins:{}, final roles:{}", superAdmins, matchedRoleIds); - if (CollectionUtil.isEmpty(matchedRoleIds)) { - log.info("------trace-L-I-F-P----> no matched role found for feature"); - return Collections.emptyList(); - } - - List relationList = roleUserService.listByRoleIds(matchedRoleIds, ouId, workspaceId); - watch.stop(); - //构建用户-去重(identityId-identityType) - List users = new ArrayList<>(); - Set filterSet = new HashSet<>(); - for (SaasRoleUserRelation relation : relationList) { - String key = relation.getIdentityId() + "-" + relation.getIdentityType(); - if (!filterSet.contains(key)) { - filterSet.add(key); - ListIdentityFromPermissionResp.UserVO user = new ListIdentityFromPermissionResp.UserVO(relation.getIdentityId(), - relation.getIdentityType(), relation.getNaturalPersonId(), superAdmins.contains(relation.getIdentityId())); - users.add(user); - } - } - watch.prettyPrint(TimeUnit.MILLISECONDS); - return users; + .collect(Collectors.groupingBy(r -> Integer.valueOf(r.getDictCode()), + Collectors.mapping(SaasProductModuleFeatureRelation::getFeatureId, Collectors.toSet()))); } @Override @@ -957,18 +877,19 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //code查询权限点信息 List features = permissionPointService.listNodeWithChildrenByCodes(req.getFeatureCodes(), null); if (CollectionUtil.isEmpty(features)) { - log.warn("no features found for:{}", req.getFeatureCodes()); + log.warn("no features data found for:{}", req.getFeatureCodes()); return Collections.emptyList(); } Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); - //权限匹配 - 工作台是否有指定权限 - Set matchedFeatureIds = matchWorkspaceFeature(req.getWorkspaceId(), null, featureIds); - if (CollectionUtil.isEmpty(matchedFeatureIds)) { - log.warn("------trace-L-I-F-P----> no matched feature in workspace"); + //权限匹配 - 工作台是否有指定权限 productUnitType -> featureIds + Map> workspaceFeatureMap = matchWorkspaceFeature(req.getWorkspaceId(), featureIds); + if (CollectionUtil.isEmpty(workspaceFeatureMap)) { + log.warn("no matched feature in workspace product"); return Collections.emptyList(); } //是否免授权权限点 + Set matchedFeatureIds = workspaceFeatureMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()); Optional freeFeature = features.stream() .filter(f -> matchedFeatureIds.contains(f.getId())) .filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType())) @@ -978,50 +899,53 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } //从相关角色查询用户-超管和普通角色 - Map respMap = getWorkspaceUser(req, matchedFeatureIds); - return new ArrayList<>(respMap.values()); + return getWorkspaceUser(req.getWorkspaceId(), null, workspaceFeatureMap); } - private Map getWorkspaceUser(WorkspacePermissionIdentityReq req, Set matchedFeatureIds) { - Map result = new HashMap<>(); - Map> distinctMap = new HashMap<>(); - //超管 - List superAdmins = roleService.listSuperAdminByWorkspace(Collections.singletonList(req.getWorkspaceId())); - for (SaasRoleWithUser superAdmin : superAdmins) { - Set distinctSet = distinctMap.getOrDefault(superAdmin.getOuId(), new HashSet<>()); - boolean suc = distinctSet.add(superAdmin.getIdentityId() + "-" + superAdmin.getIdentityType()); - distinctMap.put(superAdmin.getOuId(), distinctSet); - if (!suc) { - continue; - } - ListIdentityFromPermissionResp resp = result.getOrDefault(superAdmin.getOuId(), new ListIdentityFromPermissionResp()); - ListIdentityFromPermissionResp.UserVO user = ListIdentityFromPermissionResp.UserVO.builder() - .isSuperAdmin(true) - .identityId(superAdmin.getIdentityId()) - .identityType(superAdmin.getIdentityType()) - .personalId(superAdmin.getNaturalPersonId()) - .build(); - resp.setOuId(superAdmin.getOuId()); - resp.getUsers().add(user); - result.put(superAdmin.getOuId(), resp); + private List getWorkspaceUser(Long workspaceId, Long ouId, Map> workspaceFeatureMap) { + + Set productTypes = workspaceFeatureMap.keySet(); + Set matchedFeatureIds = workspaceFeatureMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()); + + List matchedRoles = new ArrayList<>(); + + //超管和管理员 + List adminRoles = roleService.listAdmins(workspaceId, ouId); + if (CollectionUtil.isEmpty(adminRoles)) { + log.warn("no admin roles found for workspaceId:{}, ouId:{}", workspaceId, ouId); + } else { + matchedRoles.addAll(adminRoles); } - //权限点查角色 -- 不考虑 角色权限集例外 - List roles = roleService.queryRoleByFeatures(matchedFeatureIds); - if (CollectionUtil.isEmpty(roles)) { + //普通角色 权限点查角色 -- 不考虑 角色权限集例外 + List normalRoles = roleService.queryRoleByFeatures(matchedFeatureIds); + if (CollectionUtil.isEmpty(normalRoles)) { log.warn("no role found for featureIds:{}", matchedFeatureIds); - return result; + } else { + matchedRoles.addAll(normalRoles); } - //角色查人 - List roleIds = roles.stream() + + //匹配角色和产品标签 + List roleIds = matchedRoles.stream() + .filter(r -> productTypes.contains(r.getProductUnitType())) .map(SaasRole::getId) .collect(Collectors.toList()); - List relations = roleUserService.listByRoleIds(roleIds, null, req.getWorkspaceId()); - if (CollectionUtil.isEmpty(relations)) { - log.warn("no user role relation found. roleIds:{}, workspaceId:{}", roleIds, req.getWorkspaceId()); - return result; + if (CollectionUtil.isEmpty(roleIds)) { + log.warn("no role matched product unit types"); + return Collections.emptyList(); } + //角色查人 + List 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(); + } + + Map> distinctMap = new HashMap<>(); + //ouId -> resp : ou维度去重 + Map resultMap = new HashMap<>(); + //组装去重 for (SaasRoleUserRelation relation : relations) { Set distinctSet = distinctMap.getOrDefault(relation.getOuId(), new HashSet<>()); boolean suc = distinctSet.add(relation.getIdentityId() + "-" + relation.getIdentityType()); @@ -1030,17 +954,18 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { continue; } - ListIdentityFromPermissionResp resp = result.getOrDefault(relation.getOuId(), new ListIdentityFromPermissionResp()); + ListIdentityFromPermissionResp resp = resultMap.getOrDefault(relation.getOuId(), new ListIdentityFromPermissionResp()); ListIdentityFromPermissionResp.UserVO user = ListIdentityFromPermissionResp.UserVO.builder() .identityId(relation.getIdentityId()) .identityType(relation.getIdentityType()) .personalId(relation.getNaturalPersonId()) .build(); + resp.setWorkspaceId(workspaceId); resp.setOuId(relation.getOuId()); resp.getUsers().add(user); - result.put(relation.getOuId(), resp); + resultMap.put(relation.getOuId(), resp); } - return result; + return new ArrayList<>(resultMap.values()); } } diff --git a/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml b/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml index 0ac1923c..9a2ede1c 100644 --- a/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml +++ b/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml @@ -34,6 +34,7 @@ r.`name` AS roleName, r.role_type AS roleType, r.workspace_id AS workspaceId, + r.product_unit_type AS productUnitType, ru.identity_id AS identityId, ru.identity_type AS identityType, ru.natural_person_id AS naturalPersonId,