@ -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 . getDept IdList ( ) , tableAlias , userDetail . getDeptIdList ( ) ) ;
userDetail . getOrgIdPath ( ) , userDetail . getGrid IdList ( ) , 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 < Se t< RoleOpeScopeResultDTO > > result = govAccessFeignClient . listRoleAllOperationScopesByRoleId ( role ) ;
Result < Lis t< RoleOpeScopeResultDTO > > result = govAccessFeignClient . listRoleAllOperationScopesByRoleId ( role ) ;
if ( ! result . success ( ) ) {
// 获取operation异常
log . error ( "调用GovAccess,根据RoleId查询Operation列表失败:{}" , result . getMsg ( ) ) ;
throw new RenException ( EpmetErrorCode . SERVER_ERROR . getCode ( ) ) ;
}
Se t< RoleOpeScopeResultDTO > roleOperations = result . getData ( ) ;
Lis t< 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 < Se t< RoleOpeScopeResultDTO > > opeResult = govAccessFeignClient . listRoleAllOperationScopesByRoleId ( roleId ) ;
Result < List < RoleOpeScopeResultDTO > > opeResult = govAccessFeignClient . listRoleAllOperationScopesByRoleId ( roleId ) ;
if ( ! opeResult . success ( ) ) {
log . error ( "DataFilter:根据角色查询角色所有的操作列表出错:{}" , opeResult . getMsg ( ) ) ;
} else {
Se t< 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,11 +388,12 @@ public class DataFilterAspect {
genOrgScopeSql ( sb , scopes , currOrgPath , pOrgPath , tableAlias ) ;
sb . replace ( sb . lastIndexOf ( "OR" ) , sb . lastIndexOf ( "OR" ) + 3 , "" ) ;
hasConditions . set ( true ) ;
return true ;
}
/ * *
* 计算组织范围过滤sql
*
* PS : 这个方法需要优化 , 当前阶段因为逻辑不稳定 , 暂时不做过度封装
* @param scopes
* @param currOrg
* @param pOrgPath
@ -342,16 +411,32 @@ public class DataFilterAspect {
break ;
case OpeScopeConstant . ORG_CURR_AND_SUB :
if ( StringUtils . isBlank ( tableAlias ) ) {
sb . append ( " ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( "%' " ) . append ( " OR " ) ;
sb . append ( " ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( "%' OR " ) ;
} else {
sb . append ( " " ) . append ( tableAlias ) . append ( ".ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( "%' " ) . append ( " OR " ) ;
sb . append ( " " ) . append ( tableAlias ) . append ( ".ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( "%' OR " ) ;
}
break ;
case OpeScopeConstant . ORG_CURR_SUB :
if ( StringUtils . isBlank ( tableAlias ) ) {
sb . append ( " ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( orgIdPathSpliter ) . append ( currOrg ) . append ( "%' " ) . append ( " OR " ) ;
sb . append ( " ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( orgIdPathSpliter ) . append ( currOrg ) . append ( "%' OR " ) ;
} else {
sb . append ( " " ) . append ( tableAlias ) . append ( ".ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( orgIdPathSpliter ) . append ( currOrg ) . append ( "%' OR " ) ;
}
break ;
//当前单位的父级单位
case OpeScopeConstant . ORG_CURR_SUP :
if ( StringUtils . isBlank ( tableAlias ) ) {
sb . append ( " '" ) . append ( pOrgPath ) . append ( "' like CONCAT(" ) . append ( "ORG_ID_PATH,'%') OR " ) ;
} else {
sb . append ( " '" ) . append ( pOrgPath ) . append ( "' like CONCAT(" ) . append ( tableAlias ) . append ( ".ORG_ID_PATH,'%') OR " ) ;
}
break ;
// 当前单位及其父级单位
case OpeScopeConstant . ORG_CURR_AND_SUP :
if ( StringUtils . isBlank ( tableAlias ) ) {
sb . append ( " '" ) . append ( pOrgPath ) . append ( orgIdPathSpliter ) . append ( currOrg ) . append ( "' like CONCAT(" ) . append ( "ORG_ID_PATH,'%') OR " ) ;
} else {
sb . append ( " " ) . append ( tableAlias ) . append ( ".ORG_ID_PATH like '" ) . append ( pOrgPath ) . append ( orgIdPathSpliter ) . append ( currOrg ) . append ( "%' " ) . append ( " OR " ) ;
sb . append ( " ' " ) . append ( pOrgPath ) . append ( orgIdPathSpliter ) . append ( currOrg ) . append ( "' like CONCAT( " ) . append ( tableAlias ) . append ( ".ORG_ID_PATH,'%' ) OR " ) ;
}
break ;
case OpeScopeConstant . ORG_EQUAL :
@ -366,6 +451,14 @@ public class DataFilterAspect {
// todo 同级的子级
//sb.append(" OR ");
break ;
case OpeScopeConstant . ORG_EQUAL_AND_SUP :
// todo 同级及其上级
//sb.append(" OR ");
break ;
case OpeScopeConstant . ORG_EQUAL_SUP :
// todo 同级的上级
//sb.append(" OR ");
break ;
}
}
}
@ -378,12 +471,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的权限,直接放入
filtedScopes . put ( scopeIndex , scope ) ;
break ;
}
String [ ] currArr = scopeIndex . split ( "_" ) ;
if ( "0" . equals ( currArr [ 1 ] ) ) {
// 为0,说明没有包含关系,直接放入