All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
matrix.boot.jdbc.orm.mybatis.handler.CustomDataPermissionHandler Maven / Gradle / Ivy
package matrix.boot.jdbc.orm.mybatis.handler;
import matrix.boot.based.dto.DataPermissionDto;
import matrix.boot.based.enums.DataPermissionOperateEnum;
import matrix.boot.common.exception.ServiceException;
import matrix.boot.jdbc.orm.mybatis.intercept.DataPermissionMybatisPlusInterceptor;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.util.cnfexpression.MultiAndExpression;
import net.sf.jsqlparser.util.cnfexpression.MultiOrExpression;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 数据权限拦截处理器
*
* @author wangcheng
* date 2022/4/12
*/
public class CustomDataPermissionHandler {
/**
* 处理数据权限
*
* @param allPlainSelects 所以选择器(包含子查询)
* @param unionPlainSelects union选择器(只有最外层union的where)
* @param aliasMap 别名字典项
* @param normalDataPermission 普通数据权限
* @param specialDataPermission 特殊数据权限
*/
public void processDataPermission(List allPlainSelects, List unionPlainSelects,
Map aliasMap,
List> normalDataPermission, List specialDataPermission) {
if (CollectionUtils.isEmpty(allPlainSelects) && CollectionUtils.isEmpty(unionPlainSelects)) {
return;
}
//解析权限表达式
MultiOrExpression permissionExpression = parseDataPermissionExpression(aliasMap, normalDataPermission, specialDataPermission);
if (permissionExpression == null) {
return;
}
//定义计数器
AtomicInteger count = new AtomicInteger(0);
for (PlainSelect plainSelect : allPlainSelects) {
//替换权限数据
replaceDataPermissionSql(plainSelect.getWhere(), permissionExpression, count);
}
if (count.get() > 0) {
//存在自定义数据权限,不自动拼装where中的数据权限
return;
}
//无默认权限,union plainSelect中都带上数据权限
for (PlainSelect plainSelect : unionPlainSelects) {
plainSelect.setWhere(buildExpression(plainSelect.getWhere(), permissionExpression));
}
}
/**
* 解析权限表达式
*
* @param aliasMap 别名字典项
* @param normalDataPermission 普通的数据权限
* @param specialDataPermission 特殊的数据权限
* @return 权限表达式
*/
private MultiOrExpression parseDataPermissionExpression(Map aliasMap,
List> normalDataPermission,
List specialDataPermission) {
//获取普通权限
if (CollectionUtils.isEmpty(normalDataPermission) && CollectionUtils.isEmpty(specialDataPermission)) {
return null;
}
//定义组条件
List orExpressions = new ArrayList<>();
if (!CollectionUtils.isEmpty(normalDataPermission)) {
List sonExpressions;
//处理普通权限
for (List dataPermissions: normalDataPermission) {
sonExpressions = new ArrayList<>();
for (DataPermissionDto item : dataPermissions) {
parseExpression(sonExpressions, item, aliasMap);
}
orExpressions.add(new MultiAndExpression(sonExpressions));
}
}
if (!CollectionUtils.isEmpty(specialDataPermission)) {
//处理特殊权限
try {
for (String dataPermission: specialDataPermission) {
orExpressions.add(CCJSqlParserUtil.parseCondExpression(dataPermission));
}
} catch (Exception e) {
throw new ServiceException(e.getMessage(), e);
}
}
return new MultiOrExpression(orExpressions);
}
/**
* 解析条件
*
* @param expressions 表达式列表
* @param item 权限信息
* @param aliasMap 别名字典项
*/
private void parseExpression(List expressions, DataPermissionDto item, Map aliasMap) {
if (DataPermissionOperateEnum.EQUAL.equals(item.getOperate())) {
//相等操作
expressions.add(new EqualsTo(getColumn(item.getColumn(), aliasMap), getValue(item.getValue())));
} else if (DataPermissionOperateEnum.NOT_EQUAL.equals(item.getOperate())) {
//不相等操作
expressions.add(new NotEqualsTo(getColumn(item.getColumn(), aliasMap), getValue(item.getValue())));
} else if (DataPermissionOperateEnum.IS_NULL.equals(item.getOperate()) || DataPermissionOperateEnum.NOT_NULL.equals(item.getOperate())) {
//查询空数据或非空数据
IsBooleanExpression expression = new IsBooleanExpression();
expression.setIsTrue(DataPermissionOperateEnum.IS_NULL.equals(item.getOperate()));
expression.setLeftExpression(getColumn(item.getColumn(), aliasMap));
expressions.add(expression);
} else if (DataPermissionOperateEnum.LIKE.equals(item.getOperate()) || DataPermissionOperateEnum.NOT_LIKE.equals(item.getOperate())) {
//相似和不相似操作
LikeExpression expression = new LikeExpression();
expression.setNot(DataPermissionOperateEnum.NOT_LIKE.equals(item.getOperate()));
expression.setLeftExpression(getColumn(item.getColumn(), aliasMap));
expression.setRightExpression(getValue(item.getValue()));
expressions.add(expression);
} else if (DataPermissionOperateEnum.IN.equals(item.getOperate()) || DataPermissionOperateEnum.NOT_IN.equals(item.getOperate())) {
//in和not in操作
ExpressionList values = getValues(item.getValue());
if (CollectionUtils.isEmpty(values.getExpressions())) {
return;
}
InExpression expression = new InExpression(getColumn(item.getColumn(), aliasMap), values);
expression.setNot(DataPermissionOperateEnum.NOT_IN.equals(item.getOperate()));
expressions.add(expression);
} else if (DataPermissionOperateEnum.BETWEEN.equals(item.getOperate()) || DataPermissionOperateEnum.NOT_BETWEEN.equals(item.getOperate())) {
//区间和不在区间操作
List values = getValues(item.getValue()).getExpressions();
if (CollectionUtils.isEmpty(values) || values.size() < 2) {
return;
}
Between expression = new Between();
expression.setNot(DataPermissionOperateEnum.NOT_BETWEEN.equals(item.getOperate()));
expression.setLeftExpression(getColumn(item.getColumn(), aliasMap));
expression.setBetweenExpressionStart(values.get(0));
expression.setBetweenExpressionEnd(values.get(1));
expressions.add(expression);
}
}
/**
* 获取列
*
* @param columnName 列名
* @param aliasMap 别名字典项
* @return 列字段
*/
private Column getColumn(String columnName, Map aliasMap) {
columnName = columnName.replaceAll("[^a-zA-Z0-9._`]+", "");
if (columnName.contains(".")) {
String[] strings = columnName.split("\\.");
strings[0] = aliasMap.getOrDefault(strings[0], strings[0]);
columnName = String.join(".", strings);
}
return new Column(columnName);
}
/**
* 获取值表达式
*
* @param value 值
* @return 值表达式
*/
private Expression getValue(Object value) {
if (value == null) {
return new NullValue();
}
if (value instanceof Date) {
return new DateValue((java.sql.Date) value);
}
String val = String.valueOf(value);
val = val.replace("\\", "")
.replace("'", "\\'");
return new StringValue(val);
}
/**
* 获取值表达式列表
*
* @param value 值列表
* @return 值表达式列表
*/
private ExpressionList getValues(Object value) {
ExpressionList result = new ExpressionList();
if (!(value instanceof List)) {
return result;
}
List> list = (List>) value;
if (CollectionUtils.isEmpty(list)) {
return result;
}
result.setExpressions(new ArrayList<>());
list.forEach(item -> result.getExpressions().add(getValue(item)));
return result;
}
/**
* 替换数据权限sql
*
* @param expression where条件表达式
* @param permissionCondition 需要替换的条件
* @param count 计数器
*/
private void replaceDataPermissionSql(Expression expression, MultiOrExpression permissionCondition, AtomicInteger count) {
if (expression == null) {
return;
}
if (!(expression instanceof BinaryExpression)) {
return;
}
BinaryExpression binaryExpression = (BinaryExpression) expression;
Expression leftExpression = binaryExpression.getLeftExpression();
if (leftExpression instanceof EqualsTo) {
if (DataPermissionMybatisPlusInterceptor.DATA_PERMISSION_SQL_PLACEHOLDER.equals(leftExpression.toString())) {
binaryExpression.setLeftExpression(permissionCondition);
count.incrementAndGet();
}
} else if (leftExpression instanceof BinaryExpression) {
replaceDataPermissionSql(leftExpression, permissionCondition, count);
}
Expression rightExpression = binaryExpression.getRightExpression();
if (rightExpression instanceof EqualsTo) {
if (DataPermissionMybatisPlusInterceptor.DATA_PERMISSION_SQL_PLACEHOLDER.equals(rightExpression.toString())) {
binaryExpression.setRightExpression(permissionCondition);
count.incrementAndGet();
}
} else if (rightExpression instanceof BinaryExpression) {
replaceDataPermissionSql(rightExpression, permissionCondition, count);
}
}
/**
* 组装条件
*
* @param whereExpression 原where条件
* @param dataPermissionExpression 数据权限条件
* @return 新条件
*/
private Expression buildExpression(Expression whereExpression, Expression dataPermissionExpression) {
if (whereExpression == null) {
return dataPermissionExpression;
}
//条件定义
List mainExpressions = new ArrayList() {{
//原条件信息
add(whereExpression);
//加入权限条件
add(dataPermissionExpression);
}};
return new MultiAndExpression(mainExpressions);
}
}