Commit 5794780c4e11da7868d90a9f4c635889ea6a906f

Authored by YunaiV
1 parent 49b4eedf

调整 SecurityPermissionFrameworkService 的实现,完善 PermissionServiceTest 的单元测试

Showing 18 changed files with 246 additions and 88 deletions
yudao-framework/yudao-spring-boot-starter-biz-data-permission/pom.xml
@@ -34,6 +34,13 @@ @@ -34,6 +34,13 @@
34 <artifactId>yudao-spring-boot-starter-mybatis</artifactId> 34 <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
35 </dependency> 35 </dependency>
36 36
  37 + <!-- 业务组件 -->
  38 + <dependency>
  39 + <groupId>cn.iocoder.boot</groupId>
  40 + <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行数据权限的获取 -->
  41 + <version>${revision}</version>
  42 + </dependency>
  43 +
37 <!-- Test 测试相关 --> 44 <!-- Test 测试相关 -->
38 <dependency> 45 <dependency>
39 <groupId>cn.iocoder.boot</groupId> 46 <groupId>cn.iocoder.boot</groupId>
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java
1 package cn.iocoder.yudao.framework.datapermission.config; 1 package cn.iocoder.yudao.framework.datapermission.config;
2 2
3 -import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule;  
4 -import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRuleCustomizer;  
5 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService; 3 +import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
  4 +import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
6 import cn.iocoder.yudao.framework.security.core.LoginUser; 5 import cn.iocoder.yudao.framework.security.core.LoginUser;
  6 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
