Browse Source

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

YunaiV 3 năm trước cách đây
mục cha
commit
5794780c4e
18 tập tin đã thay đổi với 246 bổ sung88 xóa
  1. 7 0
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/pom.xml
  2. 6 6
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java
  3. 0 21
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/service/DeptDataPermissionFrameworkService.java
  4. 9 6
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
  5. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleCustomizer.java
  6. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/package-info.java
  7. 11 11
      yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java
  8. 8 0
      yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java
  9. 2 2
      yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityFrameworkService.java
  10. 38 0
      yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityFrameworkServiceImpl.java
  11. 28 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java
  12. 1 1
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/dto/DeptDataPermissionRespDTO.java
  13. 16 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java
  14. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/datapermission/config/DataPermissionConfiguration.java
  15. 27 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java
  16. 8 18
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
  17. 3 0
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java
  18. 79 17
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java

+ 7 - 0
yudao-framework/yudao-spring-boot-starter-biz-data-permission/pom.xml

@@ -34,6 +34,13 @@
             <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
         </dependency>
 
+        <!-- 业务组件 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行数据权限的获取 -->
+            <version>${revision}</version>
+        </dependency>
+
         <!-- Test 测试相关 -->
         <dependency>
             <groupId>cn.iocoder.boot</groupId>

+ 6 - 6
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java

@@ -1,9 +1,9 @@
 package cn.iocoder.yudao.framework.datapermission.config;
 
-import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule;
-import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRuleCustomizer;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
+import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
+import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.context.annotation.Bean;
@@ -18,14 +18,14 @@ import java.util.List;
  */
 @Configuration
 @ConditionalOnClass(LoginUser.class)
-@ConditionalOnBean(value = {DeptDataPermissionFrameworkService.class, DeptDataPermissionRuleCustomizer.class})
+@ConditionalOnBean(value = {PermissionApi.class, DeptDataPermissionRuleCustomizer.class})
 public class YudaoDeptDataPermissionAutoConfiguration {
 
     @Bean
-    public DeptDataPermissionRule deptDataPermissionRule(DeptDataPermissionFrameworkService service,
+    public DeptDataPermissionRule deptDataPermissionRule(PermissionApi permissionApi,
                                                          List<DeptDataPermissionRuleCustomizer> customizers) {
         // 创建 DeptDataPermissionRule 对象
-        DeptDataPermissionRule rule = new DeptDataPermissionRule(service);
+        DeptDataPermissionRule rule = new DeptDataPermissionRule(permissionApi);
         // 补全表配置
         customizers.forEach(customizer -> customizer.customize(rule));
         return rule;

+ 0 - 21
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/service/DeptDataPermissionFrameworkService.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.framework.datapermission.core.dept.service;
-
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
-
-/**
- * 基于部门的数据权限 Framework Service 接口
- * 目前的实现类是 SysPermissionServiceImpl 类
- *
- * @author 芋道源码
- */
-public interface DeptDataPermissionFrameworkService {
-
-    /**
-     * 获得登陆用户的部门数据权限
-     *
-     * @param userId 用户编号
-     * @return 部门数据权限
-     */
-    DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
-
-}

+ 9 - 6
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRule.java → yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
+package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -6,13 +6,13 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -25,7 +25,10 @@ import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
 import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
 import net.sf.jsqlparser.expression.operators.relational.InExpression;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * 基于部门的 {@link DataPermissionRule} 数据权限规则实现
@@ -58,7 +61,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
 
     static final Expression EXPRESSION_NULL = new NullValue();
 
-    private final DeptDataPermissionFrameworkService deptDataPermissionService;
+    private final PermissionApi permissionApi;
 
     /**
      * 基于部门的表字段配置
@@ -102,7 +105,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
         DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);
         // 从上下文中拿不到,则调用逻辑进行获取
         if (deptDataPermission == null) {
-            deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser.getId());
+            deptDataPermission = permissionApi.getDeptDataPermission(loginUser.getId());
             if (deptDataPermission == null) {
                 log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser));
                 throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限",

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRuleCustomizer.java → yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleCustomizer.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
+package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
 
 /**
  * {@link DeptDataPermissionRule} 的自定义配置接口

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/package-info.java → 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 @@
  *
  * @author 芋道源码
  */
-package cn.iocoder.yudao.framework.datapermission.core.dept;
+package cn.iocoder.yudao.framework.datapermission.core.rule.dept;

+ 11 - 11
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRuleTest.java → yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java

@@ -1,11 +1,11 @@
-package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
+package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
@@ -19,7 +19,7 @@ import org.mockito.MockedStatic;
 
 import java.util.Map;
 
-import static cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule.EXPRESSION_NULL;
+import static cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRule.EXPRESSION_NULL;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
 import static org.junit.jupiter.api.Assertions.*;
@@ -38,7 +38,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
     private DeptDataPermissionRule rule;
 
     @Mock
-    private DeptDataPermissionFrameworkService deptDataPermissionFrameworkService;
+    private PermissionApi permissionApi;
 
     @BeforeEach
     @SuppressWarnings("unchecked")
@@ -95,7 +95,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
             securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
             // mock 方法(DeptDataPermissionRespDTO)
             DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true);
-            when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
+            when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
 
             // 调用
             Expression expression = rule.getExpression(tableName, tableAlias);
@@ -118,7 +118,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
             securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
             // mock 方法(DeptDataPermissionRespDTO)
             DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO();
-            when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
+            when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
 
             // 调用
             Expression expression = rule.getExpression(tableName, tableAlias);
@@ -142,7 +142,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
             // mock 方法(DeptDataPermissionRespDTO)
             DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
                     .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true);
-            when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
+            when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
 
             // 调用
             Expression expression = rule.getExpression(tableName, tableAlias);
@@ -166,7 +166,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
             // mock 方法(DeptDataPermissionRespDTO)
             DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
                     .setSelf(true);
-            when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
+            when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
             // 添加 user 字段配置
             rule.addUserColumn("t_user", "id");
 
@@ -192,7 +192,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
             // mock 方法(DeptDataPermissionRespDTO)
             DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
                     .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L));
