1. 增加数据权限的自动配置 DataPermissionAutoConfiguration
2. 增加数据权限的 AOP DataPermissionAnnotationInterceptor 3. 重命名 DataPermissionDatabaseInterceptorplp
parent
2334e177c5
commit
f9b15fe70d
@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.framework.datapermission.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactory;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactoryImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class DataPermissionAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public DataPermissionRuleFactory dataPermissionRuleFactory(List<DataPermissionRule> rules) {
|
||||
return new DataPermissionRuleFactoryImpl(rules);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataPermissionDatabaseInterceptor dataPermissionDatabaseInterceptor(List<DataPermissionRule> rules) {
|
||||
DataPermissionRuleFactory ruleFactory = dataPermissionRuleFactory(rules);
|
||||
return new DataPermissionDatabaseInterceptor(ruleFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataPermissionAnnotationAdvisor dataPermissionAnnotationAdvisor() {
|
||||
return new DataPermissionAnnotationAdvisor();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.iocoder.yudao.framework.datapermission.core.aop;
|
||||
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.AbstractPointcutAdvisor;
|
||||
import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
|
||||
|
||||
/**
|
||||
* {@link cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission} 注解的 Advisor 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DataPermissionAnnotationAdvisor extends AbstractPointcutAdvisor {
|
||||
|
||||
private final Advice advice;
|
||||
|
||||
private final Pointcut pointcut;
|
||||
|
||||
public DataPermissionAnnotationAdvisor() {
|
||||
this.advice = new DataPermissionAnnotationInterceptor();
|
||||
this.pointcut = this.buildPointcut();
|
||||
}
|
||||
|
||||
protected Pointcut buildPointcut() {
|
||||
Pointcut classPointcut = new AnnotationMatchingPointcut(DataPermission.class, true);
|
||||
Pointcut methodPointcut = new AnnotationMatchingPointcut(null, DataPermission.class, true);
|
||||
return new ComposablePointcut(classPointcut).union(methodPointcut);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package cn.iocoder.yudao.framework.datapermission.core.aop;
|
||||
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* {@link DataPermission} 注解的 Context 上下文
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class DataPermissionContextHolder {
|
||||
|
||||
private static final ThreadLocal<Deque<DataPermission>> DATA_PERMISSIONS =
|
||||
TransmittableThreadLocal.withInitial(ArrayDeque::new);
|
||||
|
||||
/**
|
||||
* 获得当前的 DataPermission 注解
|
||||
*
|
||||
* @return DataPermission 注解
|
||||
*/
|
||||
public static DataPermission peek() {
|
||||
return DATA_PERMISSIONS.get().remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 入栈 DataPermission 注解
|
||||
*
|
||||
* @param dataPermission DataPermission 注解
|
||||
*/
|
||||
public static void push(DataPermission dataPermission) {
|
||||
DATA_PERMISSIONS.get().push(dataPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 出栈 DataPermission 注解
|
||||
*
|
||||
* @return DataPermission 注解
|
||||
*/
|
||||
public static DataPermission poll() {
|
||||
DataPermission dataPermission = DATA_PERMISSIONS.get().poll();
|
||||
// 无元素时,清空 ThreadLocal
|
||||
if (dataPermission == null) {
|
||||
DATA_PERMISSIONS.remove();
|
||||
}
|
||||
return dataPermission;
|
||||
}
|
||||
|
||||
}
|
||||
4
yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptor.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
4
yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptor.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
@ -1 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.datapermission.core;
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.framework.datapermission.core.rule;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class DataPermissionRuleFactoryImpl implements DataPermissionRuleFactory {
|
||||
|
||||
/**
|
||||
* 数据权限规则数组
|
||||
*/
|
||||
private final List<DataPermissionRule> rules;
|
||||
|
||||
@Override
|
||||
public List<DataPermissionRule> getDataPermissionRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DataPermissionRule> getDataPermissionRule(String mappedStatementId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package cn.iocoder.yudao.framework.datapermission.core.aop;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link DataPermissionAnnotationInterceptor} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class DataPermissionAnnotationInterceptorTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private DataPermissionAnnotationInterceptor interceptor;
|
||||
|
||||
@Mock
|
||||
private MethodInvocation methodInvocation;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
interceptor.getDataPermissionCache().clear();
|
||||
}
|
||||
|
||||
@Test // 无 @DataPermission 注解
|
||||
public void testInvoke_none() throws Throwable {
|
||||
// 参数
|
||||
mockMethodInvocation(TestNone.class);
|
||||
|
||||
// 调用
|
||||
Object result = interceptor.invoke(methodInvocation);
|
||||
// 断言
|
||||
assertEquals("none", result);
|
||||
assertEquals(1, interceptor.getDataPermissionCache().size());
|
||||
assertTrue(CollUtil.getFirst(interceptor.getDataPermissionCache().values()).enable());
|
||||
}
|
||||
|
||||
@Test // 在 Method 上有 @DataPermission 注解
|
||||
public void testInvoke_method() throws Throwable {
|
||||
// 参数
|
||||
mockMethodInvocation(TestMethod.class);
|
||||
|
||||
// 调用
|
||||
Object result = interceptor.invoke(methodInvocation);
|
||||
// 断言
|
||||
assertEquals("method", result);
|
||||
assertEquals(1, interceptor.getDataPermissionCache().size());
|
||||
assertFalse(CollUtil.getFirst(interceptor.getDataPermissionCache().values()).enable());
|
||||
}
|
||||
|
||||
@Test // 在 Class 上有 @DataPermission 注解
|
||||
public void testInvoke_class() throws Throwable {
|
||||
// 参数
|
||||
mockMethodInvocation(TestClass.class);
|
||||
|
||||
// 调用
|
||||
Object result = interceptor.invoke(methodInvocation);
|
||||
// 断言
|
||||
assertEquals("class", result);
|
||||
assertEquals(1, interceptor.getDataPermissionCache().size());
|
||||
assertFalse(CollUtil.getFirst(interceptor.getDataPermissionCache().values()).enable());
|
||||
}
|
||||
|
||||
private void mockMethodInvocation(Class<?> clazz) throws Throwable {
|
||||
Object targetObject = clazz.newInstance();
|
||||
Method method = targetObject.getClass().getMethod("echo");
|
||||
when(methodInvocation.getThis()).thenReturn(targetObject);
|
||||
when(methodInvocation.getMethod()).thenReturn(method);
|
||||
when(methodInvocation.proceed()).then(invocationOnMock -> method.invoke(targetObject));
|
||||
}
|
||||
|
||||
static class TestMethod {
|
||||
|
||||
@DataPermission(enable = false)
|
||||
public String echo() {
|
||||
return "method";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@DataPermission(enable = false)
|
||||
static class TestClass {
|
||||
|
||||
public String echo() {
|
||||
return "class";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestNone {
|
||||
|
||||
public String echo() {
|
||||
return "none";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
14
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest.java
14
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest.java
10
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest2.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
10
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest2.java → yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
cn.iocoder.yudao.framework.datapermission.config.DataPermissionAutoConfiguration
|
||||
Loading…
Reference in New Issue