7 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 7 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
8 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 8 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
9 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Bean;
@@ -18,14 +18,14 @@ import java.util.List; @@ -18,14 +18,14 @@ import java.util.List;
18 */ 18 */
19 @Configuration 19 @Configuration
20 @ConditionalOnClass(LoginUser.class) 20 @ConditionalOnClass(LoginUser.class)
21 -@ConditionalOnBean(value = {DeptDataPermissionFrameworkService.class, DeptDataPermissionRuleCustomizer.class}) 21 +@ConditionalOnBean(value = {PermissionApi.class, DeptDataPermissionRuleCustomizer.class})
22 public class YudaoDeptDataPermissionAutoConfiguration { 22 public class YudaoDeptDataPermissionAutoConfiguration {
23 23
24 @Bean 24 @Bean
25 - public DeptDataPermissionRule deptDataPermissionRule(DeptDataPermissionFrameworkService service, 25 + public DeptDataPermissionRule deptDataPermissionRule(PermissionApi permissionApi,
26 List<DeptDataPermissionRuleCustomizer> customizers) { 26 List<DeptDataPermissionRuleCustomizer> customizers) {
27 // 创建 DeptDataPermissionRule 对象 27 // 创建 DeptDataPermissionRule 对象
28 - DeptDataPermissionRule rule = new DeptDataPermissionRule(service); 28 + DeptDataPermissionRule rule = new DeptDataPermissionRule(permissionApi);
29 // 补全表配置 29 // 补全表配置
30 customizers.forEach(customizer -> customizer.customize(rule)); 30 customizers.forEach(customizer -> customizer.customize(rule));
31 return rule; 31 return rule;
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/service/DeptDataPermissionFrameworkService.java deleted
1 -package cn.iocoder.yudao.framework.datapermission.core.dept.service;  
2 -  
3 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;  
4 -  
5 -/**  
6 - * 基于部门的数据权限 Framework Service 接口  
7 - * 目前的实现类是 SysPermissionServiceImpl 类  
8 - *  
9 - * @author 芋道源码  
10 - */  
11 -public interface DeptDataPermissionFrameworkService {  
12 -  
13 - /**  
14 - * 获得登陆用户的部门数据权限  
15 - *  
16 - * @param userId 用户编号  
17 - * @return 部门数据权限  
18 - */  
19 - DeptDataPermissionRespDTO getDeptDataPermission(Long userId);  
20 -  
21 -}  
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRule.java renamed to yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
1 -package cn.iocoder.yudao.framework.datapermission.core.dept.rule; 1 +package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
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.ObjectUtil;
@@ -6,13 +6,13 @@ import cn.hutool.core.util.StrUtil; @@ -6,13 +6,13 @@ import cn.hutool.core.util.StrUtil;
6 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 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;  
11 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule; 9 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
12 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 10 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
13 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 11 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
14 import cn.iocoder.yudao.framework.security.core.LoginUser; 12 import cn.iocoder.yudao.framework.security.core.LoginUser;
15 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; 13 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
  14 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  15 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
16 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; 16 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
17 import lombok.AllArgsConstructor; 17 import lombok.AllArgsConstructor;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
@@ -25,7 +25,10 @@ import net.sf.jsqlparser.expression.operators.relational.EqualsTo; @@ -25,7 +25,10 @@ import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
25 import net.sf.jsqlparser.expression.operators.relational.ExpressionList; 25 import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
26 import net.sf.jsqlparser.expression.operators.relational.InExpression; 26 import net.sf.jsqlparser.expression.operators.relational.InExpression;
27 27
28 -import java.util.*; 28 +import java.util.HashMap;
  29 +import java.util.HashSet;
  30 +import java.util.Map;
  31 +import java.util.Set;
29 32
30 /** 33 /**
31 * 基于部门的 {@link DataPermissionRule} 数据权限规则实现 34 * 基于部门的 {@link DataPermissionRule} 数据权限规则实现
@@ -58,7 +61,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -58,7 +61,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
58 61
59 static final Expression EXPRESSION_NULL = new NullValue(); 62 static final Expression EXPRESSION_NULL = new NullValue();
60 63
61 - private final DeptDataPermissionFrameworkService deptDataPermissionService; 64 + private final PermissionApi permissionApi;
62 65
63 /** 66 /**
64 * 基于部门的表字段配置 67 * 基于部门的表字段配置
@@ -102,7 +105,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -102,7 +105,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
102 DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class); 105 DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);
103 // 从上下文中拿不到,则调用逻辑进行获取 106 // 从上下文中拿不到,则调用逻辑进行获取
104 if (deptDataPermission == null) { 107 if (deptDataPermission == null) {
105 - deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser.getId()); 108 + deptDataPermission = permissionApi.getDeptDataPermission(loginUser.getId());
106 if (deptDataPermission == null) { 109 if (deptDataPermission == null) {
107 log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser)); 110 log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser));
108 throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限", 111 throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限",
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRuleCustomizer.java renamed to yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleCustomizer.java
1 -package cn.iocoder.yudao.framework.datapermission.core.dept.rule; 1 +package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
2 2
3 /** 3 /**
4 * {@link DeptDataPermissionRule} 的自定义配置接口 4 * {@link DeptDataPermissionRule} 的自定义配置接口
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/package-info.java renamed to yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/package-info.java
@@ -3,4 +3,4 @@ @@ -3,4 +3,4 @@
3 * 3 *
4 * @author 芋道源码 4 * @author 芋道源码
5 */ 5 */
6 -package cn.iocoder.yudao.framework.datapermission.core.dept; 6 +package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRuleTest.java renamed to yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java
1 -package cn.iocoder.yudao.framework.datapermission.core.dept.rule; 1 +package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
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.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.util.collection.SetUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
7 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;  
8 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 7 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  8 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
9 import cn.iocoder.yudao.framework.security.core.LoginUser; 9 import cn.iocoder.yudao.framework.security.core.LoginUser;
10 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; 10 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
11 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; 11 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
@@ -19,7 +19,7 @@ import org.mockito.MockedStatic; @@ -19,7 +19,7 @@ import org.mockito.MockedStatic;
19 19
20 import java.util.Map; 20 import java.util.Map;
21 21
22 -import static cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule.EXPRESSION_NULL; 22 +import static cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRule.EXPRESSION_NULL;
23 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 23 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
24 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; 24 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
25 import static org.junit.jupiter.api.Assertions.*; 25 import static org.junit.jupiter.api.Assertions.*;
@@ -38,7 +38,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -38,7 +38,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
38 private DeptDataPermissionRule rule; 38 private DeptDataPermissionRule rule;
39 39
40 @Mock 40 @Mock
41 - private DeptDataPermissionFrameworkService deptDataPermissionFrameworkService; 41 + private PermissionApi permissionApi;
42 42
43 @BeforeEach 43 @BeforeEach
44 @SuppressWarnings("unchecked") 44 @SuppressWarnings("unchecked")
@@ -95,7 +95,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -95,7 +95,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
95 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 95 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
96 // mock 方法(DeptDataPermissionRespDTO) 96 // mock 方法(DeptDataPermissionRespDTO)
97 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true); 97 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true);
98 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission); 98 + when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
99 99
100 // 调用 100 // 调用
101 Expression expression = rule.getExpression(tableName, tableAlias); 101 Expression expression = rule.getExpression(tableName, tableAlias);
@@ -118,7 +118,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -118,7 +118,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
118 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); 118 securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
119 // mock 方法(DeptDataPermissionRespDTO) 119 // mock 方法(DeptDataPermissionRespDTO)
120 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO(); 120 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO();
121 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission); 121 + when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
122 122
123 // 调用 123 // 调用
124 Expression expression = rule.getExpression(tableName, tableAlias); 124 Expression expression = rule.getExpression(tableName, tableAlias);
@@ -142,7 +142,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -142,7 +142,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
142 // mock 方法(DeptDataPermissionRespDTO) 142 // mock 方法(DeptDataPermissionRespDTO)
143 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 143 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
144 .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true); 144 .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true);
145 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission); 145 + when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
146 146
147 // 调用 147 // 调用
148 Expression expression = rule.getExpression(tableName, tableAlias); 148 Expression expression = rule.getExpression(tableName, tableAlias);
@@ -166,7 +166,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -166,7 +166,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
166 // mock 方法(DeptDataPermissionRespDTO) 166 // mock 方法(DeptDataPermissionRespDTO)
167 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 167 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
168 .setSelf(true); 168 .setSelf(true);
169 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission); 169 + when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
170 // 添加 user 字段配置 170 // 添加 user 字段配置
171 rule.addUserColumn("t_user", "id"); 171 rule.addUserColumn("t_user", "id");
172 172
@@ -192,7 +192,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -192,7 +192,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
192 // mock 方法(DeptDataPermissionRespDTO) 192 // mock 方法(DeptDataPermissionRespDTO)
193 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 193 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
194 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)); 194 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L));
195 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission); 195 + when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
196 // 添加 dept 字段配置 196 // 添加 dept 字段配置
197 rule.addDeptColumn("t_user", "dept_id"); 197 rule.addDeptColumn("t_user", "dept_id");
198 198
@@ -218,7 +218,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { @@ -218,7 +218,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
218 // mock 方法(DeptDataPermissionRespDTO) 218 // mock 方法(DeptDataPermissionRespDTO)
219 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() 219 DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
220 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true); 220 .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true);
221 - when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission); 221 + when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
222 // 添加 user 字段配置 222 // 添加 user 字段配置
223 rule.addUserColumn("t_user", "id"); 223 rule.addUserColumn("t_user", "id");
224 // 添加 dept 字段配置 224 // 添加 dept 字段配置
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java
@@ -5,8 +5,11 @@ import cn.iocoder.yudao.framework.security.core.context.TransmittableThreadLocal @@ -5,8 +5,11 @@ import cn.iocoder.yudao.framework.security.core.context.TransmittableThreadLocal
5 import cn.iocoder.yudao.framework.security.core.filter.TokenAuthenticationFilter; 5 import cn.iocoder.yudao.framework.security.core.filter.TokenAuthenticationFilter;
6 import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl; 6 import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl;
7 import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl; 7 import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl;
  8 +import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkService;
  9 +import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkServiceImpl;