-            when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
+            when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
             // 添加 dept 字段配置
             rule.addDeptColumn("t_user", "dept_id");
 
@@ -218,7 +218,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
             // mock 方法(DeptDataPermissionRespDTO)
             DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
                     .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true);
-            when(deptDataPermissionFrameworkService.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
+            when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(deptDataPermission);
             // 添加 user 字段配置
             rule.addUserColumn("t_user", "id");
             // 添加 dept 字段配置

+ 8 - 0
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
 import cn.iocoder.yudao.framework.security.core.filter.TokenAuthenticationFilter;
 import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl;
 import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl;
+import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkService;
+import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkServiceImpl;
 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
 import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi;
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
 import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
@@ -78,6 +81,11 @@ public class YudaoSecurityAutoConfiguration {
         return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
     }
 
+    @Bean("ss") // 使用 Spring Security 的缩写,方便食用
+    public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
+        return new SecurityFrameworkServiceImpl(permissionApi);
+    }
+
     /**
      * 声明调用 {@link SecurityContextHolder#setStrategyName(String)} 方法,
      * 设置使用 {@link TransmittableThreadLocalSecurityContextHolderStrategy} 作为 Security 的上下文策略

+ 2 - 2
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityPermissionFrameworkService.java → yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityFrameworkService.java

@@ -1,11 +1,11 @@
 package cn.iocoder.yudao.framework.security.core.service;
 
 /**
- * Security 框架 Permission Service 接口,定义 security 组件需要的功能
+ * Security 框架 Service 接口,定义权限相关的校验操作
  *
  * @author 芋道源码
  */
-public interface SecurityPermissionFrameworkService {
+public interface SecurityFrameworkService {
 
     /**
      * 判断是否有权限

+ 38 - 0
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityFrameworkServiceImpl.java

@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.framework.security.core.service;
+
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
+import lombok.AllArgsConstructor;
+
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+
+/**
+ * 默认的 {@link SecurityFrameworkService} 实现类
+ *
+ * @author 芋道源码
+ */
+@AllArgsConstructor
+public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
+
+    private final PermissionApi permissionApi;
+
+    @Override
+    public boolean hasPermission(String permission) {
+        return hasAnyPermissions(permission);
+    }
+
+    @Override
+    public boolean hasAnyPermissions(String... permissions) {
+        return permissionApi.hasAnyPermissions(getLoginUserId(), permissions);
+    }
+
+    @Override
+    public boolean hasRole(String role) {
+        return hasAnyRoles(role);
+    }
+
+    @Override
+    public boolean hasAnyRoles(String... roles) {
+        return permissionApi.hasAnyRoles(getLoginUserId(), roles);
+    }
+
+}

+ 28 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java

@@ -1,5 +1,7 @@
 package cn.iocoder.yudao.module.system.api.permission;
 
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
+
 import java.util.Collection;
 import java.util.Set;
 
@@ -18,4 +20,30 @@ public interface PermissionApi {
      */
     Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds);
 
+    /**
+     * 判断是否有权限,任一一个即可
+     *
+     * @param userId 用户编号
+     * @param permissions 权限
+     * @return 是否
+     */
+    boolean hasAnyPermissions(Long userId, String... permissions);
+
+    /**
+     * 判断是否有角色,任一一个即可
+     *
+     * @param userId 用户编号
+     * @param roles 角色数组
+     * @return 是否
+     */
+    boolean hasAnyRoles(Long userId, String... roles);
+
+    /**
+     * 获得登陆用户的部门数据权限
+     *
+     * @param userId 用户编号
+     * @return 部门数据权限
+     */
+    DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
+
 }

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/service/dto/DeptDataPermissionRespDTO.java → yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/dto/DeptDataPermissionRespDTO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.datapermission.core.dept.service.dto;
+package cn.iocoder.yudao.module.system.api.permission.dto;
 
 import lombok.Data;
 

