package com.iailab.framework.datapermission.core.db;
|
|
import cn.hutool.core.collection.CollUtil;
|
import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler;
|
import com.iailab.framework.datapermission.core.rule.DataPermissionRule;
|
import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory;
|
import com.iailab.framework.mybatis.core.util.MyBatisUtils;
|
import lombok.RequiredArgsConstructor;
|
import net.sf.jsqlparser.expression.Expression;
|
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
import net.sf.jsqlparser.schema.Table;
|
|
import java.util.List;
|
|
/**
|
* 基于 {@link DataPermissionRule} 的数据权限处理器
|
*
|
* 它的底层,是基于 MyBatis Plus 的 <a href="https://baomidou.com/plugins/data-permission/">数据权限插件</a>
|
* 核心原理:它会在 SQL 执行前拦截 SQL 语句,并根据用户权限动态添加权限相关的 SQL 片段。这样,只有用户有权限访问的数据才会被查询出来
|
*
|
* @author 芋道源码
|
*/
|
@RequiredArgsConstructor
|
public class DataPermissionRuleHandler implements MultiDataPermissionHandler {
|
|
private final DataPermissionRuleFactory ruleFactory;
|
|
@Override
|
public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {
|
// 获得 Mapper 对应的数据权限的规则
|
List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(mappedStatementId);
|
if (CollUtil.isEmpty(rules)) {
|
return null;
|
}
|
|
// 生成条件
|
Expression allExpression = null;
|
for (DataPermissionRule rule : rules) {
|
// 判断表名是否匹配
|
String tableName = MyBatisUtils.getTableName(table);
|
if (!rule.getTableNames().contains(tableName)) {
|
continue;
|
}
|
|
// 单条规则的条件
|
Expression oneExpress = rule.getExpression(tableName, table.getAlias());
|
if (oneExpress == null) {
|
continue;
|
}
|
// 拼接到 allExpression 中
|
allExpression = allExpression == null ? oneExpress
|
: new AndExpression(allExpression, oneExpress);
|
}
|
return allExpression;
|
}
|
|
}
|