8 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; 10 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
9 import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi; 11 import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi;
  12 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
10 import org.springframework.beans.factory.config.MethodInvokingFactoryBean; 13 import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
11 import org.springframework.boot.context.properties.EnableConfigurationProperties; 14 import org.springframework.boot.context.properties.EnableConfigurationProperties;
12 import org.springframework.context.annotation.Bean; 15 import org.springframework.context.annotation.Bean;
@@ -78,6 +81,11 @@ public class YudaoSecurityAutoConfiguration { @@ -78,6 +81,11 @@ public class YudaoSecurityAutoConfiguration {
78 return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi); 81 return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
79 } 82 }
80 83
  84 + @Bean("ss") // 使用 Spring Security 的缩写,方便食用
  85 + public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
  86 + return new SecurityFrameworkServiceImpl(permissionApi);
  87 + }
  88 +
81 /** 89 /**
82 * 声明调用 {@link SecurityContextHolder#setStrategyName(String)} 方法, 90 * 声明调用 {@link SecurityContextHolder#setStrategyName(String)} 方法,
83 * 设置使用 {@link TransmittableThreadLocalSecurityContextHolderStrategy} 作为 Security 的上下文策略 91 * 设置使用 {@link TransmittableThreadLocalSecurityContextHolderStrategy} 作为 Security 的上下文策略
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityPermissionFrameworkService.java renamed to yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityFrameworkService.java
1 package cn.iocoder.yudao.framework.security.core.service; 1 package cn.iocoder.yudao.framework.security.core.service;
2 2
3 /** 3 /**
4 - * Security 框架 Permission Service 接口,定义 security 组件需要的功能 4 + * Security 框架 Service 接口,定义权限相关的校验操作
5 * 5 *
6 * @author 芋道源码 6 * @author 芋道源码
7 */ 7 */
8 -public interface SecurityPermissionFrameworkService { 8 +public interface SecurityFrameworkService {
9 9
10 /** 10 /**
11 * 判断是否有权限 11 * 判断是否有权限
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityFrameworkServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.security.core.service;
  2 +
  3 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  4 +import lombok.AllArgsConstructor;
  5 +
  6 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  7 +
  8 +/**
  9 + * 默认的 {@link SecurityFrameworkService} 实现类
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@AllArgsConstructor
  14 +public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
  15 +
  16 + private final PermissionApi permissionApi;
  17 +
  18 + @Override
  19 + public boolean hasPermission(String permission) {
  20 + return hasAnyPermissions(permission);
  21 + }
  22 +
  23 + @Override
  24 + public boolean hasAnyPermissions(String... permissions) {
  25 + return permissionApi.hasAnyPermissions(getLoginUserId(), permissions);
  26 + }
  27 +
  28 + @Override
  29 + public boolean hasRole(String role) {
  30 + return hasAnyRoles(role);
  31 + }
  32 +
  33 + @Override
  34 + public boolean hasAnyRoles(String... roles) {
  35 + return permissionApi.hasAnyRoles(getLoginUserId(), roles);
  36 + }
  37 +
  38 +}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java
1 package cn.iocoder.yudao.module.system.api.permission; 1 package cn.iocoder.yudao.module.system.api.permission;
2 2
  3 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
  4 +
3 import java.util.Collection; 5 import java.util.Collection;
4 import java.util.Set; 6 import java.util.Set;
5 7
@@ -18,4 +20,30 @@ public interface PermissionApi { @@ -18,4 +20,30 @@ public interface PermissionApi {
18 */ 20 */
19 Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds); 21 Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds);
20 22
  23 + /**
  24 + * 判断是否有权限,任一一个即可
  25 + *
  26 + * @param userId 用户编号
  27 + * @param permissions 权限
  28 + * @return 是否
  29 + */
  30 + boolean hasAnyPermissions(Long userId, String... permissions);
  31 +
  32 + /**
  33 + * 判断是否有角色,任一一个即可
  34 + *
  35 + * @param userId 用户编号
  36 + * @param roles 角色数组
  37 + * @return 是否
  38 + */
  39 + boolean hasAnyRoles(Long userId, String... roles);
  40 +
  41 + /**
  42 + * 获得登陆用户的部门数据权限
  43 + *
  44 + * @param userId 用户编号
  45 + * @return 部门数据权限
  46 + */
  47 + DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
  48 +
