Commit 8737674d743ea2bcfdb0a50a0d7f007c58753884

Authored by YunaiV
1 parent d8a24262

去除 LoginUser 的 roleIds、deptId 字段,简化

Showing 16 changed files with 179 additions and 189 deletions
yudao-dependencies/pom.xml
@@ -22,7 +22,6 @@ @@ -22,7 +22,6 @@
22 <swagger-annotations.version>1.5.22</swagger-annotations.version> 22 <swagger-annotations.version>1.5.22</swagger-annotations.version>
23 <servlet.versoin>2.5</servlet.versoin> 23 <servlet.versoin>2.5</servlet.versoin>
24 <!-- DB 相关 --> 24 <!-- DB 相关 -->
25 - <mysql.version>5.1.46</mysql.version>  
26 <druid.version>1.2.8</druid.version> 25 <druid.version>1.2.8</druid.version>
27 <mybatis-plus.version>3.4.3.4</mybatis-plus.version> 26 <mybatis-plus.version>3.4.3.4</mybatis-plus.version>
28 <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version> 27 <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
@@ -76,12 +75,6 @@ @@ -76,12 +75,6 @@
76 <version>${spring.boot.version}</version> 75 <version>${spring.boot.version}</version>
77 <type>pom</type> 76 <type>pom</type>
78 <scope>import</scope> 77 <scope>import</scope>
79 - <exclusions>  
80 - <exclusion>  
81 - <groupId>mysql</groupId>  
82 - <artifactId>mysql-connector-java</artifactId>  
83 - </exclusion>  
84 - </exclusions>  
85 </dependency> 78 </dependency>
86 79
87 <!-- 业务组件 --> 80 <!-- 业务组件 -->
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
@@ -54,6 +54,13 @@ public class CollectionUtils { @@ -54,6 +54,13 @@ public class CollectionUtils {
54 return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toList()); 54 return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toList());
55 } 55 }
56 56
  57 + public static <T, U> List<U> convertList(Collection<T> from, Function<T, U> func, Predicate<T> filter) {
  58 + if (CollUtil.isEmpty(from)) {
  59 + return new ArrayList<>();
  60 + }
  61 + return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toList());
  62 + }
  63 +
57 public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) { 64 public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) {
58 if (CollUtil.isEmpty(from)) { 65 if (CollUtil.isEmpty(from)) {
59 return new HashSet<>(); 66 return new HashSet<>();
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRule.java
1 package cn.iocoder.yudao.framework.datapermission.core.dept.rule; 1 package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
5 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;  
6 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 6 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  9 +import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
  10 +import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
9 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule; 11 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
10 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 12 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
11 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 13 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
@@ -13,7 +15,6 @@ import cn.iocoder.yudao.framework.security.core.LoginUser; @@ -13,7 +15,6 @@ import cn.iocoder.yudao.framework.security.core.LoginUser;
13 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; 15 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
14 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; 16 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
15 import lombok.AllArgsConstructor; 17 import lombok.AllArgsConstructor;
16 -import lombok.Getter;  
17 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
18 import net.sf.jsqlparser.expression.Alias; 19 import net.sf.jsqlparser.expression.Alias;
19 import net.sf.jsqlparser.expression.Expression; 20 import net.sf.jsqlparser.expression.Expression;
@@ -24,10 +25,7 @@ import net.sf.jsqlparser.expression.operators.relational.EqualsTo; @@ -24,10 +25,7 @@ import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
24 import net.sf.jsqlparser.expression.operators.relational.ExpressionList; 25 import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
25 import net.sf.jsqlparser.expression.operators.relational.InExpression; 26 import net.sf.jsqlparser.expression.operators.relational.InExpression;
26 27
27 -import java.util.HashMap;  
28 -import java.util.HashSet;  
29 -import java.util.Map;  
30 -import java.util.Set; 28 +import java.util.*;
31 29
32 /** 30 /**
33 * 基于部门的 {@link DataPermissionRule} 数据权限规则实现 31 * 基于部门的 {@link DataPermissionRule} 数据权限规则实现
@@ -50,6 +48,11 @@ import java.util.Set; @@ -50,6 +48,11 @@ import java.util.Set;
50 @Slf4j 48 @Slf4j
51 public class DeptDataPermissionRule implements DataPermissionRule { 49 public class DeptDataPermissionRule implements DataPermissionRule {
52 50
  51 + /**
  52 + * LoginUser 的 Context 缓存 Key
  53 + */
  54 + protected static final String CONTEXT_KEY = DeptDataPermissionRule.class.getSimpleName();
  55 +
53 private static final String DEPT_COLUMN_NAME = "dept_id"; 56 private static final String DEPT_COLUMN_NAME = "dept_id";
54 private static final String USER_COLUMN_NAME = "user_id"; 57 private static final String USER_COLUMN_NAME = "user_id";
55 58
@@ -90,13 +93,23 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -90,13 +93,23 @@ public class DeptDataPermissionRule implements DataPermissionRule {
90 if (loginUser == null) { 93 if (loginUser == null) {
91 return null; 94 return null;
92 } 95 }
  96 + // 只有管理员类型的用户,才进行数据权限的处理
  97 + if (ObjectUtil.notEqual(loginUser.getUserType(), UserTypeEnum.ADMIN.getValue())) {
  98 + return null;
  99 + }
93 100
94 // 获得数据权限 101 // 获得数据权限
95 - DeptDataPermissionRespDTO deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser); 102 + DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);
  103 + // 从上下文中拿不到,则调用逻辑进行获取
96 if (deptDataPermission == null) { 104 if (deptDataPermission == null) {
97 - log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser));  
98 - throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限",  
99 - loginUser.getId(), tableName, tableAlias.getName())); 105 + deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser.getId());
  106 + if (deptDataPermission == null) {
  107 + log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser));
  108 + throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限",
  109 + loginUser.getId(), tableName, tableAlias.getName()));
  110 + }
  111 + // 添加到上下文中,避免重复计算
  112 + loginUser.setContext(CONTEXT_KEY, deptDataPermission);
100 } 113 }
101 114
102 // 情况一,如果是 ALL 可查看全部,则无需拼接条件 115 // 情况一,如果是 ALL 可查看全部,则无需拼接条件
@@ -111,8 +124,8 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -111,8 +124,8 @@ public class DeptDataPermissionRule implements DataPermissionRule {
111 } 124 }
112 125
113 // 情况三,拼接 Dept 和 User 的条件,最后组合 126 // 情况三,拼接 Dept 和 User 的条件,最后组合
114 - Expression deptExpression = this.buildDeptExpression(tableName,tableAlias, deptDataPermission.getDeptIds());  
115 - Expression userExpression = this.buildUserExpression(tableName, tableAlias, deptDataPermission.getSelf(), loginUser.getId()); 127 + Expression deptExpression = buildDeptExpression(tableName,tableAlias, deptDataPermission.getDeptIds());
  128 + Expression userExpression = buildUserExpression(tableName, tableAlias, deptDataPermission.getSelf(), loginUser.getId());
