调整 SecurityPermissionFrameworkService 的实现,完善 PermissionServiceTest 的单元测试
parent
49b4eedfc0
commit
5794780c4e
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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,4 +1,4 @@
|
|||
package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
|
||||
package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
|
||||
|
||||
/**
|
||||
* {@link DeptDataPermissionRule} 的自定义配置接口
|
|
@ -3,4 +3,4 @@
|
|||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.datapermission.core.dept;
|
||||
package cn.iocoder.yudao.framework.datapermission.core.rule.dept;
|
|
@ -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 字段配置
|
|
@ -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 的上下文策略
|
||||
|
|
|
@ -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 {
|
||||
|
||||
/**
|
||||
* 判断是否有权限
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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,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;
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue