Browse Source

完善数据权限的单元测试

YunaiV 3 years ago
parent
commit
3fbd394653

+ 3 - 3
yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/DataPermission.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/annotation/DataPermission.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.datapermission.config;
+package cn.iocoder.yudao.framework.datapermission.core.annotation;
 
 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
 
@@ -25,11 +25,11 @@ public @interface DataPermission {
     /**
      * 生效的数据权限规则数组,优先级高于 {@link #excludeRules()}
      */
-    Class<DataPermissionRule>[] includeRules() default {};
+    Class<? extends DataPermissionRule>[] includeRules() default {};
 
     /**
      * 排除的数据权限规则数组,优先级最低
      */
-    Class<DataPermissionRule>[] excludeRules() default {};
+    Class<? extends DataPermissionRule>[] excludeRules() default {};
 
 }

+ 1 - 59
yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptor.java

@@ -129,7 +129,6 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
     @Override
     protected void processUpdate(Update update, int index, String sql, Object obj) {
         final Table table = update.getTable();
-//        update.setWhere(this.andExpression(table, update.getWhere()));
         update.setWhere(this.builderExpression(update.getWhere(), table));
     }
 
@@ -138,28 +137,9 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
      */
     @Override
     protected void processDelete(Delete delete, int index, String sql, Object obj) {
-//        delete.setWhere(this.andExpression(delete.getTable(), delete.getWhere()));
         delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable()));
     }
 
-//    /**
-//     * delete update 语句 where 处理
-//     */
-//    protected BinaryExpression andExpression(Table table, Expression where) {
-//        //获得where条件表达式
-//        EqualsTo equalsTo = new EqualsTo();
-//        equalsTo.setLeftExpression(this.getAliasColumn(table));
-//        equalsTo.setRightExpression(getTenantId());
-//        if (null != where) {
-//            if (where instanceof OrExpression) {
-//                return new AndExpression(equalsTo, new Parenthesis(where));
-//            } else {
-//                return new AndExpression(equalsTo, where);
-//            }
-//        }
-//        return equalsTo;
-//    }
-
     /**
      * 处理 PlainSelect
      */