116 if (deptExpression == null && userExpression == null) { 129 if (deptExpression == null && userExpression == null) {
117 // TODO 芋艿:获得不到条件的时候,暂时不抛出异常,而是不返回数据 130 // TODO 芋艿:获得不到条件的时候,暂时不抛出异常,而是不返回数据
118 log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]", 131 log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]",
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/service/DeptDataPermissionFrameworkService.java
1 package cn.iocoder.yudao.framework.datapermission.core.dept.service; 1 package cn.iocoder.yudao.framework.datapermission.core.dept.service;
2 2
3 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 3 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
4 -import cn.iocoder.yudao.framework.security.core.LoginUser;  
5 4
6 /** 5 /**
7 * 基于部门的数据权限 Framework Service 接口 6 * 基于部门的数据权限 Framework Service 接口
@@ -14,9 +13,9 @@ public interface DeptDataPermissionFrameworkService { @@ -14,9 +13,9 @@ public interface DeptDataPermissionFrameworkService {
14 /** 13 /**
15 * 获得登陆用户的部门数据权限 14 * 获得登陆用户的部门数据权限
16 * 15 *
17 - * @param loginUser 登陆用户 16 + * @param userId 用户编号
18 * @return 部门数据权限 17 * @return 部门数据权限
19 */ 18 */
20 - DeptDataPermissionRespDTO getDeptDataPermission(LoginUser loginUser); 19 + DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
21 20
22 } 21 }
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRuleTest.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.datapermission.core.dept.rule; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ReflectUtil; 4 import cn.hutool.core.util.ReflectUtil;
  5 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
5 import cn.iocoder.yudao.framework.common.util.collection.SetUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
6 import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService; 7 import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
7 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 8 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
@@ -69,7 +70,8 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -69,7 +70,8 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
69 String tableName = "t_user"; 70 String tableName = "t_user";
70 Alias tableAlias = new Alias("u"); 71 Alias tableAlias = new Alias("u");
71 // mock 方法 72 // mock 方法
72 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 73 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  74 + .setUserType(UserTypeEnum.ADMIN.getValue()));
73 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 75 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
74 76
75 // 调用 77 // 调用
@@ -88,16 +90,18 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -88,16 +90,18 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
88 String tableName = "t_user"; 90 String tableName = "t_user";
89 Alias tableAlias = new Alias("u"); 91 Alias tableAlias = new Alias("u");
90 // mock 方法(LoginUser) 92 // mock 方法(LoginUser)
91 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 93 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  94 + .setUserType(UserTypeEnum.ADMIN.getValue()));
92 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 95 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
93 // mock 方法(DeptDataPermissionRespDTO) 96 // mock 方法(DeptDataPermissionRespDTO)
94 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true); 97 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true);
95 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission); 98 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
96 99
97 // 调用 100 // 调用
98 Expression expression = rule.getExpression(tableName, tableAlias); 101 Expression expression = rule.getExpression(tableName, tableAlias);
99 // 断言 102 // 断言
100 assertNull(expression); 103 assertNull(expression);
  104 + assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
101 } 105 }
102 } 106 }
103 107
@@ -109,16 +113,18 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -109,16 +113,18 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
109 String tableName = "t_user"; 113 String tableName = "t_user";
110 Alias tableAlias = new Alias("u"); 114 Alias tableAlias = new Alias("u");
111 // mock 方法(LoginUser) 115 // mock 方法(LoginUser)
112 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 116 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  117 + .setUserType(UserTypeEnum.ADMIN.getValue()));
113 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 118 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
114 // mock 方法(DeptDataPermissionRespDTO) 119 // mock 方法(DeptDataPermissionRespDTO)
115 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO(); 120 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO();
116 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission); 121 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
117 122
118 // 调用 123 // 调用
119 Expression expression = rule.getExpression(tableName, tableAlias); 124 Expression expression = rule.getExpression(tableName, tableAlias);
120 // 断言 125 // 断言
121 assertEquals("null = null", expression.toString()); 126 assertEquals("null = null", expression.toString());
  127 + assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
122 } 128 }
123 } 129 }
124 130
@@ -130,17 +136,19 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -130,17 +136,19 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
130 String tableName = "t_user"; 136 String tableName = "t_user";
131 Alias tableAlias = new Alias("u"); 137 Alias tableAlias = new Alias("u");
132 // mock 方法(LoginUser) 138 // mock 方法(LoginUser)
133 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 139 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  140 + .setUserType(UserTypeEnum.ADMIN.getValue()));
134 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 141 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
135 // mock 方法(DeptDataPermissionRespDTO) 142 // mock 方法(DeptDataPermissionRespDTO)
136 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 143 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
137 .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true); 144 .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true);
138 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission); 145 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
139 146
140 // 调用 147 // 调用
141 Expression expression = rule.getExpression(tableName, tableAlias); 148 Expression expression = rule.getExpression(tableName, tableAlias);
142 // 断言 149 // 断言
143 assertSame(EXPRESSION_NULL, expression); 150 assertSame(EXPRESSION_NULL, expression);
  151 + assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
144 } 152 }
145 } 153 }
146 154
@@ -152,12 +160,13 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -152,12 +160,13 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
152 String tableName = "t_user"; 160 String tableName = "t_user";
153 Alias tableAlias = new Alias("u"); 161 Alias tableAlias = new Alias("u");
154 // mock 方法(LoginUser) 162 // mock 方法(LoginUser)
155 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 163 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  164 + .setUserType(UserTypeEnum.ADMIN.getValue()));
156 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 165 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
157 // mock 方法(DeptDataPermissionRespDTO) 166 // mock 方法(DeptDataPermissionRespDTO)
158 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 167 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
159 .setSelf(true); 168 .setSelf(true);
160 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission); 169 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
161 // 添加 user 字段配置 170 // 添加 user 字段配置
162 rule.addUserColumn("t_user", "id"); 171 rule.addUserColumn("t_user", "id");
163 172
@@ -165,6 +174,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -165,6 +174,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
165 Expression expression = rule.getExpression(tableName, tableAlias); 174 Expression expression = rule.getExpression(tableName, tableAlias);
166 // 断言 175 // 断言
167 assertEquals("u.id = 1", expression.toString()); 176 assertEquals("u.id = 1", expression.toString());
  177 + assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
168 } 178 }
169 } 179 }
170 180
@@ -176,12 +186,13 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -176,12 +186,13 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
176 String tableName = "t_user"; 186 String tableName = "t_user";
177 Alias tableAlias = new Alias("u"); 187 Alias tableAlias = new Alias("u");
178 // mock 方法(LoginUser) 188 // mock 方法(LoginUser)
179 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 189 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  190 + .setUserType(UserTypeEnum.ADMIN.getValue()));
180 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 191 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
181 // mock 方法(DeptDataPermissionRespDTO) 192 // mock 方法(DeptDataPermissionRespDTO)
182 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 193 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
183 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)); 194 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L));
184 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission); 195 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
185 // 添加 dept 字段配置 196 // 添加 dept 字段配置
186 rule.addDeptColumn("t_user", "dept_id"); 197 rule.addDeptColumn("t_user", "dept_id");
187 198
@@ -189,6 +200,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -189,6 +200,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
189 Expression expression = rule.getExpression(tableName, tableAlias); 200 Expression expression = rule.getExpression(tableName, tableAlias);
190 // 断言 201 // 断言
191 assertEquals("u.dept_id IN (10, 20)", expression.toString()); 202 assertEquals("u.dept_id IN (10, 20)", expression.toString());
  203 + assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
192 } 204 }
193 } 205 }
194 206
@@ -200,12 +212,13 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -200,12 +212,13 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
200 String tableName = "t_user"; 212 String tableName = "t_user";
201 Alias tableAlias = new Alias("u"); 213 Alias tableAlias = new Alias("u");
202 // mock 方法(LoginUser) 214 // mock 方法(LoginUser)
203 - LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)); 215 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
  216 + .setUserType(UserTypeEnum.ADMIN.getValue()));
204 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 217 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
205 // mock 方法(DeptDataPermissionRespDTO) 218 // mock 方法(DeptDataPermissionRespDTO)
206 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 219 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
207 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true); 220 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true);
208 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission); 221 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
209 // 添加 user 字段配置 222 // 添加 user 字段配置
210 rule.addUserColumn("t_user", "id"); 223 rule.addUserColumn("t_user", "id");
211 // 添加 dept 字段配置 224 // 添加 dept 字段配置
@@ -215,6 +228,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -215,6 +228,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
215 Expression expression = rule.getExpression(tableName, tableAlias); 228 Expression expression = rule.getExpression(tableName, tableAlias);
216 // 断言 229 // 断言
217 assertEquals("u.dept_id IN (10, 20) OR u.id = 1", expression.toString()); 230 assertEquals("u.dept_id IN (10, 20) OR u.id = 1", expression.toString());
  231 + assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
