From e5158ed3b27d60f37d538868c4b344e05a8015e4 Mon Sep 17 00:00:00 2001 From: zhouhao Date: Tue, 25 Jan 2022 15:39:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../define/AuthorizeDefinitionContext.java | 7 ++++ .../define/AuthorizeDefinitionCustomizer.java | 7 ++++ ...ompositeAuthorizeDefinitionCustomizer.java | 24 +++++++++++ .../define/MergedAuthorizeDefinition.java | 6 +-- ...ultAopMethodAuthorizeDefinitionParser.java | 18 +++++++- .../web/api/crud/entity/QueryParamEntity.java | 24 +++++++++-- .../EnableCacheReactiveCrudService.java | 42 ++++++++++++++----- .../ReactiveServiceQueryController.java | 12 +++--- .../web/cache/ReactiveCache.java | 21 +++++----- .../web/bean/FastBeanCopier.java | 1 - ...AuthorizationServiceAutoConfiguration.java | 9 +++- .../service/PermissionSynchronization.java | 16 +++++-- 12 files changed, 146 insertions(+), 41 deletions(-) create mode 100644 hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionContext.java create mode 100644 hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionCustomizer.java create mode 100644 hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/CompositeAuthorizeDefinitionCustomizer.java diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionContext.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionContext.java new file mode 100644 index 000000000..8b69af611 --- /dev/null +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionContext.java @@ -0,0 +1,7 @@ +package org.hswebframework.web.authorization.define; + +public interface AuthorizeDefinitionContext { + + void addResource(ResourceDefinition def); + +} diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionCustomizer.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionCustomizer.java new file mode 100644 index 000000000..b0fe8d320 --- /dev/null +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinitionCustomizer.java @@ -0,0 +1,7 @@ +package org.hswebframework.web.authorization.define; + +public interface AuthorizeDefinitionCustomizer { + + void custom(AuthorizeDefinitionContext context); + +} diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/CompositeAuthorizeDefinitionCustomizer.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/CompositeAuthorizeDefinitionCustomizer.java new file mode 100644 index 000000000..54af14835 --- /dev/null +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/CompositeAuthorizeDefinitionCustomizer.java @@ -0,0 +1,24 @@ +package org.hswebframework.web.authorization.define; + +import lombok.AllArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +@AllArgsConstructor +public class CompositeAuthorizeDefinitionCustomizer implements AuthorizeDefinitionCustomizer{ + + private final List customizers; + + public CompositeAuthorizeDefinitionCustomizer(Iterable customizers){ + this(StreamSupport.stream(customizers.spliterator(),false).collect(Collectors.toList())); + } + + @Override + public void custom(AuthorizeDefinitionContext context) { + for (AuthorizeDefinitionCustomizer customizer : customizers) { + customizer.custom(context); + } + } +} diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/MergedAuthorizeDefinition.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/MergedAuthorizeDefinition.java index 94d32070d..b247c7a0c 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/MergedAuthorizeDefinition.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/MergedAuthorizeDefinition.java @@ -4,11 +4,11 @@ import java.util.List; import java.util.Set; -public class MergedAuthorizeDefinition { +public class MergedAuthorizeDefinition implements AuthorizeDefinitionContext { - private ResourcesDefinition resources = new ResourcesDefinition(); + private final ResourcesDefinition resources = new ResourcesDefinition(); - private DimensionsDefinition dimensions = new DimensionsDefinition(); + private final DimensionsDefinition dimensions = new DimensionsDefinition(); public Set getResources() { return resources.getResources(); diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java index 0a5f9efaf..6b3c96afe 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java @@ -6,6 +6,7 @@ import org.hswebframework.web.aop.MethodInterceptorContext; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.authorization.annotation.DataAccess; import org.hswebframework.web.authorization.annotation.Dimension; +import org.hswebframework.web.authorization.annotation.ResourceAction; import org.hswebframework.web.authorization.basic.define.DefaultBasicAuthorizeDefinition; import org.hswebframework.web.authorization.basic.define.EmptyAuthorizeDefinition; import org.hswebframework.web.authorization.define.AuthorizeDefinition; @@ -15,8 +16,10 @@ import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.RequestMapping; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -63,7 +66,8 @@ public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAutho } //使用自定义 if (!CollectionUtils.isEmpty(parserCustomizers)) { - definition = parserCustomizers.stream() + definition = parserCustomizers + .stream() .map(customizer -> customizer.parse(target, method, context)) .filter(Objects::nonNull) .findAny().orElse(null); @@ -77,7 +81,7 @@ public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAutho Authorize annotation = AnnotationUtils.findAnnotation(target, method, Authorize.class); - if (annotation != null && annotation.ignore()) { + if (isIgnoreMethod(method) || (annotation != null && annotation.ignore())) { cache.put(key, EmptyAuthorizeDefinition.instance); return null; } @@ -107,4 +111,14 @@ public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAutho cache.clear(); } + static boolean isIgnoreMethod(Method method) { + //不是public的方法 + if(!Modifier.isPublic(method.getModifiers())){ + return true; + } + //没有以下注解 + return null == AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class) + && null == AnnotatedElementUtils.findMergedAnnotation(method, ResourceAction.class); + } + } diff --git a/hsweb-commons/hsweb-commons-api/src/main/java/org/hswebframework/web/api/crud/entity/QueryParamEntity.java b/hsweb-commons/hsweb-commons-api/src/main/java/org/hswebframework/web/api/crud/entity/QueryParamEntity.java index 680d51589..fadebf1d1 100644 --- a/hsweb-commons/hsweb-commons-api/src/main/java/org/hswebframework/web/api/crud/entity/QueryParamEntity.java +++ b/hsweb-commons/hsweb-commons-api/src/main/java/org/hswebframework/web/api/crud/entity/QueryParamEntity.java @@ -10,9 +10,11 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.hswebframework.ezorm.core.NestConditional; import org.hswebframework.ezorm.core.dsl.Query; +import org.hswebframework.ezorm.core.param.Param; import org.hswebframework.ezorm.core.param.QueryParam; import org.hswebframework.ezorm.core.param.Term; import org.hswebframework.ezorm.core.param.TermType; +import org.hswebframework.web.bean.FastBeanCopier; import org.springframework.util.StringUtils; @@ -26,11 +28,11 @@ import java.util.function.Consumer; * 可通过静态方法创建:
* 如: *
- *{@code
+ * {@code
  *      QueryParamEntity.of("id",id);
- *}
+ * }
  * 
- * + *

* 或者使用DSL方式来构造: *

{@code
  *  QueryParamEntity
@@ -97,6 +99,20 @@ public class QueryParamEntity extends QueryParam {
         return super.getExcludes();
     }
 
+    /**
+     * 基于另外一个条件参数来创建查询条件实体
+     *
+     * @param param 参数
+     * @return 新的查询条件
+     * @since 4.0.14
+     */
+    public static QueryParamEntity of(Param param) {
+        if (param instanceof QueryParamEntity) {
+            return ((QueryParamEntity) param).clone();
+        }
+        return FastBeanCopier.copy(param, new QueryParamEntity());
+    }
+
     /**
      * 创建一个空的查询参数实体,该实体无任何参数.
      *
@@ -217,7 +233,7 @@ public class QueryParamEntity extends QueryParam {
         return this;
     }
 
-    public QueryParamEntity doNotSort(){
+    public QueryParamEntity doNotSort() {
         this.setSorts(new ArrayList<>());
         return this;
     }
diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java
index d152b5e36..272ecd4e5 100644
--- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java
+++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java
@@ -9,6 +9,7 @@ import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
 import java.util.Collection;
+import java.util.function.Function;
 
 public interface EnableCacheReactiveCrudService extends ReactiveCrudService {
 
@@ -16,8 +17,8 @@ public interface EnableCacheReactiveCrudService extends ReactiveCrudServic
 
     default Mono findById(K id) {
         return this.getCache()
-                .mono("id:" + id)
-                .onCacheMissResume(ReactiveCrudService.super.findById(Mono.just(id)));
+                   .mono("id:" + id)
+                   .onCacheMissResume(ReactiveCrudService.super.findById(Mono.just(id)));
     }
 
     @Override
@@ -27,44 +28,65 @@ public interface EnableCacheReactiveCrudService extends ReactiveCrudServic
 
     @Override
     default Mono updateById(K id, Mono entityPublisher) {
-        return ReactiveCrudService.super.updateById(id, entityPublisher)
+        return ReactiveCrudService.super
+                .updateById(id, entityPublisher)
                 .doFinally(i -> getCache().evict("id:" + id).subscribe());
     }
 
+    @Override
+    default Mono save(E data) {
+        return ReactiveCrudService.super
+                .save(data)
+                .doFinally(i -> getCache().clear().subscribe());
+    }
+
     @Override
     default Mono save(Publisher entityPublisher) {
-        return ReactiveCrudService.super.save(entityPublisher)
+        return ReactiveCrudService.super
+                .save(entityPublisher)
+                .doFinally(i -> getCache().clear().subscribe());
+    }
+
+    @Override
+    default Mono insert(E data) {
+        return ReactiveCrudService.super
+                .insert(data)
                 .doFinally(i -> getCache().clear().subscribe());
     }
 
     @Override
     default Mono insert(Publisher entityPublisher) {
-        return ReactiveCrudService.super.insert(entityPublisher)
+        return ReactiveCrudService.super
+                .insert(entityPublisher)
                 .doFinally(i -> getCache().clear().subscribe());
     }
 
     @Override
     default Mono insertBatch(Publisher> entityPublisher) {
-        return ReactiveCrudService.super.insertBatch(entityPublisher)
+        return ReactiveCrudService.super
+                .insertBatch(entityPublisher)
                 .doFinally(i -> getCache().clear().subscribe());
     }
 
     @Override
     default Mono deleteById(Publisher idPublisher) {
-        return Flux.from(idPublisher)
-                .doOnNext(id -> this.getCache().evict("id:" + id).subscribe())
+        return Flux
+                .from(idPublisher)
+                .flatMap(id -> this.getCache().evict("id:" + id).thenReturn(id))
                 .as(ReactiveCrudService.super::deleteById);
     }
 
     @Override
     default ReactiveUpdate createUpdate() {
-        return ReactiveCrudService.super.createUpdate()
+        return ReactiveCrudService.super
+                .createUpdate()
                 .onExecute((update, s) -> s.doFinally((__) -> getCache().clear().subscribe()));
     }
 
     @Override
     default ReactiveDelete createDelete() {
-        return ReactiveCrudService.super.createDelete()
+        return ReactiveCrudService.super
+                .createDelete()
                 .onExecute((update, s) -> s.doFinally((__) -> getCache().clear().subscribe()));
     }
 }
diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/reactive/ReactiveServiceQueryController.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/reactive/ReactiveServiceQueryController.java
index ef0f074a1..51eed4f7f 100644
--- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/reactive/ReactiveServiceQueryController.java
+++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/reactive/ReactiveServiceQueryController.java
@@ -72,9 +72,9 @@ public interface ReactiveServiceQueryController {
      */
     @PostMapping("/_query/no-paging")
     @QueryAction
-    @QueryNoPagingOperation(summary = "使用POST方式分页动态查询(不返回总数)",
+    @Operation(summary = "使用POST方式分页动态查询(不返回总数)",
             description = "此操作不返回分页总数,如果需要获取全部数据,请设置参数paging=false")
-    default Flux query(@Parameter(hidden = true) @RequestBody Mono query) {
+    default Flux query(@RequestBody Mono query) {
         return query.flatMapMany(this::query);
     }
 
@@ -133,8 +133,8 @@ public interface ReactiveServiceQueryController {
     @PostMapping("/_query")
     @QueryAction
     @SuppressWarnings("all")
-    @QueryOperation(summary = "使用POST方式分页动态查询")
-    default Mono> queryPager(@Parameter(hidden = true) @RequestBody Mono query) {
+    @Operation(summary = "使用POST方式分页动态查询")
+    default Mono> queryPager(@RequestBody Mono query) {
         return query.flatMap(q -> queryPager(q));
     }
 
@@ -165,8 +165,8 @@ public interface ReactiveServiceQueryController {
      */
     @PostMapping("/_count")
     @QueryAction
-    @QueryNoPagingOperation(summary = "使用POST方式查询总数")
-    default Mono count(@Parameter(hidden = true) @RequestBody Mono query) {
+    @Operation(summary = "使用POST方式查询总数")
+    default Mono count(@RequestBody Mono query) {
         return query.flatMap(this::count);
     }
 
diff --git a/hsweb-concurrent/hsweb-concurrent-cache/src/main/java/org/hswebframework/web/cache/ReactiveCache.java b/hsweb-concurrent/hsweb-concurrent-cache/src/main/java/org/hswebframework/web/cache/ReactiveCache.java
index 0411631ae..6b5f0f971 100644
--- a/hsweb-concurrent/hsweb-concurrent-cache/src/main/java/org/hswebframework/web/cache/ReactiveCache.java
+++ b/hsweb-concurrent/hsweb-concurrent-cache/src/main/java/org/hswebframework/web/cache/ReactiveCache.java
@@ -26,19 +26,20 @@ public interface ReactiveCache {
     Mono clear();
 
     default CacheFlux.FluxCacheBuilderMapMiss flux(Object key) {
-        return otherSupplier ->
-                Flux.defer(() ->
-                        getFlux(key)
-                                .switchIfEmpty(otherSupplier.get()
-                                        .collectList()
-                                        .flatMapMany(values -> put(key, Flux.fromIterable(values))
-                                                .thenMany(Flux.fromIterable(values)))));
+        return otherSupplier -> Flux
+                .defer(() -> this
+                        .getFlux(key)
+                        .switchIfEmpty(otherSupplier.get()
+                                                    .collectList()
+                                                    .flatMapMany(values -> put(key, Flux.fromIterable(values))
+                                                            .thenMany(Flux.fromIterable(values)))));
     }
 
     default CacheMono.MonoCacheBuilderMapMiss mono(Object key) {
-        return otherSupplier ->
-                Mono.defer(() -> getMono(key)
+        return otherSupplier -> Mono
+                .defer(() -> this
+                        .getMono(key)
                         .switchIfEmpty(otherSupplier.get()
-                                .flatMap(value -> put(key, Mono.just(value)).thenReturn(value))));
+                                                    .flatMap(value -> put(key, Mono.just(value)).thenReturn(value))));
     }
 }
diff --git a/hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java b/hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java
index 066da714a..b80d23bf0 100644
--- a/hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java
+++ b/hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java
@@ -20,7 +20,6 @@ import java.beans.PropertyDescriptor;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Supplier;
diff --git a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationServiceAutoConfiguration.java b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationServiceAutoConfiguration.java
index a8f5e2f95..2d80c4fba 100644
--- a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationServiceAutoConfiguration.java
+++ b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationServiceAutoConfiguration.java
@@ -3,13 +3,17 @@ package org.hswebframework.web.system.authorization.defaults.configuration;
 import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
 import org.hswebframework.web.authorization.ReactiveAuthenticationInitializeService;
 import org.hswebframework.web.authorization.ReactiveAuthenticationManagerProvider;
+import org.hswebframework.web.authorization.define.AuthorizeDefinitionCustomizer;
+import org.hswebframework.web.authorization.define.CompositeAuthorizeDefinitionCustomizer;
 import org.hswebframework.web.authorization.simple.DefaultAuthorizationAutoConfiguration;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.hswebframework.web.system.authorization.api.UserDimensionProvider;
+import org.hswebframework.web.system.authorization.api.entity.PermissionEntity;
 import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
 import org.hswebframework.web.system.authorization.defaults.service.*;
 import org.hswebframework.web.system.authorization.defaults.service.terms.DimensionTerm;
 import org.hswebframework.web.system.authorization.defaults.service.terms.UserDimensionTerm;
+import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.context.annotation.Bean;
@@ -41,8 +45,9 @@ public class AuthorizationServiceAutoConfiguration {
         }
 
         @Bean
-        public PermissionSynchronization permissionSynchronization() {
-            return new PermissionSynchronization();
+        public PermissionSynchronization permissionSynchronization(ReactiveRepository permissionRepository,
+                                                                   ObjectProvider customizer) {
+            return new PermissionSynchronization(permissionRepository, new CompositeAuthorizeDefinitionCustomizer(customizer));
         }
 
         @Bean
diff --git a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java
index 7a153619e..bd8baa237 100644
--- a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java
+++ b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java
@@ -26,13 +26,20 @@ import java.util.stream.Collectors;
 @Slf4j
 public class PermissionSynchronization implements CommandLineRunner {
 
-    @Autowired
-    private ReactiveRepository permissionRepository;
+    private final ReactiveRepository permissionRepository;
+
+    private final AuthorizeDefinitionCustomizer customizer;
 
     private final MergedAuthorizeDefinition definition = new MergedAuthorizeDefinition();
 
     private final Map> entityFieldsMapping = new HashMap<>();
 
+    public PermissionSynchronization(ReactiveRepository permissionRepository,
+                                     AuthorizeDefinitionCustomizer customizer) {
+        this.permissionRepository = permissionRepository;
+        this.customizer = customizer;
+    }
+
     @EventListener
     public void handleResourceParseEvent(AuthorizeDefinitionInitializedEvent event) {
         definition.merge(event.getAllDefinition());
@@ -115,7 +122,10 @@ public class PermissionSynchronization implements CommandLineRunner {
         if (definition.getResources().isEmpty()) {
             return;
         }
-        permissionRepository.createQuery()
+        customizer.custom(definition);
+
+        permissionRepository
+                .createQuery()
                 .fetch()
                 .collect(Collectors.toMap(PermissionEntity::getId, Function.identity()))
                 .flatMap(group -> Flux.fromIterable(definition.getResources())