21 } 49 }
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/service/dto/DeptDataPermissionRespDTO.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/dto/DeptDataPermissionRespDTO.java
1 -package cn.iocoder.yudao.framework.datapermission.core.dept.service.dto; 1 +package cn.iocoder.yudao.module.system.api.permission.dto;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java
1 package cn.iocoder.yudao.module.system.api.permission; 1 package cn.iocoder.yudao.module.system.api.permission;
2 2
  3 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
3 import cn.iocoder.yudao.module.system.service.permission.PermissionService; 4 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
4 import org.springframework.stereotype.Service; 5 import org.springframework.stereotype.Service;
5 6
@@ -23,4 +24,19 @@ public class PermissionApiImpl implements PermissionApi { @@ -23,4 +24,19 @@ public class PermissionApiImpl implements PermissionApi {
23 return permissionService.getUserRoleIdListByRoleIds(roleIds); 24 return permissionService.getUserRoleIdListByRoleIds(roleIds);
24 } 25 }
25 26
  27 + @Override
  28 + public boolean hasAnyPermissions(Long userId, String... permissions) {
  29 + return permissionService.hasAnyPermissions(userId, permissions);
  30 + }
  31 +
  32 + @Override
  33 + public boolean hasAnyRoles(Long userId, String... roles) {
  34 + return permissionService.hasAnyRoles(userId, roles);
  35 + }
  36 +
  37 + @Override
  38 + public DeptDataPermissionRespDTO getDeptDataPermission(Long userId) {
  39 + return permissionService.getDeptDataPermission(userId);
  40 + }
  41 +
26 } 42 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/datapermission/config/DataPermissionConfiguration.java
@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.framework.datapermission.config; @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.framework.datapermission.config;
2 2
3 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 3 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
4 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 4 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
5 -import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRuleCustomizer; 5 +import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
6 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Bean;
7 import org.springframework.context.annotation.Configuration; 7 import org.springframework.context.annotation.Configuration;
8 8
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java
1 package cn.iocoder.yudao.module.system.service.permission; 1 package cn.iocoder.yudao.module.system.service.permission;
2 2
3 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;  
4 -import cn.iocoder.yudao.framework.security.core.service.SecurityPermissionFrameworkService; 3 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
5 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; 4 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
6 import org.springframework.lang.Nullable; 5 import org.springframework.lang.Nullable;
7 6
@@ -16,7 +15,7 @@ import java.util.Set; @@ -16,7 +15,7 @@ import java.util.Set;
16 * 15 *
17 * @author 芋道源码 16 * @author 芋道源码
18 */ 17 */
19 -public interface PermissionService extends SecurityPermissionFrameworkService, DeptDataPermissionFrameworkService { 18 +public interface PermissionService {
20 19
21 /** 20 /**
22 * 初始化权限的本地缓存 21 * 初始化权限的本地缓存
@@ -115,4 +114,29 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D @@ -115,4 +114,29 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D
115 */ 114 */
116 void processUserDeleted(Long userId); 115 void processUserDeleted(Long userId);
117 116
  117 + /**
  118 + * 判断是否有权限,任一一个即可
  119 + *
  120 + * @param userId 用户编号
  121 + * @param permissions 权限
  122 + * @return 是否
  123 + */
  124 + boolean hasAnyPermissions(Long userId, String... permissions);
  125 +
  126 + /**
  127 + * 判断是否有角色,任一一个即可
  128 + *
  129 + * @param roles 角色数组
  130 + * @return 是否
  131 + */
  132 + boolean hasAnyRoles(Long userId, String... roles);
  133 +
  134 + /**
  135 + * 获得登陆用户的部门数据权限
  136 + *
  137 + * @param userId 用户编号
  138 + * @return 部门数据权限
  139 + */
  140 + DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
  141 +
118 } 142 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
@@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 8 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
9 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; 10 import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
11 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 11 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
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;
@@ -45,7 +45,6 @@ import java.util.function.Supplier; @@ -45,7 +45,6 @@ import java.util.function.Supplier;
45 45
46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
47 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue; 47 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
48 -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;  
49 import static java.util.Collections.singleton; 48 import static java.util.Collections.singleton;
50 49
51 /** 50 /**
@@ -53,7 +52,7 @@ import static java.util.Collections.singleton; @@ -53,7 +52,7 @@ import static java.util.Collections.singleton;
53 * 52 *
54 * @author 芋道源码 53 * @author 芋道源码
55 */ 54 */
56 -@Service("ss") // 使用 Spring Security 的缩写,方便食用 55 +@Service
57 @Slf4j 56 @Slf4j
58 public class PermissionServiceImpl implements PermissionService { 57 public class PermissionServiceImpl implements PermissionService {
59 58
@@ -71,7 +70,7 @@ public class PermissionServiceImpl implements PermissionService { @@ -71,7 +70,7 @@ public class PermissionServiceImpl implements PermissionService {
71 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 70 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
72 */ 71 */
73 @Getter 72 @Getter
74 - @Setter // 单元测试 73 + @Setter // 单元测试需要
75 private volatile Multimap<Long, Long> roleMenuCache; 74 private volatile Multimap<Long, Long> roleMenuCache;
76 /** 75 /**
77 * 菜单编号与角色编号的缓存映射 76 * 菜单编号与角色编号的缓存映射
@@ -81,6 +80,7 @@ public class PermissionServiceImpl implements PermissionService { @@ -81,6 +80,7 @@ public class PermissionServiceImpl implements PermissionService {
81 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 80 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
82 */ 81 */
83 @Getter 82 @Getter
  83 + @Setter // 单元测试需要
84 private volatile Multimap<Long, Long> menuRoleCache; 84 private volatile Multimap<Long, Long> menuRoleCache;
85 /** 85 /**
86 * 缓存 RoleMenu 的最大更新时间,用于后续的增量轮询,判断是否有更新 86 * 缓存 RoleMenu 的最大更新时间,用于后续的增量轮询,判断是否有更新
@@ -399,19 +399,14 @@ public class PermissionServiceImpl implements PermissionService { @@ -399,19 +399,14 @@ public class PermissionServiceImpl implements PermissionService {
399 } 399 }
400 400
401 @Override 401 @Override
402 - public boolean hasPermission(String permission) {  
403 - return hasAnyPermissions(permission);  
404 - }  
405 -  
406 - @Override  
407 - public boolean hasAnyPermissions(String... permissions) { 402 + public boolean hasAnyPermissions(Long userId, String... permissions) {
408 // 如果为空,说明已经有权限 403 // 如果为空,说明已经有权限
409 if (ArrayUtil.isEmpty(permissions)) { 404 if (ArrayUtil.isEmpty(permissions)) {
410 return true; 405 return true;
411 } 406 }
412 407
413 // 获得当前登录的角色。如果为空,说明没有权限 408 // 获得当前登录的角色。如果为空,说明没有权限
414 - Set<Long> roleIds = getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); 409 + Set<Long> roleIds = getUserRoleIdsFromCache(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
415 if (CollUtil.isEmpty(roleIds)) { 410 if (CollUtil.isEmpty(roleIds)) {
416 return false; 411 return false;
417 } 412 }
@@ -434,19 +429,14 @@ public class PermissionServiceImpl implements PermissionService { @@ -434,19 +429,14 @@ public class PermissionServiceImpl implements PermissionService {
434 } 429 }
435 430
436 @Override 431 @Override
437 - public boolean hasRole(String role) {  
438 - return hasAnyRoles(role);  
439 - }  
440 -  
441 - @Override  
442 - public boolean hasAnyRoles(String... roles) { 432 + public boolean hasAnyRoles(Long userId, String... roles) {
443 // 如果为空,说明已经有权限 433 // 如果为空,说明已经有权限
444 if (ArrayUtil.isEmpty(roles)) { 434 if (ArrayUtil.isEmpty(roles)) {
445 return true; 435 return true;
446 } 436 }
447 437
448 // 获得当前登录的角色。如果为空,说明没有权限 438 // 获得当前登录的角色。如果为空,说明没有权限
449 - Set<Long> roleIds = getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); 439 + Set<Long> roleIds = getUserRoleIdsFromCache(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
450 if (CollUtil.isEmpty(roleIds)) { 440 if (CollUtil.isEmpty(roleIds)) {
451 return false; 441 return false;
452 } 442 }
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
13 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; 13 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
14 import cn.iocoder.yudao.module.system.service.common.CaptchaService; 14 import cn.iocoder.yudao.module.system.service.common.CaptchaService;
15 import cn.iocoder.yudao.module.system.service.logger.LoginLogService; 15 import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
  16 +import cn.iocoder.yudao.module.system.service.member.MemberService;
16 import cn.iocoder.yudao.module.system.service.social.SocialUserService; 17 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
17 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 18 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
18 import org.junit.jupiter.api.BeforeEach; 19 import org.junit.jupiter.api.BeforeEach;
@@ -49,6 +50,8 @@ public class AuthServiceImplTest extends BaseDbUnitTest { @@ -49,6 +50,8 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
49 private SmsCodeApi smsCodeApi; 50 private SmsCodeApi smsCodeApi;
50 @MockBean 51 @MockBean
51 private OAuth2TokenService oauth2TokenService; 52 private OAuth2TokenService oauth2TokenService;
  53 + @MockBean
  54 + private MemberService memberService;
52 55
53 @MockBean 56 @MockBean
54 private Validator validator; 57 private Validator validator;
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
@@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil; @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.map.MapUtil; 4 import cn.hutool.core.map.MapUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 6 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
7 -import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; 7 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
8 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 8 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
9 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 9 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
10 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
@@ -359,22 +359,84 @@ public class PermissionServiceTest extends BaseDbUnitTest { @@ -359,22 +359,84 @@ public class PermissionServiceTest extends BaseDbUnitTest {
359 verify(permissionProducer).sendUserRoleRefreshMessage(); 359 verify(permissionProducer).sendUserRoleRefreshMessage();
360 } 360 }
361 361
362 -// @Test  
363 -// public void testHasAnyRoles_superAdmin() {  
364 -// // 准备参数  
365 -// String[] roles = new String[]{"yunai", "tudou"};  
366 -// // mock 方法  
367 -// List<RoleDO> roleList = singletonList(randomPojo(RoleDO.class, o -> o.setId(100L)));  
368 -// when(roleService.getRolesFromCache(eq(roleIds))).thenReturn(roleList);  
369 -// when(roleService.hasAnySuperAdmin(same(roleList))).thenReturn(true);  
370 -// List<MenuDO> menuList = randomPojoList(MenuDO.class);  
371 -// when(menuService.getMenuListFromCache(eq(menuTypes), eq(menusStatuses))).thenReturn(menuList);  
372 -//  
373 -// // 调用  
374 -// List<MenuDO> result = permissionService.getRoleMenuListFromCache(roleIds, menuTypes, menusStatuses);  
375 -// // 断言  
376 -// assertSame(menuList, result);  
377 -// } 362 + @Test
  363 + public void testHasAnyPermissions_superAdmin() {
  364 + // 准备参数
  365 + Long userId = 1L;
  366 + String[] roles = new String[]{"system:user:query", "system:user:create"};
  367 + // mock 用户与角色的缓存
  368 + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
  369 + RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
  370 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  371 + when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
  372 + // mock 其它方法
  373 + when(roleService.hasAnySuperAdmin(eq(asSet(100L)))).thenReturn(true);
  374 +
  375 + // 调用
  376 + boolean has = permissionService.hasAnyPermissions(userId, roles);
  377 + // 断言
  378 + assertTrue(has);
  379 + }
  380 +
  381 + @Test
  382 + public void testHasAnyPermissions_normal() {
  383 + // 准备参数
  384 + Long userId = 1L;
  385 + String[] roles = new String[]{"system:user:query", "system:user:create"};
  386 + // mock 用户与角色的缓存
  387 + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
  388 + RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
  389 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  390 + when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
  391 + // mock 其它方法
  392 + MenuDO menu = randomPojo(MenuDO.class, o -> o.setId(1000L));
  393 + when(menuService.getMenuListByPermissionFromCache(eq("system:user:create"))).thenReturn(singletonList(menu));
  394 + permissionService.setMenuRoleCache(ImmutableMultimap.<Long, Long>builder().put(1000L, 100L).build());
  395 +
  396 +
  397 + // 调用
  398 + boolean has = permissionService.hasAnyPermissions(userId, roles);
  399 + // 断言
  400 + assertTrue(has);
  401 + }
  402 +
  403 + @Test
  404 + public void testHasAnyRoles_superAdmin() {
  405 + // 准备参数
  406 + Long userId = 1L;
  407 + String[] roles = new String[]{"yunai", "tudou"};
  408 + // mock 用户与角色的缓存
  409 + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
  410 + RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
  411 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  412 + when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
  413 + // mock 其它方法
  414 + when(roleService.hasAnySuperAdmin(eq(asSet(100L)))).thenReturn(true);
  415 +
  416 + // 调用
  417 + boolean has = permissionService.hasAnyRoles(userId, roles);
  418 + // 断言
  419 + assertTrue(has);
  420 + }
  421 +
  422 + @Test
  423 + public void testHasAnyRoles_normal() {
  424 + // 准备参数
  425 + Long userId = 1L;
  426 + String[] roles = new String[]{"yunai", "tudou"};
  427 + // mock 用户与角色的缓存
  428 + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
  429 + RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L).setCode("yunai")
  430 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  431 + when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
  432 + // mock 其它方法
  433 + when(roleService.getRolesFromCache(eq(asSet(100L)))).thenReturn(singletonList(role));
  434 +
  435 + // 调用
  436 + boolean has = permissionService.hasAnyRoles(userId, roles);
  437 + // 断言
  438 + assertTrue(has);
  439 + }
378 440
379 @Test 441 @Test
380 public void testGetDeptDataPermission_All() { 442 public void testGetDeptDataPermission_All() {