218 } 232 }
219 } 233 }
220 234
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java
@@ -50,17 +50,6 @@ public class LoginUser implements UserDetails { @@ -50,17 +50,6 @@ public class LoginUser implements UserDetails {
50 */ 50 */
51 private Long tenantId; 51 private Long tenantId;
52 52
53 - // ========== UserTypeEnum.ADMIN 独有字段 ==========  
54 - // TODO 芋艿:可以通过定义一个 Map<String, String> exts 的方式,去除管理员的字段。不过这样会导致系统比较复杂,所以暂时不去掉先;  
55 - /**  
56 - * 角色编号数组  
57 - */  
58 - private Set<Long> roleIds;  
59 - /**  
60 - * 部门编号  
61 - */  
62 - private Long deptId;  
63 -  
64 // ========== 上下文 ========== 53 // ========== 上下文 ==========
65 /** 54 /**
66 * 上下文字段,不进行持久化 55 * 上下文字段,不进行持久化
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
@@ -11,7 +11,6 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS @@ -11,7 +11,6 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
11 import org.springframework.util.StringUtils; 11 import org.springframework.util.StringUtils;
12 12
13 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletRequest;
14 -import java.util.Set;  
15 14
16 /** 15 /**
17 * 安全服务工具类 16 * 安全服务工具类
@@ -80,17 +79,6 @@ public class SecurityFrameworkUtils { @@ -80,17 +79,6 @@ public class SecurityFrameworkUtils {
80 } 79 }
81 80
82 /** 81 /**
83 - * 获得当前用户的角色编号数组  
84 - *  
85 - * @return 角色编号数组  
86 - */  
87 - @Nullable  
88 - public static Set<Long> getLoginUserRoleIds() {  
89 - LoginUser loginUser = getLoginUser();  
90 - return loginUser != null ? loginUser.getRoleIds() : null;  
91 - }  
92 -  
93 - /**  
94 * 设置当前用户 82 * 设置当前用户
95 * 83 *
96 * @param loginUser 登录用户 84 * @param loginUser 登录用户
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
@@ -84,7 +84,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -84,7 +84,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
84 @Override 84 @Override
85 public String login(AppAuthLoginReqVO reqVO, String userIp, String userAgent) { 85 public String login(AppAuthLoginReqVO reqVO, String userIp, String userAgent) {
86 // 使用手机 + 密码,进行登录。 86 // 使用手机 + 密码,进行登录。
87 - LoginUser loginUser = this.login0(reqVO.getMobile(), reqVO.getPassword()); 87 + LoginUser loginUser = login0(reqVO.getMobile(), reqVO.getPassword());
88 88
89 // 缓存登录用户到 Redis 中,返回 Token 令牌 89 // 缓存登录用户到 Redis 中,返回 Token 令牌
90 return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent); 90 return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
@@ -26,12 +26,13 @@ import org.springframework.web.bind.annotation.*; @@ -26,12 +26,13 @@ import org.springframework.web.bind.annotation.*;
26 import javax.annotation.Resource; 26 import javax.annotation.Resource;
27 import javax.validation.Valid; 27 import javax.validation.Valid;
28 import java.util.List; 28 import java.util.List;
  29 +import java.util.Set;
29 30
30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 31 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
31 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; 32 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
32 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; 33 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent;
33 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 34 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
34 -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserRoleIds; 35 +import static java.util.Collections.singleton;
35 36
36 @Api(tags = "管理后台 - 认证") 37 @Api(tags = "管理后台 - 认证")
37 @RestController 38 @RestController
@@ -69,12 +70,12 @@ public class AuthController { @@ -69,12 +70,12 @@ public class AuthController {
69 return null; 70 return null;
70 } 71 }
71 // 获得角色列表 72 // 获得角色列表
72 - List<RoleDO> roleList = roleService.getRolesFromCache(getLoginUserRoleIds()); 73 + Set<Long> roleIds = permissionService.getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
  74 + List<RoleDO> roleList = roleService.getRolesFromCache(roleIds);
73 // 获得菜单列表 75 // 获得菜单列表
74 - List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(  
75 - getLoginUserRoleIds(), // 注意,基于登录的角色,因为后续的权限判断也是基于它 76 + List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(roleIds,
76 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()), 77 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()),
77 - SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); 78 + singleton(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的
78 // 拼接结果返回 79 // 拼接结果返回
79 return success(AuthConvert.INSTANCE.convert(user, roleList, menuList)); 80 return success(AuthConvert.INSTANCE.convert(user, roleList, menuList));
80 } 81 }
@@ -82,11 +83,12 @@ public class AuthController { @@ -82,11 +83,12 @@ public class AuthController {
82 @GetMapping("/list-menus") 83 @GetMapping("/list-menus")
83 @ApiOperation("获得登录用户的菜单列表") 84 @ApiOperation("获得登录用户的菜单列表")
84 public CommonResult<List<AuthMenuRespVO>> getMenus() { 85 public CommonResult<List<AuthMenuRespVO>> getMenus() {
  86 + // 获得角色列表
  87 + Set<Long> roleIds = permissionService.getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
85 // 获得用户拥有的菜单列表 88 // 获得用户拥有的菜单列表
86 - List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(  
87 - getLoginUserRoleIds(), // 注意,基于登录的角色,因为后续的权限判断也是基于它 89 + List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(roleIds,
88 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型 90 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型
89 - SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的 91 + singleton(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的
90 // 转换成 Tree 结构返回 92 // 转换成 Tree 结构返回
91 return success(AuthConvert.INSTANCE.buildMenuTree(menuList)); 93 return success(AuthConvert.INSTANCE.buildMenuTree(menuList));
92 } 94 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/UserSessionController.java
1 package cn.iocoder.yudao.module.system.controller.admin.auth; 1 package cn.iocoder.yudao.module.system.controller.admin.auth;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
3 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageItemRespVO; 7 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageItemRespVO;
4 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO; 8 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
5 import cn.iocoder.yudao.module.system.convert.auth.UserSessionConvert; 9 import cn.iocoder.yudao.module.system.convert.auth.UserSessionConvert;
6 import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
7 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
8 -import cn.iocoder.yudao.module.system.service.auth.UserSessionService;  
9 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 12 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
10 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
11 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
12 -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 13 +import cn.iocoder.yudao.module.system.service.auth.UserSessionService;
13 import cn.iocoder.yudao.module.system.service.dept.DeptService; 14 import cn.iocoder.yudao.module.system.service.dept.DeptService;
14 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 15 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
15 import io.swagger.annotations.Api; 16 import io.swagger.annotations.Api;
@@ -49,7 +50,8 @@ public class UserSessionController { @@ -49,7 +50,8 @@ public class UserSessionController {
49 50
50 // 获得拼接需要的数据 51 // 获得拼接需要的数据
51 Map<Long, AdminUserDO> userMap = userService.getUserMap( 52 Map<Long, AdminUserDO> userMap = userService.getUserMap(
52 - convertList(pageResult.getList(), UserSessionDO::getUserId)); 53 + convertList(pageResult.getList(), UserSessionDO::getUserId,
  54 + session -> session.getUserType().equals(UserTypeEnum.ADMIN.getValue())));
53 Map<Long, DeptDO> deptMap = deptService.getDeptMap( 55 Map<Long, DeptDO> deptMap = deptService.getDeptMap(
54 convertList(userMap.values(), AdminUserDO::getDeptId)); 56 convertList(userMap.values(), AdminUserDO::getDeptId));
55 // 拼接结果返回 57 // 拼接结果返回
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
@@ -17,7 +17,6 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; @@ -17,7 +17,6 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
17 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; 17 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
18 import cn.iocoder.yudao.module.system.service.common.CaptchaService; 18 import cn.iocoder.yudao.module.system.service.common.CaptchaService;
19 import cn.iocoder.yudao.module.system.service.logger.LoginLogService; 19 import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
20 -import cn.iocoder.yudao.module.system.service.permission.PermissionService;  
21 import cn.iocoder.yudao.module.system.service.social.SocialUserService; 20 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
22 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 21 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
23 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
@@ -36,12 +35,10 @@ import org.springframework.util.Assert; @@ -36,12 +35,10 @@ import org.springframework.util.Assert;
36 import javax.annotation.Resource; 35 import javax.annotation.Resource;
37 import javax.validation.Validator; 36 import javax.validation.Validator;
38 import java.util.Objects; 37 import java.util.Objects;
39 -import java.util.Set;  
40 38
41 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 39 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
42 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; 40 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
43 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; 41 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
44 -import static java.util.Collections.singleton;  
45 42
46 /** 43 /**
47 * Auth Service 实现类 44 * Auth Service 实现类
@@ -60,8 +57,6 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -60,8 +57,6 @@ public class AdminAuthServiceImpl implements AdminAuthService {
60 @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // UserService 存在重名 57 @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // UserService 存在重名
61 private AdminUserService userService; 58 private AdminUserService userService;
62 @Resource 59 @Resource
63 - private PermissionService permissionService;  
64 - @Resource  
65 private CaptchaService captchaService; 60 private CaptchaService captchaService;
66 @Resource 61 @Resource
67 private LoginLogService loginLogService; 62 private LoginLogService loginLogService;
@@ -211,16 +206,6 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -211,16 +206,6 @@ public class AdminAuthServiceImpl implements AdminAuthService {
211 } 206 }
212 } 207 }
213 208
214 - /**  
215 - * 获得 User 拥有的角色编号数组  
216 - *  
217 - * @param userId 用户编号  
218 - * @return 角色编号数组  
219 - */  
220 - private Set<Long> getUserRoleIds(Long userId) {  
221 - return permissionService.getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));  
222 - }  
223 -  
224 @Override 209 @Override
225 public String socialQuickLogin(AuthSocialQuickLoginReqVO reqVO, String userIp, String userAgent) { 210 public String socialQuickLogin(AuthSocialQuickLoginReqVO reqVO, String userIp, String userAgent) {
226 // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 211 // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
@@ -318,17 +303,13 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -318,17 +303,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
318 } 303 }
319 304
320 // 刷新 LoginUser 缓存 305 // 刷新 LoginUser 缓存
321 - LoginUser newLoginUser= this.buildLoginUser(user); 306 + LoginUser newLoginUser= buildLoginUser(user);
322 userSessionService.refreshUserSession(token, newLoginUser); 307 userSessionService.refreshUserSession(token, newLoginUser);
323 return newLoginUser; 308 return newLoginUser;
324 } 309 }
325 310
326 private LoginUser buildLoginUser(AdminUserDO user) { 311 private LoginUser buildLoginUser(AdminUserDO user) {
327 - LoginUser loginUser = AuthConvert.INSTANCE.convert(user);  
328 - // 补全字段  
329 - loginUser.setDeptId(user.getDeptId());  
330 - loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId()));  
331 - return loginUser; 312 + return AuthConvert.INSTANCE.convert(user);
332 } 313 }
333 314
334 } 315 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
@@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.system.service.permission; @@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.system.service.permission;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.CollectionUtil; 4 import cn.hutool.core.collection.CollectionUtil;
5 import cn.hutool.core.util.ArrayUtil; 5 import cn.hutool.core.util.ArrayUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 8 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 9 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  10 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
9 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 11 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
10 -import cn.iocoder.yudao.framework.security.core.LoginUser;  
11 -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;  
12 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; 12 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
13 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 13 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
14 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; 14 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
@@ -22,6 +22,8 @@ import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper; @@ -22,6 +22,8 @@ import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
22 import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; 22 import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
23 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer; 23 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
24 import cn.iocoder.yudao.module.system.service.dept.DeptService; 24 import cn.iocoder.yudao.module.system.service.dept.DeptService;
  25 +import cn.iocoder.yudao.module.system.service.user.AdminUserService;
  26 +import com.google.common.base.Suppliers;