+ 16 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.system.api.permission;
 
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
 import org.springframework.stereotype.Service;
 
@@ -23,4 +24,19 @@ public class PermissionApiImpl implements PermissionApi {
         return permissionService.getUserRoleIdListByRoleIds(roleIds);
     }
 
+    @Override
+    public boolean hasAnyPermissions(Long userId, String... permissions) {
+        return permissionService.hasAnyPermissions(userId, permissions);
+    }
+
+    @Override
+    public boolean hasAnyRoles(Long userId, String... roles) {
+        return permissionService.hasAnyRoles(userId, roles);
+    }
+
+    @Override
+    public DeptDataPermissionRespDTO getDeptDataPermission(Long userId) {
+        return permissionService.getDeptDataPermission(userId);
+    }
+
 }

+ 1 - 1
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;
 
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
-import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRuleCustomizer;
+import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 

+ 27 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java

@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.system.service.permission;
 
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
-import cn.iocoder.yudao.framework.security.core.service.SecurityPermissionFrameworkService;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import org.springframework.lang.Nullable;
 
@@ -16,7 +15,7 @@ import java.util.Set;
  *
  * @author 芋道源码
  */
-public interface PermissionService extends SecurityPermissionFrameworkService, DeptDataPermissionFrameworkService {
+public interface PermissionService {
 
     /**
      * 初始化权限的本地缓存
@@ -115,4 +114,29 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D
      */
     void processUserDeleted(Long userId);
 
+    /**
+     * 判断是否有权限,任一一个即可
+     *
+     * @param userId 用户编号
+     * @param permissions 权限
+     * @return 是否
+     */
+    boolean hasAnyPermissions(Long userId, String... permissions);
+
+    /**
+     * 判断是否有角色,任一一个即可
+     *
+     * @param roles 角色数组
+     * @return 是否
+     */
+    boolean hasAnyRoles(Long userId, String... roles);
+
+    /**
+     * 获得登陆用户的部门数据权限
+     *
+     * @param userId 用户编号
+     * @return 部门数据权限
+     */
+    DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
+
 }

+ 8 - 18
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;
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
@@ -45,7 +45,6 @@ import java.util.function.Supplier;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static java.util.Collections.singleton;
 
 /**
@@ -53,7 +52,7 @@ import static java.util.Collections.singleton;
  *
  * @author 芋道源码
  */
-@Service("ss") // 使用 Spring Security 的缩写,方便食用
+@Service
 @Slf4j
 public class PermissionServiceImpl implements PermissionService {
 
@@ -71,7 +70,7 @@ public class PermissionServiceImpl implements PermissionService {
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
     @Getter
-    @Setter // 单元测试
+    @Setter // 单元测试需要
     private volatile Multimap<Long, Long> roleMenuCache;
     /**
      * 菜单编号与角色编号的缓存映射
@@ -81,6 +80,7 @@ public class PermissionServiceImpl implements PermissionService {
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
     @Getter
+    @Setter // 单元测试需要
     private volatile Multimap<Long, Long> menuRoleCache;
     /**
      * 缓存 RoleMenu 的最大更新时间,用于后续的增量轮询,判断是否有更新
@@ -399,19 +399,14 @@ public class PermissionServiceImpl implements PermissionService {
     }
 
     @Override
-    public boolean hasPermission(String permission) {
-        return hasAnyPermissions(permission);
-    }
-
-    @Override
-    public boolean hasAnyPermissions(String... permissions) {
+    public boolean hasAnyPermissions(Long userId, String... permissions) {
         // 如果为空,说明已经有权限
         if (ArrayUtil.isEmpty(permissions)) {
             return true;
         }
 
         // 获得当前登录的角色。如果为空,说明没有权限
-        Set<Long> roleIds = getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
+        Set<Long> roleIds = getUserRoleIdsFromCache(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
         if (CollUtil.isEmpty(roleIds)) {
             return false;
         }
@@ -434,19 +429,14 @@ public class PermissionServiceImpl implements PermissionService {
     }
 
     @Override
-    public boolean hasRole(String role) {
-        return hasAnyRoles(role);
-    }
-
-    @Override
-    public boolean hasAnyRoles(String... roles) {
+    public boolean hasAnyRoles(Long userId, String... roles) {
         // 如果为空,说明已经有权限
         if (ArrayUtil.isEmpty(roles)) {
             return true;
         }
 
         // 获得当前登录的角色。如果为空,说明没有权限
-        Set<Long> roleIds = getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
+        Set<Long> roleIds = getUserRoleIdsFromCache(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
         if (CollUtil.isEmpty(roleIds)) {
             return false;
         }

+ 3 - 0
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;
 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
 import cn.iocoder.yudao.module.system.service.common.CaptchaService;
 import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
+import cn.iocoder.yudao.module.system.service.member.MemberService;
 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 import org.junit.jupiter.api.BeforeEach;
@@ -49,6 +50,8 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
     private SmsCodeApi smsCodeApi;
     @MockBean
     private OAuth2TokenService oauth2TokenService;
+    @MockBean
+    private MemberService memberService;
 
     @MockBean
     private Validator validator;

+ 79 - 17
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;
 import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
@@ -359,22 +359,84 @@ public class PermissionServiceTest extends BaseDbUnitTest {
         verify(permissionProducer).sendUserRoleRefreshMessage();
     }
 
-//    @Test
-//    public void testHasAnyRoles_superAdmin() {
-//        // 准备参数
-//        String[] roles = new String[]{"yunai", "tudou"};
-//        // mock 方法
-//        List<RoleDO> roleList = singletonList(randomPojo(RoleDO.class, o -> o.setId(100L)));
-//        when(roleService.getRolesFromCache(eq(roleIds))).thenReturn(roleList);
-//        when(roleService.hasAnySuperAdmin(same(roleList))).thenReturn(true);
-//        List<MenuDO> menuList = randomPojoList(MenuDO.class);
-//        when(menuService.getMenuListFromCache(eq(menuTypes), eq(menusStatuses))).thenReturn(menuList);
-//
-//        // 调用
-//        List<MenuDO> result = permissionService.getRoleMenuListFromCache(roleIds, menuTypes, menusStatuses);
-//        // 断言
-//        assertSame(menuList, result);
-//    }
+    @Test
+    public void testHasAnyPermissions_superAdmin() {
+        // 准备参数
+        Long userId = 1L;
+        String[] roles = new String[]{"system:user:query", "system:user:create"};
+        // mock 用户与角色的缓存
+        permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
+        RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
+                .setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
+        // mock 其它方法
+        when(roleService.hasAnySuperAdmin(eq(asSet(100L)))).thenReturn(true);
+
+        // 调用
+        boolean has = permissionService.hasAnyPermissions(userId, roles);
+        // 断言
+        assertTrue(has);
+    }
+
+    @Test
+    public void testHasAnyPermissions_normal() {
+        // 准备参数
+        Long userId = 1L;
+        String[] roles = new String[]{"system:user:query", "system:user:create"};
+        // mock 用户与角色的缓存
+        permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
+        RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
+                .setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
+        // mock 其它方法
+        MenuDO menu = randomPojo(MenuDO.class, o -> o.setId(1000L));
+        when(menuService.getMenuListByPermissionFromCache(eq("system:user:create"))).thenReturn(singletonList(menu));
+        permissionService.setMenuRoleCache(ImmutableMultimap.<Long, Long>builder().put(1000L, 100L).build());
+
+
+        // 调用
+        boolean has = permissionService.hasAnyPermissions(userId, roles);
+        // 断言
+        assertTrue(has);
+    }
+
+    @Test
+    public void testHasAnyRoles_superAdmin() {
+        // 准备参数
+        Long userId = 1L;
+        String[] roles = new String[]{"yunai", "tudou"};
+        // mock 用户与角色的缓存
+        permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
+        RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
+                .setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
+        // mock 其它方法
+        when(roleService.hasAnySuperAdmin(eq(asSet(100L)))).thenReturn(true);
+
+        // 调用
+        boolean has = permissionService.hasAnyRoles(userId, roles);
+        // 断言
+        assertTrue(has);
+    }
+
+    @Test
+    public void testHasAnyRoles_normal() {
+        // 准备参数
+        Long userId = 1L;
+        String[] roles = new String[]{"yunai", "tudou"};
+        // mock 用户与角色的缓存
+        permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(100L)).build());
+        RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L).setCode("yunai")
+                .setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        when(roleService.getRoleFromCache(eq(100L))).thenReturn(role);
+        // mock 其它方法
+        when(roleService.getRolesFromCache(eq(asSet(100L)))).thenReturn(singletonList(role));
+
+        // 调用
+        boolean has = permissionService.hasAnyRoles(userId, roles);
+        // 断言
+        assertTrue(has);
+    }
 
     @Test
     public void testGetDeptDataPermission_All() {