@@ -169,10 +149,6 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
         processWhereSubSelect(where);
         if (fromItem instanceof Table) {
             Table fromTable = (Table) fromItem;
-//            if (!ignoreTable(fromTable.getName())) {
-//                //#1186 github
-//                plainSelect.setWhere(builderExpression(where, fromTable));
-//            }
             plainSelect.setWhere(builderExpression(where, fromTable));
         } else {
             processFromItem(fromItem);
@@ -261,7 +237,7 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
      * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p>
      * <p> fixed gitee pulls/141</p>
      *
-     * @param function
+     * @param function 函数
      */
     protected void processFunction(Function function) {
         ExpressionList parameters = function.getParameters();
@@ -326,21 +302,12 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
                     processJoin(join);
                     continue;
                 }
-//                // 当前表是否忽略
-//                boolean needIgnore = ignoreTable(fromTable.getName());
-//                // 表名压栈,忽略的表压入 null,以便后续不处理
-//                tables.push(needIgnore ? null : fromTable);
                 tables.push(fromTable);
                 // 尾缀多个 on 表达式的时候统一处理
                 if (originOnExpressions.size() > 1) {
                     Collection<Expression> onExpressions = new LinkedList<>();
                     for (Expression originOnExpression : originOnExpressions) {
                         Table currentTable = tables.poll();
-//                        if (currentTable == null) {
-//                            onExpressions.add(originOnExpression);
-//                        } else {
-//                            onExpressions.add(builderExpression(originOnExpression, currentTable));
-//                        }
                         onExpressions.add(builderExpression(originOnExpression, currentTable));
                     }
                     join.setOnExpressions(onExpressions);
@@ -358,15 +325,6 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
     protected void processJoin(Join join) {
         if (join.getRightItem() instanceof Table) {
             Table fromTable = (Table) join.getRightItem();
-//            if (ignoreTable(fromTable.getName())) {
-//                // 过滤退出执行
-//                return;
-//            }
-            // 走到这里说明 on 表达式肯定只有一个
-//            Collection<Expression> originOnExpressions = join.getOnExpressions();
-//            List<Expression> onExpressions = new LinkedList<>();
-//            onExpressions.add(builderExpression(originOnExpressions.iterator().next(), fromTable));
-//            join.setOnExpressions(onExpressions);
             Expression originOnExpression = CollUtil.getFirst(join.getOnExpressions());
             originOnExpression = builderExpression(originOnExpression, fromTable);
             join.setOnExpressions(CollUtil.newArrayList(originOnExpression));
@@ -395,22 +353,6 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
         return new AndExpression(currentExpression, equalsTo);
     }
 
-//    /**
-//     * 租户字段别名设置
-//     * <p>tenantId 或 tableAlias.tenantId</p>
-//     *
-//     * @param table 表对象
-//     * @return 字段
-//     */
-//    protected Column getAliasColumn(Table table) {
-//        StringBuilder column = new StringBuilder();
-//        if (table.getAlias() != null) {
-//            column.append(table.getAlias().getName()).append(StringPool.DOT);
-//        }
-//        column.append(getTenantIdColumn());
-//        return new Column(column.toString());
-//    }
-
     /**
      * 构建指定表的数据权限的 Expression 过滤条件
      *

+ 108 - 4
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest2.java

@@ -8,13 +8,15 @@ import net.sf.jsqlparser.expression.Alias;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.LongValue;
 import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.InExpression;
 import net.sf.jsqlparser.schema.Column;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
@@ -44,7 +46,8 @@ public class DataPermissionInterceptorTest2 extends BaseMockitoUnitTest {
 
             @Override
             public Set<String> getTableNames() {
-                return asSet("entity", "entity1", "entity2", "t1", "t2");
+                return asSet("entity", "entity1", "entity2", "t1", "t2", // 支持 MyBatis Plus 的单元测试
+                        "t_user", "t_role"); // 满足自己的单元测试
             }
 
             @Override
@@ -54,9 +57,28 @@ public class DataPermissionInterceptorTest2 extends BaseMockitoUnitTest {
                 return new EqualsTo(column, value);
             }
 
+        };
+        // 部门的数据权限规则
+        DataPermissionRule deptRule = new DataPermissionRule() {
+
+            private static final String COLUMN = "dept_id";
+
+            @Override
+            public Set<String> getTableNames() {
+                return asSet("t_user");  // 满足自己的单元测试
+            }
+
+            @Override
+            public Expression getExpression(String tableName, Alias tableAlias) {
+                Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN);
+                ExpressionList values = new ExpressionList(new LongValue(10L),
+                        new LongValue(20L));
+                return new InExpression(column, values);
+            }
+
         };
         // 设置到上下文,保证
-        DataPermissionInterceptor.ContextHolder.init(Collections.singletonList(tenantRule));
+        DataPermissionInterceptor.ContextHolder.init(Arrays.asList(tenantRule, deptRule));
     }
 
     @Test
@@ -252,7 +274,6 @@ public class DataPermissionInterceptorTest2 extends BaseMockitoUnitTest {
 //                "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
     }
 
-
     @Test
     void selectWithAs() {
         assertSql("with with_as_A as (select * from entity) select * from with_as_A",
@@ -263,4 +284,87 @@ public class DataPermissionInterceptorTest2 extends BaseMockitoUnitTest {
         assertEquals(targetSql, interceptor.parserSingle(sql, null));
     }
 
+    // ========== 额外的测试 ==========
+
+    @Test
+    public void testSelectSingle() {
+        // 单表
+        assertSql("select * from t_user where id = ?",
+                "SELECT * FROM t_user WHERE id = ? AND tenant_id = 1 AND dept_id IN (10, 20)");
+
+        assertSql("select * from t_user where id = ? or name = ?",
+                "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)");
+
+        assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)",
+                "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)");
+
+        /* not */
+        assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)",
+                "SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)");
+    }
+
+    @Test
+    public void testSelectLeftJoin() {
+        // left join
+        assertSql("SELECT * FROM t_user e " +
+                        "left join t_role e1 on e1.id = e.id " +
+                        "WHERE e.id = ? OR e.name = ?",
+                "SELECT * FROM t_user e " +
+                        "LEFT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+                        "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");
+
+        // 条件 e.id = ? OR e.name = ? 带括号
+        assertSql("SELECT * FROM t_user e " +
+                        "left join t_role e1 on e1.id = e.id " +
+                        "WHERE (e.id = ? OR e.name = ?)",
+                "SELECT * FROM t_user e " +
+                        "LEFT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+                        "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");
+    }
+
+    @Test
+    public void testSelectRightJoin() {
+        // right join
+        assertSql("SELECT * FROM t_user e " +
+                        "right join t_role e1 on e1.id = e.id " +
+                        "WHERE e.id = ? OR e.name = ?",
+                "SELECT * FROM t_user e " +
+                        "RIGHT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+                        "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");
+
+        // 条件 e.id = ? OR e.name = ? 带括号
+        assertSql("SELECT * FROM t_user e " +
+                        "right join t_role e1 on e1.id = e.id " +
+                        "WHERE (e.id = ? OR e.name = ?)",
+                "SELECT * FROM t_user e " +
+                        "RIGHT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+                        "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");
+    }
+
+    @Test
+    public void testSelectInnerJoin() {
+        // inner join
+        assertSql("SELECT * FROM t_user e " +
+                        "inner join entity1 e1 on e1.id = e.id " +
+                        "WHERE e.id = ? OR e.name = ?",
+                "SELECT * FROM t_user e " +
+                        "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+                        "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");
+
+        // 条件 e.id = ? OR e.name = ? 带括号
+        assertSql("SELECT * FROM t_user e " +
+                        "inner join t_role e1 on e1.id = e.id " +
+                        "WHERE (e.id = ? OR e.name = ?)",
+                "SELECT * FROM t_user e " +
+                        "INNER JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+                        "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");
+
+        // 垃圾 inner join todo
+//        assertSql("SELECT * FROM entity,entity1 " +
+//                "WHERE entity.id = entity1.id",
+//            "SELECT * FROM entity e " +
+//                "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
+//                "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
+    }
+
 }