25 import com.google.common.collect.ImmutableMultimap; 27 import com.google.common.collect.ImmutableMultimap;
26 import com.google.common.collect.Multimap; 28 import com.google.common.collect.Multimap;
27 import com.google.common.collect.Sets; 29 import com.google.common.collect.Sets;
@@ -36,6 +38,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager @@ -36,6 +38,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
36 import javax.annotation.PostConstruct; 38 import javax.annotation.PostConstruct;
37 import javax.annotation.Resource; 39 import javax.annotation.Resource;
38 import java.util.*; 40 import java.util.*;
  41 +import java.util.function.Supplier;
  42 +
  43 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  44 +import static java.util.Collections.singleton;
39 45
40 /** 46 /**
41 * 权限 Service 实现类 47 * 权限 Service 实现类
@@ -47,11 +53,6 @@ import java.util.*; @@ -47,11 +53,6 @@ import java.util.*;
47 public class PermissionServiceImpl implements PermissionService { 53 public class PermissionServiceImpl implements PermissionService {
48 54
49 /** 55 /**
50 - * LoginUser 的 Context 缓存 Key  
51 - */  
52 - public static final String CONTEXT_KEY = PermissionServiceImpl.class.getSimpleName();  
53 -  
54 - /**  
55 * 定时执行 {@link #schedulePeriodicRefresh()} 的周期 56 * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
56 * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高 57 * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
57 */ 58 */
@@ -93,6 +94,8 @@ public class PermissionServiceImpl implements PermissionService { @@ -93,6 +94,8 @@ public class PermissionServiceImpl implements PermissionService {
93 private MenuService menuService; 94 private MenuService menuService;
94 @Resource 95 @Resource
95 private DeptService deptService; 96 private DeptService deptService;
  97 + @Resource
  98 + private AdminUserService userService;
96 99
97 @Resource 100 @Resource
98 private PermissionProducer permissionProducer; 101 private PermissionProducer permissionProducer;
@@ -319,7 +322,7 @@ public class PermissionServiceImpl implements PermissionService { @@ -319,7 +322,7 @@ public class PermissionServiceImpl implements PermissionService {
319 } 322 }
320 323
321 // 获得当前登录的角色。如果为空,说明没有权限 324 // 获得当前登录的角色。如果为空,说明没有权限
322 - Set<Long> roleIds = SecurityFrameworkUtils.getLoginUserRoleIds(); 325 + Set<Long> roleIds = getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
323 if (CollUtil.isEmpty(roleIds)) { 326 if (CollUtil.isEmpty(roleIds)) {
324 return false; 327 return false;
325 } 328 }
@@ -354,7 +357,7 @@ public class PermissionServiceImpl implements PermissionService { @@ -354,7 +357,7 @@ public class PermissionServiceImpl implements PermissionService {
354 } 357 }
355 358
356 // 获得当前登录的角色。如果为空,说明没有权限 359 // 获得当前登录的角色。如果为空,说明没有权限
357 - Set<Long> roleIds = SecurityFrameworkUtils.getLoginUserRoleIds(); 360 + Set<Long> roleIds = getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
358 if (CollUtil.isEmpty(roleIds)) { 361 if (CollUtil.isEmpty(roleIds)) {
359 return false; 362 return false;
360 } 363 }
@@ -368,16 +371,18 @@ public class PermissionServiceImpl implements PermissionService { @@ -368,16 +371,18 @@ public class PermissionServiceImpl implements PermissionService {
368 } 371 }
369 372
370 @Override 373 @Override
371 - public DeptDataPermissionRespDTO getDeptDataPermission(LoginUser loginUser) {  
372 - // 判断是否 context 已经缓存  
373 - DeptDataPermissionRespDTO result = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);  
374 - if (result != null) { 374 + @DataPermission(enable = false) // 关闭数据权限,不然就会出现递归获取数据权限的问题
  375 + public DeptDataPermissionRespDTO getDeptDataPermission(Long userId) {
  376 + DeptDataPermissionRespDTO result = new DeptDataPermissionRespDTO();
  377 + // 获得用户的角色
  378 + Set<Long> roleIds = getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
  379 + if (CollUtil.isEmpty(roleIds)) {
375 return result; 380 return result;
376 } 381 }
377 -  
378 - // 创建 DeptDataPermissionRespDTO 对象  
379 - result = new DeptDataPermissionRespDTO();  
380 - List<RoleDO> roles = roleService.getRolesFromCache(loginUser.getRoleIds()); 382 + List<RoleDO> roles = roleService.getRolesFromCache(roleIds);
  383 + // 获得用户的部门编号的缓存,通过 Guava 的 Suppliers 惰性求值,即有且仅有第一次发起 DB 的查询
  384 + Supplier<Long> userDeptIdCache = Suppliers.memoize(() -> userService.getUser(userId).getDeptId());
  385 + // 遍历每个角色,计算
381 for (RoleDO role : roles) { 386 for (RoleDO role : roles) {
382 // 为空时,跳过 387 // 为空时,跳过
383 if (role.getDataScope() == null) { 388 if (role.getDataScope() == null) {
@@ -393,20 +398,20 @@ public class PermissionServiceImpl implements PermissionService { @@ -393,20 +398,20 @@ public class PermissionServiceImpl implements PermissionService {
393 CollUtil.addAll(result.getDeptIds(), role.getDataScopeDeptIds()); 398 CollUtil.addAll(result.getDeptIds(), role.getDataScopeDeptIds());
394 // 自定义可见部门时,保证可以看到自己所在的部门。否则,一些场景下可能会有问题。 399 // 自定义可见部门时,保证可以看到自己所在的部门。否则,一些场景下可能会有问题。
395 // 例如说,登录时,基于 t_user 的 username 查询会可能被 dept_id 过滤掉 400 // 例如说,登录时,基于 t_user 的 username 查询会可能被 dept_id 过滤掉
396 - CollUtil.addAll(result.getDeptIds(), loginUser.getDeptId()); 401 + CollUtil.addAll(result.getDeptIds(), userDeptIdCache.get());
397 continue; 402 continue;
398 } 403 }
399 // 情况三,DEPT_ONLY 404 // 情况三,DEPT_ONLY
400 if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_ONLY.getScope())) { 405 if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_ONLY.getScope())) {
401 - CollectionUtils.addIfNotNull(result.getDeptIds(), loginUser.getDeptId()); 406 + CollectionUtils.addIfNotNull(result.getDeptIds(), userDeptIdCache.get());
402 continue; 407 continue;
403 } 408 }
404 // 情况四,DEPT_DEPT_AND_CHILD 409 // 情况四,DEPT_DEPT_AND_CHILD
405 if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_AND_CHILD.getScope())) { 410 if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_AND_CHILD.getScope())) {
406 - List<DeptDO> depts = deptService.getDeptsByParentIdFromCache(loginUser.getDeptId(), true); 411 + List<DeptDO> depts = deptService.getDeptsByParentIdFromCache(userDeptIdCache.get(), true);
407 CollUtil.addAll(result.getDeptIds(), CollectionUtils.convertList(depts, DeptDO::getId)); 412 CollUtil.addAll(result.getDeptIds(), CollectionUtils.convertList(depts, DeptDO::getId));
408 - //添加本身部门id  
409 - CollUtil.addAll(result.getDeptIds(), loginUser.getDeptId()); 413 + // 添加本身部门编号
  414 + CollUtil.addAll(result.getDeptIds(), userDeptIdCache.get());
410 continue; 415 continue;
411 } 416 }
412 // 情况五,SELF 417 // 情况五,SELF
@@ -415,11 +420,8 @@ public class PermissionServiceImpl implements PermissionService { @@ -415,11 +420,8 @@ public class PermissionServiceImpl implements PermissionService {
415 continue; 420 continue;
416 } 421 }
417 // 未知情况,error log 即可 422 // 未知情况,error log 即可
418 - log.error("[getDeptDataPermission][LoginUser({}) role({}) 无法处理]", loginUser.getId(), JsonUtils.toJsonString(result)); 423 + log.error("[getDeptDataPermission][LoginUser({}) role({}) 无法处理]", userId, JsonUtils.toJsonString(result));
419 } 424 }
420 -  
421 - // 添加到缓存,并返回  
422 - loginUser.setContext(CONTEXT_KEY, result);  
423 return result; 425 return result;
424 } 426 }
425 427
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
@@ -81,6 +81,7 @@ public class TenantServiceImpl implements TenantService { @@ -81,6 +81,7 @@ public class TenantServiceImpl implements TenantService {
81 @Getter 81 @Getter
82 private volatile Date maxUpdateTime; 82 private volatile Date maxUpdateTime;
83 83
  84 + @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
84 @Autowired(required = false) // 由于 yudao.tenant.enable 配置项,可以关闭多租户的功能,所以这里只能不强制注入 85 @Autowired(required = false) // 由于 yudao.tenant.enable 配置项,可以关闭多租户的功能,所以这里只能不强制注入
85 private TenantProperties tenantProperties; 86 private TenantProperties tenantProperties;
86 87
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
@@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.system.service.tenant.TenantService; @@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.system.service.tenant.TenantService;
25 import com.google.common.annotations.VisibleForTesting; 25 import com.google.common.annotations.VisibleForTesting;
26 import lombok.extern.slf4j.Slf4j; 26 import lombok.extern.slf4j.Slf4j;
27 import org.springframework.beans.factory.annotation.Value; 27 import org.springframework.beans.factory.annotation.Value;
  28 +import org.springframework.context.annotation.Lazy;
28 import org.springframework.security.crypto.password.PasswordEncoder; 29 import org.springframework.security.crypto.password.PasswordEncoder;
29 import org.springframework.stereotype.Service; 30 import org.springframework.stereotype.Service;
30 import org.springframework.transaction.annotation.Transactional; 31 import org.springframework.transaction.annotation.Transactional;
@@ -61,6 +62,7 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -61,6 +62,7 @@ public class AdminUserServiceImpl implements AdminUserService {
61 @Resource 62 @Resource
62 private PasswordEncoder passwordEncoder; 63 private PasswordEncoder passwordEncoder;
63 @Resource 64 @Resource
  65 + @Lazy // 延迟,避免循环依赖报错
64 private TenantService tenantService; 66 private TenantService tenantService;
65 67
66 @Resource 68 @Resource
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java
1 package cn.iocoder.yudao.module.system.service.auth; 1 package cn.iocoder.yudao.module.system.service.auth;
2 2
3 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
4 import cn.iocoder.yudao.framework.security.core.LoginUser; 3 import cn.iocoder.yudao.framework.security.core.LoginUser;
5 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
6 import cn.iocoder.yudao.framework.test.core.util.AssertUtils; 5 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
@@ -12,7 +11,6 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; @@ -12,7 +11,6 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
12 import cn.iocoder.yudao.module.system.service.common.CaptchaService; 11 import cn.iocoder.yudao.module.system.service.common.CaptchaService;
13 import cn.iocoder.yudao.module.system.service.dept.PostService; 12 import cn.iocoder.yudao.module.system.service.dept.PostService;
14 import cn.iocoder.yudao.module.system.service.logger.LoginLogService; 13 import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
15 -import cn.iocoder.yudao.module.system.service.permission.PermissionService;  
16 import cn.iocoder.yudao.module.system.service.social.SocialUserService; 14 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
17 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 15 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
18 import org.junit.jupiter.api.BeforeEach; 16 import org.junit.jupiter.api.BeforeEach;
@@ -34,7 +32,6 @@ import java.util.Set; @@ -34,7 +32,6 @@ import java.util.Set;
34 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 32 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
35 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; 33 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
36 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; 34 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
37 -import static java.util.Collections.singleton;  
38 import static org.junit.jupiter.api.Assertions.assertEquals; 35 import static org.junit.jupiter.api.Assertions.assertEquals;
39 import static org.junit.jupiter.api.Assertions.assertThrows; 36 import static org.junit.jupiter.api.Assertions.assertThrows;
40 import static org.mockito.ArgumentMatchers.eq; 37 import static org.mockito.ArgumentMatchers.eq;
@@ -49,8 +46,6 @@ public class AuthServiceImplTest extends BaseDbUnitTest { @@ -49,8 +46,6 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
49 @MockBean 46 @MockBean
50 private AdminUserService userService; 47 private AdminUserService userService;
51 @MockBean 48 @MockBean
52 - private PermissionService permissionService;  
53 - @MockBean  
54 private AuthenticationManager authenticationManager; 49 private AuthenticationManager authenticationManager;
55 @MockBean 50 @MockBean
56 private Authentication authentication; 51 private Authentication authentication;
@@ -108,16 +103,11 @@ public class AuthServiceImplTest extends BaseDbUnitTest { @@ -108,16 +103,11 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
108 // mock 方法 01 103 // mock 方法 01
109 AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); 104 AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId));
110 when(userService.getUser(eq(userId))).thenReturn(user); 105 when(userService.getUser(eq(userId))).thenReturn(user);
111 - // mock 方法 02  
112 - Set<Long> roleIds = randomSet(Long.class);  
113 - when(permissionService.getUserRoleIds(eq(userId), eq(singleton(CommonStatusEnum.ENABLE.getStatus()))))  
114 - .thenReturn(roleIds);  
115 106
116 // 调用 107 // 调用
117 LoginUser loginUser = authService.mockLogin(userId); 108 LoginUser loginUser = authService.mockLogin(userId);
118 // 断言 109 // 断言
119 AssertUtils.assertPojoEquals(user, loginUser, "updateTime"); 110 AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
120 - assertEquals(roleIds, loginUser.getRoleIds());  
121 } 111 }
122 112
123 @Test 113 @Test
@@ -247,15 +237,10 @@ public class AuthServiceImplTest extends BaseDbUnitTest { @@ -247,15 +237,10 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
247 // mock authentication 237 // mock authentication
248 Long userId = randomLongId(); 238 Long userId = randomLongId();
249 Set<Long> userRoleIds = randomSet(Long.class); 239 Set<Long> userRoleIds = randomSet(Long.class);
250 - LoginUser loginUser = randomPojo(LoginUser.class, o -> {  
251 - o.setId(userId);  
252 - o.setRoleIds(userRoleIds);  
253 - }); 240 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(userId));
254 when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword()))) 241 when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
255 .thenReturn(authentication); 242 .thenReturn(authentication);
256 when(authentication.getPrincipal()).thenReturn(loginUser); 243 when(authentication.getPrincipal()).thenReturn(loginUser);
257 - // mock 获得 User 拥有的角色编号数组  
258 - when(permissionService.getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()))).thenReturn(userRoleIds);  
259 // mock 缓存登录用户到 Redis 244 // mock 缓存登录用户到 Redis
260 String token = randomString(); 245 String token = randomString();
261 when(userSessionService.createUserSession(loginUser, userIp, userAgent)).thenReturn(token); 246 when(userSessionService.createUserSession(loginUser, userIp, userAgent)).thenReturn(token);
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
1 package cn.iocoder.yudao.module.system.service.permission; 1 package cn.iocoder.yudao.module.system.service.permission;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
4 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 7 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
5 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; 8 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
6 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO; 9 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
7 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
  11 +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
