From 343e2bed9b493c780f009c349a741864b3db7eb6 Mon Sep 17 00:00:00 2001 From: zhou-hao Date: Sat, 16 Nov 2019 12:18:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=BC=8F=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom-data-access.md | 2 +- .../authorization/annotation/DataAccess.java | 2 +- .../define/AuthorizingContext.java | 23 ---- .../basic/aop/AopAuthorizingController.java | 107 +++++++--------- .../access/DefaultDataAccessController.java | 1 - .../access/FieldFilterDataAccessHandler.java | 117 ++++++++++++------ .../aop/AopAuthorizingControllerTest.java | 44 +++++++ .../basic/aop/TestController.java | 18 ++- .../web/aop/MethodInterceptorContext.java | 16 ++- .../web/aop/MethodInterceptorHolder.java | 83 ++++++++----- ...opDataSourceSwitcherAutoConfiguration.java | 3 +- .../loggin/aop/AopAccessLoggerSupport.java | 2 +- 12 files changed, 249 insertions(+), 169 deletions(-) diff --git a/hsweb-authorization/hsweb-authorization-api/custom-data-access.md b/hsweb-authorization/hsweb-authorization-api/custom-data-access.md index a0fdcad30..1258315f1 100644 --- a/hsweb-authorization/hsweb-authorization-api/custom-data-access.md +++ b/hsweb-authorization/hsweb-authorization-api/custom-data-access.md @@ -40,7 +40,7 @@ public class MyDataAccessHandler implements org.hswebframework.web.authorization @Override public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) { //被拦截的方法参数 - Map param= context.getParams(); + Map param= context.getNamedArguments(); // 判断逻辑 //... return true; diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/DataAccess.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/DataAccess.java index fcec6dc0c..7b3478bb6 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/DataAccess.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/DataAccess.java @@ -29,7 +29,7 @@ import java.lang.annotation.*; * * @author zhouhao * @see DataAccessController - * @see Authorize#dataAccess() + * @see ResourceAction#dataAccess() * @since 3.0 */ @Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD}) diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizingContext.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizingContext.java index e8657afaf..bef19d1ac 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizingContext.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizingContext.java @@ -21,27 +21,4 @@ public class AuthorizingContext { private MethodInterceptorContext paramContext; - public AuthorizeDefinition getDefinition() { - return definition; - } - - public void setDefinition(AuthorizeDefinition definition) { - this.definition = definition; - } - - public Authentication getAuthentication() { - return authentication; - } - - public void setAuthentication(Authentication authentication) { - this.authentication = authentication; - } - - public MethodInterceptorContext getParamContext() { - return paramContext; - } - - public void setParamContext(MethodInterceptorContext paramContext) { - this.paramContext = paramContext; - } } diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java index 10772ccaa..bc22cf901 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java @@ -1,5 +1,6 @@ package org.hswebframework.web.authorization.basic.aop; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -11,10 +12,12 @@ import org.hswebframework.web.authorization.basic.handler.AuthorizingHandler; import org.hswebframework.web.authorization.define.*; import org.hswebframework.web.authorization.exception.UnAuthorizedException; import org.hswebframework.web.utils.AnnotationUtils; +import org.reactivestreams.Publisher; import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; @@ -22,6 +25,10 @@ import reactor.core.publisher.Mono; import java.lang.reflect.Method; import java.util.List; +import java.util.concurrent.Callable; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -51,81 +58,48 @@ public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor this.autoParse = autoParse; } - protected Mono handleReactive(AuthorizeDefinition definition, MethodInterceptorHolder holder, AuthorizingContext context, Mono mono) { - return Authentication.currentReactive() - .switchIfEmpty(Mono.error(new UnAuthorizedException())) - .flatMap(auth -> { - ResourcesDefinition resources = definition.getResources(); - - context.setAuthentication(auth); - if (definition.getPhased() == Phased.before) { - authorizingHandler.handRBAC(context); - if (resources != null && resources.getPhased() == Phased.before) { - authorizingHandler.handleDataAccess(context); - } else { - return mono.doOnNext(res -> { - context.setParamContext(holder.createParamContext(res)); - authorizingHandler.handleDataAccess(context); - }); - } - } else { - if (resources != null && resources.getPhased() == Phased.before) { - authorizingHandler.handleDataAccess(context); - return mono.doOnNext(res -> { - context.setParamContext(holder.createParamContext(res)); - authorizingHandler.handRBAC(context); - }); - } else { - return mono.doOnNext(res -> { - context.setParamContext(holder.createParamContext(res)); - authorizingHandler.handle(context); - }); - } - - } - return mono; - }); - } - - protected Flux handleReactive(AuthorizeDefinition definition, MethodInterceptorHolder holder, AuthorizingContext context, Flux flux) { + protected Publisher handleReactive0(AuthorizeDefinition definition, + MethodInterceptorHolder holder, + AuthorizingContext context, + Supplier> invoker) { return Authentication.currentReactive() .switchIfEmpty(Mono.error(new UnAuthorizedException())) .flatMapMany(auth -> { - ResourcesDefinition resources = definition.getResources(); - context.setAuthentication(auth); - if (definition.getPhased() == Phased.before) { + Function afterRuner = runnable -> { + MethodInterceptorContext interceptorContext = holder.createParamContext(invoker.get()); + runnable.run(); + return (Publisher) interceptorContext.getInvokeResult(); + }; + if (context.getDefinition().getPhased() != Phased.after) { authorizingHandler.handRBAC(context); - if (resources != null && resources.getPhased() == Phased.before) { + if (context.getDefinition().getResources().getPhased() != Phased.after) { authorizingHandler.handleDataAccess(context); + return invoker.get(); } else { - return flux.doOnNext(res -> { - context.setParamContext(holder.createParamContext(res)); + return afterRuner.apply(() -> authorizingHandler.handleDataAccess(context)); + } + + } else { + if (context.getDefinition().getResources().getPhased() != Phased.after) { + authorizingHandler.handleDataAccess(context); + return invoker.get(); + } else { + return afterRuner.apply(() -> { + authorizingHandler.handRBAC(context); authorizingHandler.handleDataAccess(context); }); } - } else { - - if (resources != null && resources.getPhased() == Phased.before) { - authorizingHandler.handleDataAccess(context); - return flux.doOnNext(res -> { - context.setParamContext(holder.createParamContext(res)); - authorizingHandler.handRBAC(context); - }); - } else { - return flux.doOnNext(res -> { - context.setParamContext(holder.createParamContext(res)); - authorizingHandler.handle(context); - }); - } - } - return flux; }); } + @SneakyThrows + private T doProceed(MethodInvocation invocation) { + return (T) invocation.proceed(); + } @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { @@ -136,17 +110,20 @@ public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor AuthorizeDefinition definition = aopMethodAuthorizeDefinitionParser.parse(methodInvocation.getThis().getClass(), methodInvocation.getMethod(), paramContext); Object result = null; boolean isControl = false; - if (null != definition) { + if (null != definition && !definition.isEmpty()) { AuthorizingContext context = new AuthorizingContext(); context.setDefinition(definition); context.setParamContext(paramContext); Class returnType = methodInvocation.getMethod().getReturnType(); //handle reactive method - if (Mono.class.isAssignableFrom(returnType)) { - return handleReactive(definition, holder, context, ((Mono) methodInvocation.proceed())); - } else if (Flux.class.isAssignableFrom(returnType)) { - return handleReactive(definition, holder, context, ((Flux) methodInvocation.proceed())); + if (Publisher.class.isAssignableFrom(returnType)) { + Publisher publisher = handleReactive0(definition, holder, context, () -> doProceed(methodInvocation)); + if (Mono.class.isAssignableFrom(returnType)) { + return Mono.from(publisher); + } else if (Flux.class.isAssignableFrom(returnType)) { + return Flux.from(publisher); + } } Authentication authentication = Authentication.current().orElseThrow(UnAuthorizedException::new); @@ -224,7 +201,7 @@ public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor log.info("publish AuthorizeDefinitionInitializedEvent,definition size:{}", definitions.size()); eventPublisher.publishEvent(new AuthorizeDefinitionInitializedEvent(definitions)); - // defaultParser.destroy(); + // defaultParser.destroy(); } } diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java index ef859a5b1..0b1480ba9 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java @@ -30,7 +30,6 @@ public final class DefaultDataAccessController implements DataAccessController { throw new UnsupportedOperationException(); } this.parent = parent; - addHandler(new FieldFilterDataAccessHandler()); } diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java index cb58d53c5..11878aca3 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java @@ -8,10 +8,13 @@ import org.hswebframework.web.authorization.access.DataAccessHandler; import org.hswebframework.web.authorization.access.FieldFilterDataAccessConfig; import org.hswebframework.web.authorization.define.AuthorizingContext; import org.hswebframework.web.authorization.define.Phased; +import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import java.util.Collection; -import java.util.Map; import java.util.Set; /** @@ -46,6 +49,22 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler { } } + protected void applyUpdateParam(FieldFilterDataAccessConfig config, Object... parameter) { + + for (Object data : parameter) { + for (String field : config.getFields()) { + try { + //设置值为null,跳过修改 + BeanUtilsBean.getInstance() + .getPropertyUtils() + .setProperty(data, field, null); + } catch (Exception e) { + logger.warn("can't set {} null", field, e); + } + } + } + } + /** * @param accesses 不可操作的字段 * @param params 参数上下文 @@ -54,52 +73,80 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler { * @see org.apache.commons.beanutils.PropertyUtilsBean */ protected boolean doUpdateAccess(FieldFilterDataAccessConfig accesses, AuthorizingContext params) { - Map paramsMap = params.getParamContext().getParams(); - Object supportParam = paramsMap.size() == 1 ? - paramsMap.values().iterator().next() : - paramsMap.values().stream() - // .filter(param -> (param instanceof Entity) || (param instanceof Model) || (param instanceof Map)) - .findAny() - .orElse(null); - if (null != supportParam) { - for (String field : accesses.getFields()) { - try { - //设置值为null,跳过修改 - BeanUtilsBean.getInstance() - .getPropertyUtils() - .setProperty(supportParam, field, null); - } catch (Exception e) { - logger.warn("can't set {} null", field, e); - } + boolean reactive = params.getParamContext().handleReactiveArguments(publisher -> { + if (publisher instanceof Mono) { + return Mono.from(publisher) + .doOnNext(data -> applyUpdateParam(accesses, data)); + } - } else { - logger.warn("doUpdateAccess skip ,because can not found any support entity in param!"); + if (publisher instanceof Flux) { + return Flux.from(publisher) + .doOnNext(data -> applyUpdateParam(accesses, data)); + + } + return publisher; + }); + if (reactive) { + return true; } + + applyUpdateParam(accesses, params.getParamContext().getArguments()); return true; } + @SuppressWarnings("all") + protected void applyQueryParam(FieldFilterDataAccessConfig config, Object param) { + if (param instanceof QueryParam) { + Set denyFields = config.getFields(); + ((QueryParam) param).excludes(denyFields.toArray(new String[0])); + return; + } + + Object r = InvokeResultUtils.convertRealResult(param); + if (r instanceof Collection) { + ((Collection) r).forEach(o -> setObjectPropertyNull(o, config.getFields())); + } else { + setObjectPropertyNull(r, config.getFields()); + } + + } + @SuppressWarnings("all") protected boolean doQueryAccess(FieldFilterDataAccessConfig access, AuthorizingContext context) { if (context.getDefinition().getResources().getPhased() == Phased.before) { - QueryParam entity = context.getParamContext().getParams() - .values().stream() - .filter(QueryParam.class::isInstance) - .map(QueryParam.class::cast) - .findAny().orElse(null); - if (entity == null) { - logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity"); + + boolean reactive = context + .getParamContext() + .handleReactiveArguments(publisher -> { + if (publisher instanceof Mono) { + return Mono.from(publisher) + .doOnNext(param -> { + applyQueryParam(access, param); + }); + } + return publisher; + }); + + if (reactive) { return true; } - Set denyFields = access.getFields(); - entity.excludes(denyFields.toArray(new String[denyFields.size()])); - } else { - Object result = InvokeResultUtils.convertRealResult(context.getParamContext().getInvokeResult()); - if (result instanceof Collection) { - ((Collection) result).forEach(o -> setObjectPropertyNull(o, access.getFields())); - } else { - setObjectPropertyNull(result, access.getFields()); + + for (Object argument : context.getParamContext().getArguments()) { + applyQueryParam(access, argument); } + } else { + if (context.getParamContext().getInvokeResult() instanceof Publisher) { + context.getParamContext().setInvokeResult( + Flux.from((Publisher) context.getParamContext().getInvokeResult()) + .doOnNext(result -> { + applyQueryParam(access, result); + }) + ); + + return true; + } + applyQueryParam(access, context.getParamContext().getInvokeResult()); } return true; } diff --git a/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java b/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java index 54d525038..2b6454ebd 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java @@ -1,13 +1,17 @@ package org.hswebframework.web.authorization.basic.aop; +import org.hswebframework.ezorm.core.param.Param; +import org.hswebframework.ezorm.core.param.QueryParam; import org.hswebframework.web.authorization.Authentication; import org.hswebframework.web.authorization.ReactiveAuthenticationHolder; import org.hswebframework.web.authorization.ReactiveAuthenticationSupplier; import org.hswebframework.web.authorization.User; +import org.hswebframework.web.authorization.basic.handler.access.FieldFilterDataAccessHandler; import org.hswebframework.web.authorization.basic.web.ReactiveUserTokenParser; import org.hswebframework.web.authorization.exception.AccessDenyException; import org.hswebframework.web.authorization.exception.UnAuthorizedException; import org.hswebframework.web.authorization.simple.SimpleAuthentication; +import org.hswebframework.web.authorization.simple.SimpleFieldFilterDataAccessConfig; import org.hswebframework.web.authorization.simple.SimplePermission; import org.hswebframework.web.authorization.simple.SimpleUser; import org.hswebframework.web.authorization.token.ParsedToken; @@ -25,6 +29,7 @@ import reactor.test.StepVerifier; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import static org.junit.Assert.*; @@ -69,4 +74,43 @@ public class AopAuthorizingControllerTest { .expectNext("403") .verifyComplete(); } + + @Test + public void testFiledDeny(){ + SimpleAuthentication authentication = new SimpleAuthentication(); + + SimpleFieldFilterDataAccessConfig config=new SimpleFieldFilterDataAccessConfig(); + config.setAction("query"); + config.setFields(new HashSet<>(Arrays.asList("name"))); + + authentication.setUser(SimpleUser.builder().id("test").username("test").build()); + authentication.setPermissions(Arrays.asList(SimplePermission.builder() + .actions(Collections.singleton("query")) + .dataAccesses(Collections.singleton(config)) + .id("test").build())); + + ReactiveAuthenticationHolder.addSupplier(new ReactiveAuthenticationSupplier() { + @Override + public Mono get(String userId) { + return Mono.empty(); + } + + @Override + public Mono get() { + return Mono.just(authentication); + } + }); + + testController.queryUser(new QueryParam()) + .map(Param::getExcludes) + .as(StepVerifier::create) + .expectNextMatches(f->f.contains("name")) + .verifyComplete(); + + testController.queryUser(Mono.just(new QueryParam())) + .map(Param::getExcludes) + .as(StepVerifier::create) + .expectNextMatches(f->f.contains("name")) + .verifyComplete(); + } } \ No newline at end of file diff --git a/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/TestController.java b/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/TestController.java index 6c2576a51..5a0900960 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/TestController.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/TestController.java @@ -1,10 +1,10 @@ package org.hswebframework.web.authorization.basic.aop; +import org.hswebframework.ezorm.core.param.QueryParam; import org.hswebframework.web.authorization.Authentication; import org.hswebframework.web.authorization.User; -import org.hswebframework.web.authorization.annotation.Authorize; -import org.hswebframework.web.authorization.annotation.QueryAction; -import org.hswebframework.web.authorization.annotation.Resource; +import org.hswebframework.web.authorization.access.DataAccessConfig; +import org.hswebframework.web.authorization.annotation.*; import org.hswebframework.web.authorization.define.Phased; import org.hswebframework.web.authorization.exception.UnAuthorizedException; import org.springframework.web.bind.annotation.RestController; @@ -27,4 +27,16 @@ public class TestController { .switchIfEmpty(Mono.error(new UnAuthorizedException())) .map(Authentication::getUser); } + + @QueryAction(dataAccess = @DataAccess(type = @DataAccessType(id= DataAccessConfig.DefaultType.DENY_FIELDS,name = "禁止访问字段"))) + public Mono queryUser(QueryParam queryParam) { + return Mono.just(queryParam); + } + + @QueryAction(dataAccess = @DataAccess(type = @DataAccessType(id= DataAccessConfig.DefaultType.DENY_FIELDS,name = "禁止访问字段"))) + public Mono queryUser(Mono queryParam) { + return queryParam; + } + + } diff --git a/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorContext.java b/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorContext.java index 92377be60..10676e266 100644 --- a/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorContext.java +++ b/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorContext.java @@ -18,11 +18,14 @@ package org.hswebframework.web.aop; +import org.reactivestreams.Publisher; + import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Map; import java.util.Optional; +import java.util.function.Function; /** * AOP拦截到方法的参数上下文,用于获取当前进行操作的方法的各种参数信息,如:当前所在类实例,参数集合,注解 @@ -55,7 +58,7 @@ public interface MethodInterceptorContext extends Serializable { * @param 参数泛型 * @return Optional */ - Optional getParameter(String name); + Optional getArgument(String name); /** * 获取当前操作方法或实例上指定类型的泛型,如果方法上未获取到,则获取实例类上的注解。实例类上未获取到,则返回null @@ -70,9 +73,16 @@ public interface MethodInterceptorContext extends Serializable { * 获取全部参数 * * @return 参数集合 - * @see this#getParameter(String) + * @see this#getArgument(String) */ - Map getParams(); + Map getNamedArguments(); + + Object[] getArguments(); + + boolean handleReactiveArguments(Function, Publisher> handler); Object getInvokeResult(); + + void setInvokeResult(Object result); + } diff --git a/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorHolder.java b/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorHolder.java index 1b75be203..8588d574e 100644 --- a/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorHolder.java +++ b/hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorHolder.java @@ -18,22 +18,29 @@ package org.hswebframework.web.aop; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.aopalliance.intercept.MethodInvocation; import org.hswebframework.web.utils.AnnotationUtils; +import org.reactivestreams.Publisher; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.util.DigestUtils; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; import java.util.Optional; +import java.util.function.Function; /** * @author zhouhao */ +@AllArgsConstructor +@Getter public class MethodInterceptorHolder { /** * 参数名称获取器,用于获取方法参数的名称 @@ -48,9 +55,12 @@ public class MethodInterceptorHolder { for (int i = 0, len = args.length; i < len; i++) { argMap.put((argNames == null || argNames[i] == null) ? "arg" + i : argNames[i], args[i]); } + return new MethodInterceptorHolder(id, invocation.getMethod(), - invocation.getThis(), argMap); + invocation.getThis(), + args, + argMap); } private String id; @@ -59,34 +69,10 @@ public class MethodInterceptorHolder { private Object target; - private Map args; + private Object[] arguments; - public MethodInterceptorHolder(String id, Method method, Object target, Map args) { - Objects.requireNonNull(id); - Objects.requireNonNull(method); - Objects.requireNonNull(target); - Objects.requireNonNull(args); - this.id = id; - this.method = method; - this.target = target; - this.args = args; - } + private Map namedArguments; - public String getId() { - return id; - } - - public Method getMethod() { - return method; - } - - public Object getTarget() { - return target; - } - - public Map getArgs() { - return args; - } public T findMethodAnnotation(Class annClass) { return AnnotationUtils.findMethodAnnotation(annClass, method, annClass); @@ -107,6 +93,30 @@ public class MethodInterceptorHolder { public MethodInterceptorContext createParamContext(Object invokeResult) { return new MethodInterceptorContext() { private static final long serialVersionUID = -4102787561601219273L; + private Object result = invokeResult; + + @Override + public Object[] getArguments() { + return arguments; + } + + public boolean handleReactiveArguments(Function, Publisher> handler) { + boolean handled = false; + Object[] args = getArguments(); + if (args == null || args.length == 0) { + return false; + } + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + if (arg instanceof Publisher) { + args[i] = handler.apply(((Mono) arg)); + handled = true; + } + } + + return handled; + } + @Override public Object getTarget() { @@ -119,11 +129,11 @@ public class MethodInterceptorHolder { } @Override - public Optional getParameter(String name) { - if (args == null) { + public Optional getArgument(String name) { + if (namedArguments == null) { return Optional.empty(); } - return Optional.ofNullable((T) args.get(name)); + return Optional.ofNullable((T) namedArguments.get(name)); } @Override @@ -132,13 +142,18 @@ public class MethodInterceptorHolder { } @Override - public Map getParams() { - return getArgs(); + public Map getNamedArguments() { + return MethodInterceptorHolder.this.getNamedArguments(); } @Override public Object getInvokeResult() { - return invokeResult; + return result; + } + + @Override + public void setInvokeResult(Object result) { + this.result = result; } }; } diff --git a/hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/AopDataSourceSwitcherAutoConfiguration.java b/hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/AopDataSourceSwitcherAutoConfiguration.java index 64f0c82a5..1a7a92995 100644 --- a/hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/AopDataSourceSwitcherAutoConfiguration.java +++ b/hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/AopDataSourceSwitcherAutoConfiguration.java @@ -22,7 +22,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -import java.util.function.Function; import static org.hswebframework.web.datasource.strategy.AnnotationDataSourceSwitchStrategyMatcher.*; @@ -112,7 +111,7 @@ public class AopDataSourceSwitcherAutoConfiguration { String id = strategy.getDataSourceId(); if (StringUtils.hasText(id)) { if (id.contains("${")) { - id = ExpressionUtils.analytical(id, context.getParams(), "spel"); + id = ExpressionUtils.analytical(id, context.getNamedArguments(), "spel"); } if (!DataSourceHolder.existing(id)) { if (strategy.isFallbackDefault()) { diff --git a/hsweb-logging/hsweb-access-logging-aop/src/main/java/org/hswebframework/web/loggin/aop/AopAccessLoggerSupport.java b/hsweb-logging/hsweb-access-logging-aop/src/main/java/org/hswebframework/web/loggin/aop/AopAccessLoggerSupport.java index 0ad1876f9..1623a124f 100644 --- a/hsweb-logging/hsweb-access-logging-aop/src/main/java/org/hswebframework/web/loggin/aop/AopAccessLoggerSupport.java +++ b/hsweb-logging/hsweb-access-logging-aop/src/main/java/org/hswebframework/web/loggin/aop/AopAccessLoggerSupport.java @@ -90,7 +90,7 @@ public class AopAccessLoggerSupport extends StaticMethodMatcherPointcutAdvisor { info.setAction(define.getAction()); info.setDescribe(define.getDescribe()); } - info.setParameters(holder.getArgs()); + info.setParameters(holder.getNamedArguments()); info.setTarget(holder.getTarget().getClass()); info.setMethod(holder.getMethod()); From 10ae5fa528b5423d103fc506cbd8de0ac77dcacc Mon Sep 17 00:00:00 2001 From: zhou-hao Date: Sun, 17 Nov 2019 21:28:12 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pom.xml | 22 +++++++++++++++ .../DepartmentAttachEntity.java | 9 ++++++ .../organizational/DistrictAttachEntity.java | 10 +++++++ .../OrganizationAttachEntity.java | 10 +++++++ .../organizational/OrganizationDimension.java | 28 +++++++++++++++++++ .../organizational/PositionAttachEntity.java | 9 ++++++ .../annotation/DistrictDataAccess.java | 17 +++++++++++ .../hsweb-system-organizational/pom.xml | 19 +++++++++++++ hsweb-system/pom.xml | 1 + 9 files changed, 125 insertions(+) create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/pom.xml create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DepartmentAttachEntity.java create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DistrictAttachEntity.java create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationAttachEntity.java create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationDimension.java create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/PositionAttachEntity.java create mode 100644 hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/annotation/DistrictDataAccess.java create mode 100644 hsweb-system/hsweb-system-organizational/pom.xml diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/pom.xml b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/pom.xml new file mode 100644 index 000000000..06a659869 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/pom.xml @@ -0,0 +1,22 @@ + + + + hsweb-system-organizational + org.hswebframework.web + 4.0.0-SNAPSHOT + + 4.0.0 + + hsweb-system-organizational-authorization + + + + org.hswebframework.web + hsweb-authorization-api + ${project.version} + + + + \ No newline at end of file diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DepartmentAttachEntity.java b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DepartmentAttachEntity.java new file mode 100644 index 000000000..533ba81a5 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DepartmentAttachEntity.java @@ -0,0 +1,9 @@ +package org.hswebframework.web.organizational; + +public interface DepartmentAttachEntity { + + String getDepartmentId(); + + void setDepartmentId(String positionId); + +} diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DistrictAttachEntity.java b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DistrictAttachEntity.java new file mode 100644 index 000000000..eb4b8c701 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/DistrictAttachEntity.java @@ -0,0 +1,10 @@ +package org.hswebframework.web.organizational; + + +public interface DistrictAttachEntity { + + String getDistrictId(); + + void serDistrictId(String districtId); + +} diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationAttachEntity.java b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationAttachEntity.java new file mode 100644 index 000000000..72cef61a5 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationAttachEntity.java @@ -0,0 +1,10 @@ +package org.hswebframework.web.organizational; + + +public interface OrganizationAttachEntity { + + String getOrgId(); + + void serOrgId(String orgId); + +} diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationDimension.java b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationDimension.java new file mode 100644 index 000000000..aea210600 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/OrganizationDimension.java @@ -0,0 +1,28 @@ +package org.hswebframework.web.organizational; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.hswebframework.web.authorization.DimensionType; + +@Getter +@AllArgsConstructor +public enum OrganizationDimension implements DimensionType { + + district("行政区"), + organization("机构"), + department("部门"), + position("岗位"), + person("人员"), + + ; + + + private String name; + + @Override + public String getId() { + return name(); + } + + +} diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/PositionAttachEntity.java b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/PositionAttachEntity.java new file mode 100644 index 000000000..70d9c7360 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/PositionAttachEntity.java @@ -0,0 +1,9 @@ +package org.hswebframework.web.organizational; + +public interface PositionAttachEntity { + + String getPositionId(); + + void setPositionId(String positionId); + +} diff --git a/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/annotation/DistrictDataAccess.java b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/annotation/DistrictDataAccess.java new file mode 100644 index 000000000..7ce678fa8 --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/annotation/DistrictDataAccess.java @@ -0,0 +1,17 @@ +package org.hswebframework.web.organizational.annotation; + +import org.hswebframework.web.authorization.annotation.DataAccessType; + +import java.lang.annotation.*; + +/** + * @see org.hswebframework.web.organizational.DistrictAttachEntity + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +@DataAccessType(id = "district", name = "行政区划") +public @interface DistrictDataAccess { + +} diff --git a/hsweb-system/hsweb-system-organizational/pom.xml b/hsweb-system/hsweb-system-organizational/pom.xml new file mode 100644 index 000000000..057a0c6ee --- /dev/null +++ b/hsweb-system/hsweb-system-organizational/pom.xml @@ -0,0 +1,19 @@ + + + + hsweb-system + org.hswebframework.web + 4.0.0-SNAPSHOT + + 4.0.0 + + hsweb-system-organizational + pom + + hsweb-system-organizational-authorization + + + + \ No newline at end of file diff --git a/hsweb-system/pom.xml b/hsweb-system/pom.xml index 8004899e0..a741a0f6b 100644 --- a/hsweb-system/pom.xml +++ b/hsweb-system/pom.xml @@ -15,6 +15,7 @@ hsweb-system-authorization hsweb-system-file hsweb-system-dictionary + hsweb-system-organizational hsweb-system