|
|
@ -19,6 +19,7 @@ import com.epmet.commons.tools.exception.EpmetErrorCode; |
|
|
|
import com.epmet.commons.tools.exception.RenException; |
|
|
|
import com.epmet.commons.tools.security.user.LoginUserUtil; |
|
|
|
import com.epmet.commons.tools.utils.Result; |
|
|
|
import org.apache.commons.lang3.ArrayUtils; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.aspectj.lang.JoinPoint; |
|
|
|
import org.aspectj.lang.annotation.Aspect; |
|
|
@ -52,6 +53,9 @@ public class DataFilterAspect { |
|
|
|
|
|
|
|
public static final ThreadLocal<String> sqlFilter = new ThreadLocal(); |
|
|
|
|
|
|
|
//public static final ThreadLocal<String> gridIdTL = new ThreadLocal();
|
|
|
|
//public static final ThreadLocal<String> deptIdTL = new ThreadLocal();
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
private LoginUserUtil loginUserUtil; |
|
|
|
|
|
|
@ -69,10 +73,30 @@ public class DataFilterAspect { |
|
|
|
//清空
|
|
|
|
sqlFilter.set(null); |
|
|
|
|
|
|
|
// 通过反射,取到注解属性
|
|
|
|
DataFilter dataFilterAnno = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(DataFilter.class); |
|
|
|
String[] tableAliases = dataFilterAnno.tableAliases(); |
|
|
|
String tableAlias = tableAliases[0]; |
|
|
|
// 取到注解属性
|
|
|
|
MethodSignature methodSignature = (MethodSignature) point.getSignature(); |
|
|
|
DataFilter dataFilterAnno = methodSignature.getMethod().getAnnotation(DataFilter.class); |
|
|
|
String tableAlias = dataFilterAnno.tableAliases()[0]; |
|
|
|
String gridIdArgName = dataFilterAnno.gridIdArgName(); |
|
|
|
String deptIdArgName = dataFilterAnno.deptIdArgName(); |
|
|
|
|
|
|
|
String[] parameterNames = methodSignature.getParameterNames(); |
|
|
|
|
|
|
|
// 取出注解参数中指定的gridId和deptId的入参的值
|
|
|
|
String gridId = null; |
|
|
|
String deptId = null; |
|
|
|
if (StringUtils.isNotBlank(gridIdArgName)) { |
|
|
|
int gridIdArgIndex = ArrayUtils.indexOf(parameterNames, gridIdArgName); |
|
|
|
if (gridIdArgIndex >-1){ |
|
|
|
gridId = (String) point.getArgs()[gridIdArgIndex]; |
|
|
|
} |
|
|
|
} |
|
|
|
if (StringUtils.isNotBlank(deptIdArgName)) { |
|
|
|
int deptArgIndex = ArrayUtils.indexOf(parameterNames, deptIdArgName); |
|
|
|
if (deptArgIndex > -1) { |
|
|
|
deptId = (String) point.getArgs()[deptArgIndex]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 从ThreadLocal中取所需权限
|
|
|
|
String requirePermission = AccessOpeAspect.requirePermissionTl.get(); |
|
|
@ -114,7 +138,7 @@ public class DataFilterAspect { |
|
|
|
|
|
|
|
// 生成过滤sql
|
|
|
|
String sqlFilterSegment = getSqlFilterSegment(userId, userDetail.getRoleIdList(), requirePermission, |
|
|
|
userDetail.getOrgIdPath(), userDetail.getDeptIdList(), tableAlias, userDetail.getDeptIdList()); |
|
|
|
userDetail.getOrgIdPath(), userDetail.getGridIdList(), tableAlias, userDetail.getDeptIdList(), gridId, deptId); |
|
|
|
|
|
|
|
// 方式1.填充到Service方法列表中的DataScope对象中。如果dao入参是用DTO的话,那么再加一个DataScope入参,sql中会报错提示#{}参数找不到,因此改用方法2
|
|
|
|
//Object[] methodArgs = point.getArgs();
|
|
|
@ -135,13 +159,13 @@ public class DataFilterAspect { |
|
|
|
Set<String> permissions = new HashSet<>(); |
|
|
|
roleIdList.forEach(role -> { |
|
|
|
// 找出该角色的所有功能操作列表
|
|
|
|
Result<Set<RoleOpeScopeResultDTO>> result = govAccessFeignClient.listRoleAllOperationScopesByRoleId(role); |
|
|
|
Result<List<RoleOpeScopeResultDTO>> result = govAccessFeignClient.listRoleAllOperationScopesByRoleId(role); |
|
|
|
if (!result.success()) { |
|
|
|
// 获取operation异常
|
|
|
|
log.error("调用GovAccess,根据RoleId查询Operation列表失败:{}", result.getMsg()); |
|
|
|
throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); |
|
|
|
} |
|
|
|
Set<RoleOpeScopeResultDTO> roleOperations = result.getData(); |
|
|
|
List<RoleOpeScopeResultDTO> roleOperations = result.getData(); |
|
|
|
permissions.addAll(roleOperations.stream().map(ope -> ope.getOperationKey()).collect(Collectors.toSet())); |
|
|
|
}); |
|
|
|
return permissions; |
|
|
@ -164,31 +188,42 @@ public class DataFilterAspect { |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
private String getSqlFilterSegment(String userId, Set<String> roleIds, String reqiurePermission, String orgIdPath, |
|
|
|
Set<String> gridIdList, String tableAlias, Set<String> deptIds) { |
|
|
|
Set<String> gridIdList, String tableAlias, Set<String> deptIds, String gridId, String deptId) { |
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
|
|
|
|
Map<String, String> accessSettings = listRoleAccessSettings(roleIds); |
|
|
|
|
|
|
|
// 1.生成sql:组织范围过滤
|
|
|
|
genOrgScopeSql(sb, orgIdPath, roleIds, reqiurePermission, tableAlias); |
|
|
|
if (!genOrgScopeSql(sb, orgIdPath, roleIds, reqiurePermission, tableAlias)) { |
|
|
|
// 返回false,说明已经开启了all所有范围,后续条件不在拼接入sql,结束执行
|
|
|
|
return sb.toString(); |
|
|
|
} |
|
|
|
|
|
|
|
// 2.生成sql:我发起的
|
|
|
|
String iCreated = accessSettings.get(AccessSettingConstant.I_CREATED_KEY); |
|
|
|
if (StringUtils.isNotBlank(iCreated) && AccessSettingConstant.I_CREATED_YES.equals(iCreated)) { |
|
|
|
if (StringUtils.isNotBlank(iCreated) && AccessSettingConstant.I_CREATED_ON.equals(iCreated)) { |
|
|
|
genICreatedSql(sb, userId, tableAlias); |
|
|
|
} |
|
|
|
|
|
|
|
// 3.生成sql:本网格的
|
|
|
|
String inGrid = accessSettings.get(AccessSettingConstant.IN_GRID_KEY); |
|
|
|
if (StringUtils.isNotBlank(inGrid) && AccessSettingConstant.IN_GRID_YES.equals(inGrid)) { |
|
|
|
genInGrid(sb, gridIdList, tableAlias); |
|
|
|
if (StringUtils.isNotBlank(inGrid) && AccessSettingConstant.IN_GRID_ON.equals(inGrid)) { |
|
|
|
if (StringUtils.isBlank(gridId)) { |
|
|
|
log.error("DataFilter:拼接SQL语句出错:需要in grid权限,但是代码中没有获取到:{}", gridId); |
|
|
|
throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); |
|
|
|
} |
|
|
|
genInGrid(sb, gridId, tableAlias); |
|
|
|
} |
|
|
|
|
|
|
|
// 4.生成sql:根据部门列表
|
|
|
|
String inDept = accessSettings.get(AccessSettingConstant.IN_DEPARTMENT_KEY); |
|
|
|
if (StringUtils.isNotBlank(inDept) && AccessSettingConstant.IN_DEPARTMENT_YES.equals(inDept)) { |
|
|
|
genDepartmentFilterSql(sb, deptIds); |
|
|
|
if (StringUtils.isNotBlank(inDept) && AccessSettingConstant.IN_DEPARTMENT_ON.equals(inDept)) { |
|
|
|
if (StringUtils.isBlank(deptId)) { |
|
|
|
log.error("DataFilter:拼接SQL语句出错:需要in department权限,但是代码中没有获取到:{}", deptId); |
|
|
|
throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); |
|
|
|
} |
|
|
|
genDepartmentFilterSql(sb, deptId, tableAlias); |
|
|
|
} |
|
|
|
|
|
|
|
return sb.toString(); |
|
|
@ -196,6 +231,7 @@ public class DataFilterAspect { |
|
|
|
|
|
|
|
/** |
|
|
|
* 列出角色对应的权限设置项 |
|
|
|
* |
|
|
|
* @param roleIds |
|
|
|
* @return |
|
|
|
*/ |
|
|
@ -216,51 +252,81 @@ public class DataFilterAspect { |
|
|
|
} |
|
|
|
return new HashMap<>(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 生成部门过滤sql |
|
|
|
* |
|
|
|
* @param sb |
|
|
|
*/ |
|
|
|
private void genDepartmentFilterSql(StringBuilder sb, Set<String> deptIdList) { |
|
|
|
private void genDepartmentFilterSql(StringBuilder sb, String deptId, String tableAlias) { |
|
|
|
//Result<List<DepartmentListResultDTO>> deptListResult = govOrgFeignClient.getDepartmentListByStaffId(staffId);
|
|
|
|
if (CollectionUtils.isEmpty(deptIdList)) { |
|
|
|
return; |
|
|
|
if (hasConditions.get()) { |
|
|
|
// 之前没有条件
|
|
|
|
sb.append(" OR "); |
|
|
|
} |
|
|
|
if (StringUtils.isBlank(tableAlias)) { |
|
|
|
sb.append(" DEPARTMENT_ID = '").append(deptId).append("' "); |
|
|
|
} else { |
|
|
|
sb.append(" ").append(tableAlias).append(".DEPARTMENT_ID ='").append(deptId).append("' "); |
|
|
|
} |
|
|
|
deptIdList.forEach(deptId -> { |
|
|
|
sb.append(hasConditions.get() ? " OR " : "").append(" DEPARTMENT_ID = '").append(deptId).append("' "); |
|
|
|
}); |
|
|
|
hasConditions.set(true); |
|
|
|
} |
|
|
|
|
|
|
|
//private void genDepartmentFilterSql(StringBuilder sb, Set<String> deptIdList) {
|
|
|
|
// //Result<List<DepartmentListResultDTO>> deptListResult = govOrgFeignClient.getDepartmentListByStaffId(staffId);
|
|
|
|
// if (CollectionUtils.isEmpty(deptIdList)) {
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// deptIdList.forEach(deptId -> {
|
|
|
|
// sb.append(hasConditions.get() ? " OR " : "").append(" DEPARTMENT_ID = '").append(deptId).append("' ");
|
|
|
|
// });
|
|
|
|
// hasConditions.set(true);
|
|
|
|
//}
|
|
|
|
|
|
|
|
/** |
|
|
|
* 网格sql |
|
|
|
* |
|
|
|
* @param sb |
|
|
|
* @param tableAlias |
|
|
|
*/ |
|
|
|
private void genInGrid(StringBuilder sb, Set<String> gridIdList, String tableAlias) { |
|
|
|
//if (StringUtils.isBlank(tableAlias)) {
|
|
|
|
// sb.append(hasConditions.get() ? " OR " : "").append(" GRID_ID ='").append(gridId).append("' ");
|
|
|
|
//} else {
|
|
|
|
// sb.append(hasConditions.get() ? " OR " : "").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' ");
|
|
|
|
//}
|
|
|
|
|
|
|
|
private void genInGrid(StringBuilder sb, String gridId, String tableAlias) { |
|
|
|
if (hasConditions.get()) { |
|
|
|
// 之前没有条件
|
|
|
|
sb.append(" OR "); |
|
|
|
} |
|
|
|
|
|
|
|
// OR GRID_ID = 'XXX' OR GRID_ID = 'QQQ'
|
|
|
|
for (String gridId : gridIdList) { |
|
|
|
if (StringUtils.isBlank(tableAlias)) { |
|
|
|
sb.append(" GRID_ID = '").append(gridId).append("' OR"); |
|
|
|
sb.append(" GRID_ID = '").append(gridId).append("' "); |
|
|
|
} else { |
|
|
|
sb.append(" ").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' OR "); |
|
|
|
} |
|
|
|
sb.append(" ").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' "); |
|
|
|
} |
|
|
|
sb.replace(sb.lastIndexOf("OR"), sb.lastIndexOf("OR") + 3, ""); |
|
|
|
hasConditions.set(true); |
|
|
|
} |
|
|
|
|
|
|
|
//private void genInGrid(StringBuilder sb, Set<String> gridIdList, String tableAlias) {
|
|
|
|
// //if (StringUtils.isBlank(tableAlias)) {
|
|
|
|
// // sb.append(hasConditions.get() ? " OR " : "").append(" GRID_ID ='").append(gridId).append("' ");
|
|
|
|
// //} else {
|
|
|
|
// // sb.append(hasConditions.get() ? " OR " : "").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' ");
|
|
|
|
// //}
|
|
|
|
//
|
|
|
|
// if (hasConditions.get()) {
|
|
|
|
// // 之前没有条件
|
|
|
|
// sb.append(" OR ");
|
|
|
|
// }
|
|
|
|
// // OR GRID_ID = 'XXX' OR GRID_ID = 'QQQ'
|
|
|
|
// for (String gridId : gridIdList) {
|
|
|
|
// if (StringUtils.isBlank(tableAlias)) {
|
|
|
|
// sb.append(" GRID_ID = '").append(gridId).append("' OR");
|
|
|
|
// } else {
|
|
|
|
// sb.append(" ").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' OR ");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// sb.replace(sb.lastIndexOf("OR"), sb.lastIndexOf("OR") + 3, "");
|
|
|
|
// hasConditions.set(true);
|
|
|
|
//}
|
|
|
|
|
|
|
|
/** |
|
|
|
* sql:我发起的 |
|
|
|
* |
|
|
@ -277,41 +343,43 @@ public class DataFilterAspect { |
|
|
|
|
|
|
|
/** |
|
|
|
* 计算组织范围过滤sql,整体入口 |
|
|
|
* |
|
|
|
* @param sb |
|
|
|
* @param orgIdPath |
|
|
|
* @param roleIds |
|
|
|
* @param reqiurePermission |
|
|
|
* @param tableAlias |
|
|
|
* @return Boolean 是否继续往下执行。true:继续执行,false:不继续执行 |
|
|
|
*/ |
|
|
|
public void genOrgScopeSql(StringBuilder sb, String orgIdPath, Set<String> roleIds, String reqiurePermission, String tableAlias) { |
|
|
|
public boolean genOrgScopeSql(StringBuilder sb, String orgIdPath, Set<String> roleIds, String reqiurePermission, String tableAlias) { |
|
|
|
|
|
|
|
// 根据角色列表查询操作范围列表
|
|
|
|
Set<RoleOpeScopeResultDTO> opeAndScopes = new HashSet<>(); |
|
|
|
//roleIds.forEach(roleId -> {
|
|
|
|
// OperationScopeFormDTO osformDto = new OperationScopeFormDTO();
|
|
|
|
// osformDto.setRoleId(roleId);
|
|
|
|
// osformDto.setOperationKey(reqiurePermission);
|
|
|
|
// Result<Set<OperationScopeDTO>> result = govAccessFeignClient.getOperationScopesByRoleId(osformDto);
|
|
|
|
// if (result.success()) {
|
|
|
|
// scopeDTOS.addAll(result.getData());
|
|
|
|
// }
|
|
|
|
//});
|
|
|
|
|
|
|
|
roleIds.forEach(roleId -> { |
|
|
|
Result<Set<RoleOpeScopeResultDTO>> opeResult = govAccessFeignClient.listRoleAllOperationScopesByRoleId(roleId); |
|
|
|
Result<List<RoleOpeScopeResultDTO>> opeResult = govAccessFeignClient.listRoleAllOperationScopesByRoleId(roleId); |
|
|
|
if (!opeResult.success()) { |
|
|
|
log.error("DataFilter:根据角色查询角色所有的操作列表出错:{}", opeResult.getMsg()); |
|
|
|
} else { |
|
|
|
Set<RoleOpeScopeResultDTO> opes = opeResult.getData(); |
|
|
|
List<RoleOpeScopeResultDTO> opes = opeResult.getData(); |
|
|
|
if (!CollectionUtils.isEmpty(opes)) { |
|
|
|
opeAndScopes.addAll(opes); |
|
|
|
opes.forEach(ope -> { |
|
|
|
if (reqiurePermission.equals(ope.getOperationKey())) { |
|
|
|
// 拿到当前操作对应的 RoleOpeScopeResultDTO
|
|
|
|
opeAndScopes.add(ope); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 过滤范围
|
|
|
|
// 过滤出最大的范围
|
|
|
|
HashSet<String> scopes = filteScopes(opeAndScopes); |
|
|
|
if (CollectionUtils.isEmpty(scopes)) { |
|
|
|
// 没有范围限制
|
|
|
|
return; |
|
|
|
return true; |
|
|
|
} |
|
|
|
if (scopes.contains(OpeScopeConstant.ORG_ALL)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// 取出父组织ID path 和当前组织ID
|
|
|
@ -320,6 +388,7 @@ public class DataFilterAspect { |
|
|
|
genOrgScopeSql(sb, scopes, currOrgPath, pOrgPath, tableAlias); |
|
|
|
sb.replace(sb.lastIndexOf("OR"), sb.lastIndexOf("OR") + 3, ""); |
|
|
|
hasConditions.set(true); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -378,12 +447,16 @@ public class DataFilterAspect { |
|
|
|
*/ |
|
|
|
private HashSet<String> filteScopes(Set<RoleOpeScopeResultDTO> scopeDTOS) { |
|
|
|
HashMap<String, RoleOpeScopeResultDTO> filtedScopes = new HashMap<>(); |
|
|
|
|
|
|
|
for (RoleOpeScopeResultDTO scope : scopeDTOS) { |
|
|
|
String scopeIndex = scope.getScopeIndex(); |
|
|
|
if (StringUtils.isBlank(scopeIndex)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (OpeScopeConstant.ORG_ALL.equals(scope.getScopeKey())) { |
|
|
|
// 如果是all,那么清除所有的scope限制,
|
|
|
|
filtedScopes.clear(); |
|
|
|
break; |
|
|
|
} |
|
|
|
String[] currArr = scopeIndex.split("_"); |
|
|
|
if ("0".equals(currArr[1])) { |
|
|
|
// 为0,说明没有包含关系,直接放入
|
|
|
|