8 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper; 12 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper;
9 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper; 13 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
10 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper; 14 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper;
11 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper; 15 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
  16 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
12 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer; 17 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
13 import cn.iocoder.yudao.module.system.service.dept.DeptService; 18 import cn.iocoder.yudao.module.system.service.dept.DeptService;
14 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;  
15 -import cn.iocoder.yudao.framework.security.core.LoginUser;  
16 -import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;  
17 -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 19 +import cn.iocoder.yudao.module.system.service.user.AdminUserService;
18 import org.junit.jupiter.api.Test; 20 import org.junit.jupiter.api.Test;
19 import org.springframework.boot.test.mock.mockito.MockBean; 21 import org.springframework.boot.test.mock.mockito.MockBean;
20 import org.springframework.context.annotation.Import; 22 import org.springframework.context.annotation.Import;
@@ -25,10 +27,10 @@ import java.util.List; @@ -25,10 +27,10 @@ import java.util.List;
25 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
26 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; 28 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
27 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 29 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  30 +import static java.util.Collections.singleton;
28 import static java.util.Collections.singletonList; 31 import static java.util.Collections.singletonList;
29 import static org.junit.jupiter.api.Assertions.*; 32 import static org.junit.jupiter.api.Assertions.*;
30 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.ArgumentMatchers.eq;
31 -import static org.mockito.ArgumentMatchers.same;  
32 import static org.mockito.Mockito.verify; 34 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when; 35 import static org.mockito.Mockito.when;
34 36
@@ -55,6 +57,9 @@ public class PermissionServiceTest extends BaseDbUnitTest { @@ -55,6 +57,9 @@ public class PermissionServiceTest extends BaseDbUnitTest {
55 @MockBean 57 @MockBean
56 private DeptService deptService; 58 private DeptService deptService;
57 @MockBean 59 @MockBean
  60 + private AdminUserService userService;
  61 +
  62 + @MockBean
58 private PermissionProducer permissionProducer; 63 private PermissionProducer permissionProducer;
59 64
60 @Test 65 @Test
@@ -124,112 +129,119 @@ public class PermissionServiceTest extends BaseDbUnitTest { @@ -124,112 +129,119 @@ public class PermissionServiceTest extends BaseDbUnitTest {
124 assertPojoEquals(dbUserRoles.get(0), userRoleDO02); 129 assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
125 } 130 }
126 131
127 - @Test // 测试从 context 获取的场景  
128 - public void testGetDeptDataPermission_fromContext() {  
129 - // 准备参数  
130 - LoginUser loginUser = randomPojo(LoginUser.class);  
131 - // mock 方法  
132 - DeptDataPermissionRespDTO respDTO = new DeptDataPermissionRespDTO();  
133 - loginUser.setContext(PermissionServiceImpl.CONTEXT_KEY, respDTO);  
134 -  
135 - // 调用  
136 - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);  
137 - // 断言  
138 - assertSame(respDTO, result);  
139 - }  
140 -  
141 @Test 132 @Test
142 public void testGetDeptDataPermission_All() { 133 public void testGetDeptDataPermission_All() {
143 // 准备参数 134 // 准备参数
144 - LoginUser loginUser = randomPojo(LoginUser.class);  
145 - // mock 方法  
146 - RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.ALL.getScope()));  
147 - when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO)); 135 + Long userId = 1L;
  136 + // mock 用户的角色编号
  137 + userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L));
  138 + // mock 获得用户的角色
  139 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.ALL.getScope())
  140 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  141 + when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO));
  142 + when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO);
