Merge branch 'feature/REQ-1502' into dev

# Conflicts:
#	tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java
This commit is contained in:
wangjibo 2023-10-30 16:22:00 +08:00
commit 152bca134e
12 changed files with 250 additions and 20 deletions

View File

@ -4,5 +4,8 @@
},
"dev": {
"host": "https://dev-app.axzo.cn/msg-center/webApi/message/"
},
"test": {
"host": "https://test-api.axzo.cn/"
}
}

View File

@ -33,4 +33,37 @@ Content-Type: application/json
> reponse-check.js
###
POST {{host}}/tyr/api/v2/auth/batchListIdentityFromPermission
Accept: application/json
Content-Type: application/json
{
"featureCode": "CMS_WEB_PROJ_0528",
"ouId": 5836,
"workspaceId":326,
"workspaceJoinType": 1
}
> reponse-check.js
###
POST {{host}}/tyr/api/v2/auth/listIdentityFromPermission
Accept: application/json
Content-Type: application/json
{
"featureCode": "CMP_APP_PROJ_0056",
"ouId": 5812,
"workspaceId":311,
"workspaceJoinType": 1
}
> reponse-check.js

View File

@ -1,12 +1,12 @@
package cn.axzo.tyr.client.model.vo;
import cn.axzo.trade.datasecurity.core.annotation.control.DisableCrypt;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Collection;
@ -21,6 +21,7 @@ import java.util.stream.Collectors;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Slf4j
public class SaasRoleVO {
private Long id;
@ -125,6 +126,7 @@ public class SaasRoleVO {
}
}
log.info("+======permissionPoint: {}", permissionPoint);
return new ArrayList<>((Collection) permissionPoint);
}

View File