148 143
149 // 调用 144 // 调用
150 - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser); 145 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
151 // 断言 146 // 断言
152 assertTrue(result.getAll()); 147 assertTrue(result.getAll());
153 assertFalse(result.getSelf()); 148 assertFalse(result.getSelf());
154 assertTrue(CollUtil.isEmpty(result.getDeptIds())); 149 assertTrue(CollUtil.isEmpty(result.getDeptIds()));
155 - assertSame(result, loginUser.getContext(PermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));  
156 } 150 }
157 151
158 @Test 152 @Test
159 public void testGetDeptDataPermission_DeptCustom() { 153 public void testGetDeptDataPermission_DeptCustom() {
160 // 准备参数 154 // 准备参数
161 - LoginUser loginUser = randomPojo(LoginUser.class);  
162 - // mock 方法  
163 - RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope()));  
164 - when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO)); 155 + Long userId = 1L;
  156 + // mock 用户的角色编号
  157 + userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L));
  158 + // mock 获得用户的角色
  159 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope())
  160 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  161 + when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO));
  162 + when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO);
  163 + // mock 部门的返回
  164 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用
165 165
166 // 调用 166 // 调用
167 - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser); 167 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(1L);
168 // 断言 168 // 断言
169 assertFalse(result.getAll()); 169 assertFalse(result.getAll());
170 assertFalse(result.getSelf()); 170 assertFalse(result.getSelf());
171 assertEquals(roleDO.getDataScopeDeptIds().size() + 1, result.getDeptIds().size()); 171 assertEquals(roleDO.getDataScopeDeptIds().size() + 1, result.getDeptIds().size());
172 assertTrue(CollUtil.containsAll(result.getDeptIds(), roleDO.getDataScopeDeptIds())); 172 assertTrue(CollUtil.containsAll(result.getDeptIds(), roleDO.getDataScopeDeptIds()));
173 - assertTrue(CollUtil.contains(result.getDeptIds(), loginUser.getDeptId()));  
174 - assertSame(result, loginUser.getContext(PermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); 173 + assertTrue(CollUtil.contains(result.getDeptIds(), 3L));
175 } 174 }
176 175
177 @Test 176 @Test
178 public void testGetDeptDataPermission_DeptOnly() { 177 public void testGetDeptDataPermission_DeptOnly() {
179 // 准备参数 178 // 准备参数
180 - LoginUser loginUser = randomPojo(LoginUser.class);  
181 - // mock 方法  
182 - RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_ONLY.getScope()));  
183 - when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO)); 179 + Long userId = 1L;
  180 + // mock 用户的角色编号
  181 + userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L));
  182 + // mock 获得用户的角色
  183 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_ONLY.getScope())
  184 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  185 + when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO));
  186 + when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO);
  187 + // mock 部门的返回
  188 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用
184 189
185 // 调用 190 // 调用
186 - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser); 191 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(1L);
187 // 断言 192 // 断言
188 assertFalse(result.getAll()); 193 assertFalse(result.getAll());
189 assertFalse(result.getSelf()); 194 assertFalse(result.getSelf());
190 assertEquals(1, result.getDeptIds().size()); 195 assertEquals(1, result.getDeptIds().size());
191 - assertTrue(CollUtil.contains(result.getDeptIds(), loginUser.getDeptId()));  
192 - assertSame(result, loginUser.getContext(PermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); 196 + assertTrue(CollUtil.contains(result.getDeptIds(), 3L));
193 } 197 }
194 198
195 @Test 199 @Test
196 public void testGetDeptDataPermission_DeptAndChild() { 200 public void testGetDeptDataPermission_DeptAndChild() {
197 // 准备参数 201 // 准备参数
198 - LoginUser loginUser = randomPojo(LoginUser.class);  
199 - // mock 方法(角色)  
200 - RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope()));  
201 - when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO)); 202 + Long userId = 1L;
  203 + // mock 用户的角色编号
  204 + userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L));
  205 + // mock 获得用户的角色
  206 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope())
  207 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  208 + when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO));
  209 + when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO);
  210 + // mock 部门的返回
  211 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用
202 // mock 方法(部门) 212 // mock 方法(部门)
203 DeptDO deptDO = randomPojo(DeptDO.class); 213 DeptDO deptDO = randomPojo(DeptDO.class);
204 - when(deptService.getDeptsByParentIdFromCache(eq(loginUser.getDeptId()), eq(true))) 214 + when(deptService.getDeptsByParentIdFromCache(eq(3L), eq(true)))
205 .thenReturn(singletonList(deptDO)); 215 .thenReturn(singletonList(deptDO));
206 216
207 // 调用 217 // 调用
208 - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser); 218 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
209 // 断言 219 // 断言
210 assertFalse(result.getAll()); 220 assertFalse(result.getAll());
211 assertFalse(result.getSelf()); 221 assertFalse(result.getSelf());
212 assertEquals(2, result.getDeptIds().size()); 222 assertEquals(2, result.getDeptIds().size());
213 assertTrue(CollUtil.contains(result.getDeptIds(), deptDO.getId())); 223 assertTrue(CollUtil.contains(result.getDeptIds(), deptDO.getId()));
214 - assertTrue(CollUtil.contains(result.getDeptIds(), loginUser.getDeptId()));  
215 - assertSame(result, loginUser.getContext(PermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); 224 + assertTrue(CollUtil.contains(result.getDeptIds(), 3L));
216 } 225 }
217 226
218 @Test 227 @Test
219 public void testGetDeptDataPermission_Self() { 228 public void testGetDeptDataPermission_Self() {
220 // 准备参数 229 // 准备参数
221 - LoginUser loginUser = randomPojo(LoginUser.class);  
222 - // mock 方法  
223 - RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.SELF.getScope()));  
224 - when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO)); 230 + Long userId = 1L;
  231 + // mock 用户的角色编号
  232 + userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L));
  233 + // mock 获得用户的角色
  234 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.SELF.getScope())
  235 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  236 + when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO));
  237 + when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO);
225 238
226 // 调用 239 // 调用
227 - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser); 240 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
228 // 断言 241 // 断言
229 assertFalse(result.getAll()); 242 assertFalse(result.getAll());
230 assertTrue(result.getSelf()); 243 assertTrue(result.getSelf());
231 assertTrue(CollUtil.isEmpty(result.getDeptIds())); 244 assertTrue(CollUtil.isEmpty(result.getDeptIds()));
232 - assertSame(result, loginUser.getContext(PermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));  
233 } 245 }
234 246
235 } 247 }