@ -0,0 +1,142 @@
package cn.axzo.tyr.server.job;
import cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import cn.axzo.tyr.server.repository.dao.*;
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.repository.entity.SaasRoleUserRelation;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* CMS角色清洗job-将回溯不了的角色洗成其他
* @description
* @date 2021/9/13 11:31
*/
@Component
@AllArgsConstructor
@Slf4j
@RefreshScope
@RequiredArgsConstructor
public class CMSOtherRoleJobHandler extends IJobHandler {
@Autowired
SaasRoleGroupDao roleGroupDao;
@Autowired
SaasRoleDao roleDao;
@Autowired
SaasPermissionGroupDao saasPermissionGroupDao;
@Autowired
SaasFeatureDao featureDao;
@Autowired
SaasRoleGroupRelationDao roleGroupRelationDao;
@Autowired
SaasRoleUserRelationDao roleUserRelationDao;
@Autowired
SaasPgroupRoleRelationDao pgroupRoleRelationDao;
@Autowired
SaasPgroupPermissionRelationDao pgroupPermissionRelationDao;
@Autowired
SaasPreRoleDao saasPreRoleDao;
@Autowired
SaasPreTemplateDao saasPreTemplateDao;
@Autowired
SaasPreGroupRoleRelationDao saasPreGroupRoleRelationDao;
/**
* CMS角色清洗job-将回溯不了的角色洗成其他
*
* @param s
* @return
* @throws Exception
*/
@Transactional // 在一个事务里面做一起提交
@Override
@XxlJob("CMSOtherRoleJobHandler")
public ReturnT<String> execute(String s) throws Exception {
log.info("CMSOtherRoleJobHandler start");
// 查询无法回溯的角色
List<SaasRole> oldRole = roleDao.lambdaQuery()
.ne(SaasRole::getWorkspaceId, -1l)
.eq(SaasRole::getRoleType, "init")
.in(SaasRole::getFitOuTypeBit, Arrays.asList(1, 2, 4, 8, 16))
.eq(SaasRole::getFromPreRoleId, 0l)
.eq(BaseEntity::getIsDelete, 0)
.list();
if (CollectionUtils.isEmpty(oldRole)) {
log.info("未找到回溯不了的角色");
}
// 根据单位类型分组
Map<Long, List<SaasRole>> ouTypeMap = oldRole.stream().collect(Collectors.groupingBy(e -> e.getFitOuTypeBit()));
Set<Long> ouType = ouTypeMap.keySet();
ouType.forEach(e -> {
// 获取"其他"角色id
Long newRoleId = getNewRoleId(e);
// 更用户角色关联关系
roleUserRelationDao.lambdaUpdate()
.in(SaasRoleUserRelation::getRoleId,ouTypeMap.get(e).stream().map(BaseEntity::getId).collect(Collectors.toList()))
.set(SaasRoleUserRelation::getRoleId,newRoleId)
.update();
});
log.info("CMSOtherRoleJobHandler end");
return ReturnT.SUCCESS;
}
/**
* 查询新角色"其他" id
* @return
*/
private Long getNewRoleId(Long ouType) {
// 根据单位类型查询权限分组
SaasRoleGroup roleGroup = roleGroupDao.lambdaQuery().eq(SaasRoleGroup::getOuTypeCode, String.valueOf(tranceOuTypeBit(ouType))).one();
// 查询权限分组下的角色
List<SaasRoleGroupRelation> roleGroupRelation = roleGroupRelationDao.lambdaQuery()
.eq(SaasRoleGroupRelation::getSaasRoleGroupId, roleGroup.getId())
.eq(BaseEntity::getIsDelete, 0)
.list();
// 查询权限分组下的"其他"角色
SaasRole otherRole = roleDao.lambdaQuery()
.in(BaseEntity::getId, roleGroupRelation.stream().map(SaasRoleGroupRelation::getRoleId).collect(Collectors.toList()))
.eq(SaasRole::getName, "其他")
.eq(BaseEntity::getIsDelete, 0)
.one();
return otherRole.getId();
}
private Integer tranceOuTypeBit(Long ouTypeBit) {
Integer ouType;
if (ouTypeBit == 1) {
ouType = OrganizationalUnitTypeEnum.PRIMARY_CONTRACTING_UNIT.getValue();
} else if (ouTypeBit == 2) {
ouType = OrganizationalUnitTypeEnum.CONSTRUCTION_UNIT.getValue();
} else if (ouTypeBit == 4) {
ouType = OrganizationalUnitTypeEnum.SUPERVISION_UNIT.getValue();
} else if (ouTypeBit == 8) {
ouType = OrganizationalUnitTypeEnum.LABOR_SUBCONTRACTING.getValue();
} else if (ouTypeBit == 16) {
ouType = OrganizationalUnitTypeEnum.PROFESSIONAL_SUBCONTRACTING.getValue();
} else {
throw new IllegalStateException("ouTypeBit 错误: " + ouTypeBit);
}
return ouType;
}
}

View File

@ -64,6 +64,13 @@ public class SaasRole extends BaseEntity<SaasRole> {
@Deprecated
private Long fromPreRoleId;
/**
* 适用单位类型 1:总包 2:建设单位 4:监理单位 8:劳务分包 16:专业分包 0都可以用 只会挂在最末级
* (1052上线后可删除)
*/
@Deprecated
private Long fitOuTypeBit;
/**
* 获取主键值
*

View File

@ -9,8 +9,6 @@ import cn.axzo.tyr.client.model.permission.PermissionPointVO;
import cn.axzo.tyr.server.repository.entity.SaasFeature;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 权限点服务
@ -55,6 +53,6 @@ public interface PermissionPointService {
*/
List<PermissionPointTreeNode> listTreeNodesFlatChild(PermissionPointTreeQueryReq request);
/** 根据code查询权限点, terminal可为空- 直查 **/
List<SaasFeature> listNodeByCode(String featureCode, String terminal);
/** 根据code查询权限点, terminal可为空 **/
List<SaasFeature> listNodeWithChildrenByCode(String featureCode, String terminal);
}

View File

@ -63,7 +63,7 @@ public interface SaasRoleUserService {
*/
List<SuperAminInfoResp> batchSuperAdminList(List<SuperAdminParam> param);
List<SaasRoleUserRelation> listByRoleIds(List<Long> roleIds);
List<SaasRoleUserRelation> listByRoleIds(List<Long> roleIds, Long workspaceId);
/**
* 删除单位参与的工作台的所有的人员与角色 目前主要是用于移除参与单位的地方

View File

@ -9,6 +9,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import cn.axzo.tyr.client.model.enums.FeatureDataType;
import cn.hutool.core.lang.Opt;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -319,6 +320,8 @@ public class PermissionPointServiceImpl implements PermissionPointService {
vo.setParentName(parent.getFeatureName());
vo.setParentFeatureType(parent.getFeatureType());
vo.setParentFeatureTypeDes(FeatureType.apply(parent.getFeatureType()).getDesc());
vo.setFitOuNodeTypeList(Collections.emptyList());
vo.setFitOuNodeTypeList(Collections.emptyList());
return vo;
}
@ -560,9 +563,26 @@ public class PermissionPointServiceImpl implements PermissionPointService {
}
@Override
public List<SaasFeature> listNodeByCode(String featureCode, String terminal) {
return saasFeatureDao.list(new LambdaQueryWrapper<SaasFeature>()
public List<SaasFeature> listNodeWithChildrenByCode(String featureCode, String terminal) {
List<SaasFeature> currentFeatrureList = saasFeatureDao.list(new LambdaQueryWrapper<SaasFeature>()
.eq(SaasFeature::getFeatureCode, featureCode)
.eq(StrUtil.isNotBlank(terminal), SaasFeature::getTerminal, terminal));
//button过滤减少查询
Set<String> pathsWithoutButton = currentFeatrureList.stream()
.filter(f -> !BUTTON.sameCode(f.getFeatureType()))
.map(SaasFeature::getPath)
.collect(Collectors.toSet());
if (CollectionUtil.isEmpty(pathsWithoutButton)) {
return currentFeatrureList;
}
Wrapper<SaasFeature> wrapper = new LambdaQueryWrapper<SaasFeature>()
.eq(StrUtil.isNotBlank(terminal), SaasFeature::getTerminal, terminal)
.and(w -> {
pathsWithoutButton.forEach(p -> w.or().likeRight(SaasFeature::getPath, p));
});
List<SaasFeature> children = saasFeatureDao.list(wrapper);
currentFeatrureList.addAll(children);
return currentFeatrureList;
}
}

View File

@ -77,7 +77,7 @@ public class RoleUserService implements SaasRoleUserService {
.build();
// 删除现有非管理员的角色
if (CollectionUtils.isNotEmpty(existsRoleUser)) {
if (CollectionUtils.isNotEmpty(notAdminRole)) {
roleUserRelationDao.deleteByUser(workspaceModel, notAdminRole);
}
// 清空所有角色
@ -227,11 +227,12 @@ public class RoleUserService implements SaasRoleUserService {
}
@Override
public List<SaasRoleUserRelation> listByRoleIds(List<Long> roleIds) {
public List<SaasRoleUserRelation> listByRoleIds(List<Long> roleIds, Long workspaceId) {
if (CollectionUtil.isEmpty(roleIds)) {
return new ArrayList<>();
}
return roleUserRelationDao.list(new LambdaQueryWrapper<SaasRoleUserRelation>()
.eq(SaasRoleUserRelation::getWorkspaceId, workspaceId)
.in(SaasRoleUserRelation::getRoleId, roleIds));
}

View File

@ -48,6 +48,7 @@ import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@ -533,7 +534,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
result.setWorkspaceId(req.getWorkspaceId());
//code查询权限点信息
List<SaasFeature> features = permissionPointService.listNodeByCode(req.getFeatureCode(), req.getTerminal());
List<SaasFeature> features = permissionPointService.listNodeWithChildrenByCode(req.getFeatureCode(), req.getTerminal());
//权限匹配 - 工作台是否有指定权限
List<SaasFeature> matchedFeature = matchWorkspaceFeature(req.getWorkspaceId(), req.getWorkspaceJoinType(), features);
if (CollectionUtil.isEmpty(matchedFeature)) {
@ -587,19 +588,32 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
//查询OU-工作台下的角色
List<SaasRole> roleList = roleService.listForOUWorkspace(ouId, workspaceId, req.getWorkspaceJoinType());
log.info("====查询OU-工作台下的角色:{}===",roleList);
//查询角色及权限
List<SaasRoleVO> rolePermissions = roleService.getByIds(roleList.stream().map(SaasRole::getId).collect(Collectors.toList()),
null, Lists.newArrayList(workspaceId), Lists.newArrayList(ouId), true);
log.info("====查询角色及权限:{}===",rolePermissions);
//计算角色实际的权限 - 匹配请求的权限 --> 实际拥有权限的角色
Set<Long> featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet());
List<SaasRoleVO> matchedRoleList = rolePermissions.stream()
.filter(rp -> rp.getMatchFeature(workspaceId, ouId).stream()
.anyMatch(f -> featureIds.contains(f.getPermissionPointId())))
.collect(Collectors.toList());
List<SaasRoleVO> matchedRoleList = new ArrayList<>();
for (SaasRoleVO rolePermission : rolePermissions) {
List<PermissionPointTreeNode> filterFeature = rolePermission.getMatchFeature(workspaceId, ouId);
if (filterFeature.stream().anyMatch(f -> featureIds.contains(f.getPermissionPointId()))) {
log.info("=====match role:{}", rolePermission.getId());
matchedRoleList.add(rolePermission);
} else {
log.info("=====not_match-role-id:{}", rolePermission.getId());
log.warn("=========not match role: {}",JSON.toJSONString(rolePermission));
}
}
log.info("-======matchedRoleList: {}", matchedRoleList);
log.info("====计算角色实际的权限 - 匹配请求的权限 --> 实际拥有权限的角色:{}===",featureIds);
//查询角色下用户
List<Long> matchedRoleIds = matchedRoleList.stream().map(SaasRoleVO::getId).collect(Collectors.toList());
log.info("====查询角色下用户:{}===",matchedRoleIds);
//追加工作台超管
Set<Long> superAdmins = roleList
.stream()
@ -607,8 +621,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
.map(SaasRole::getId)
.collect(Collectors.toSet());
matchedRoleIds.addAll(superAdmins);
List<SaasRoleUserRelation> relationList = roleUserService.listByRoleIds(matchedRoleIds);
log.info("====追加工作台超管:{}===",superAdmins);
List<SaasRoleUserRelation> relationList = roleUserService.listByRoleIds(matchedRoleIds, workspaceId);
log.info("====追加工作台超管:{}===",relationList);
//构建用户-去重(identityId-identityType)
List<ListIdentityFromPermissionResp.UserVO> users = new ArrayList<>();
Set<String> filterSet = new HashSet<>();

View File

@ -47,7 +47,7 @@ spring:
cloud:
nacos:
config:
server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80}
server-addr: ${NACOS_HOST:https://dev-nacos.axzo.cn}:${NACOS_PORT:443}
file-extension: yaml
namespace: ${NACOS_NAMESPACE_ID:f82179f1-81a9-41a1-a489-4f9ab5660a6e}
logging:
@ -62,7 +62,7 @@ spring:
cloud:
nacos:
config:
server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80}
server-addr: ${NACOS_HOST:https://dev-nacos.axzo.cn}:${NACOS_PORT:443}
file-extension: yaml
namespace: ${NACOS_NAMESPACE_ID:35eada10-9574-4db8-9fea-bc6a4960b6c7}
---

View File

@ -11,6 +11,7 @@ import cn.axzo.tyr.client.model.permission.PermissionPointVO;
import cn.axzo.tyr.server.controller.permission.PermissionPointController;
import cn.axzo.tyr.server.repository.entity.SaasFeature;
import cn.axzo.tyr.server.repository.dao.SaasFeatureDao;
import cn.axzo.tyr.server.service.PermissionPointService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.junit.jupiter.api.Test;
@ -33,6 +34,8 @@ public class PermissionPointTest {
private PermissionPointController controller;
@Autowired
private SaasFeatureDao saasFeatureDao;
@Autowired
private PermissionPointService permissionPointService;
@Test
public void testList() {
@ -133,4 +136,10 @@ public class PermissionPointTest {
System.out.println(JSON.toJSONString(result));
}
@Test
public void test() {
List<SaasFeature> saasFeatures = permissionPointService.listNodeWithChildrenByCode("CMS_WEB_PROJ_0546", "NT_CMS_WEB_PROJ");
System.out.println(JSON.toJSONString(saasFeatures));
}
}