From 1a1b38bea00f73ebfc2ab374388ec161a53554c2 Mon Sep 17 00:00:00 2001 From: zhou-hao Date: Mon, 11 Nov 2019 15:04:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../authorization/annotation/DataAccess.java | 1 - .../annotation/FieldDataAccess.java | 11 ++++ .../DefaultBasicAuthorizeDefinition.java | 28 +++++----- .../service/PermissionSynchronization.java | 54 ++++++++++++++++++- 4 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/FieldDataAccess.java 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..064571fb3 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,6 @@ import java.lang.annotation.*; * * @author zhouhao * @see DataAccessController - * @see Authorize#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/annotation/FieldDataAccess.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/FieldDataAccess.java new file mode 100644 index 000000000..cc194004d --- /dev/null +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/FieldDataAccess.java @@ -0,0 +1,11 @@ +package org.hswebframework.web.authorization.annotation; + +import java.lang.annotation.*; + +@DataAccessType(id = "DENY_FIELDS", name = "字段权限") +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) +public @interface FieldDataAccess { + +} diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java index 6eaf28a29..22ff47907 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java @@ -58,7 +58,7 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition { definition.setTargetClass(targetClass); definition.setTargetMethod(method); - Set annotations = AnnotatedElementUtils.findAllMergedAnnotations(method, types); + Set methodAnnotation = AnnotatedElementUtils.findAllMergedAnnotations(method, types); Set classAnnotation = AnnotatedElementUtils.findAllMergedAnnotations(targetClass, types); @@ -66,7 +66,7 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition { .stream() .collect(Collectors.toMap(Annotation::annotationType, Function.identity())); - Map mapping = annotations + Map mapping = methodAnnotation .stream() .collect(Collectors.toMap(Annotation::annotationType, Function.identity())); @@ -79,7 +79,7 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition { } } - for (Annotation annotation : annotations) { + for (Annotation annotation : methodAnnotation) { if (annotation instanceof Authorize) { definition.putAnnotation(((Authorize) annotation)); } @@ -91,7 +91,7 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition { } } - for (Annotation annotation : annotations) { + for (Annotation annotation : methodAnnotation) { if (annotation instanceof ResourceAction) { Optional.ofNullable(mapping.getOrDefault(Resource.class, classAnnotationMap.get(Resource.class))) @@ -107,19 +107,23 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition { .ifPresent(dat -> definition.putAnnotation(action, dat)); }); } + Optional actionDefinition = Optional.ofNullable(mapping.getOrDefault(Resource.class, classAnnotationMap.get(Resource.class))) + .map(Resource.class::cast) + .flatMap(res -> definition.getResources().getResource(res.id())) + .flatMap(res -> Optional.ofNullable(mapping.get(ResourceAction.class)) + .map(ResourceAction.class::cast) + .flatMap(ra -> res.getAction(ra.id()))); + + if (annotation instanceof DataAccessType) { + actionDefinition.ifPresent(ra -> definition.putAnnotation(ra, (DataAccessType) annotation)); + } + if (annotation instanceof DataAccess) { - Optional.ofNullable(mapping.getOrDefault(Resource.class, classAnnotationMap.get(Resource.class))) - .map(Resource.class::cast) - .flatMap(res -> definition.getResources().getResource(res.id())) - .flatMap(res -> Optional.ofNullable(mapping.get(ResourceAction.class)) - .map(ResourceAction.class::cast) - .flatMap(ra -> res.getAction(ra.id()))) - .ifPresent(ra -> { + actionDefinition.ifPresent(ra -> { definition.putAnnotation(ra, (DataAccess) annotation); Optional.ofNullable(mapping.get(DataAccessType.class)) .map(DataAccessType.class::cast) .ifPresent(dat -> definition.putAnnotation(ra, dat)); - }); } 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 638d156f4..d7ed82f6d 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 @@ -2,15 +2,28 @@ package org.hswebframework.web.system.authorization.defaults.service; import lombok.extern.slf4j.Slf4j; import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository; +import org.hswebframework.ezorm.rdb.mapping.annotation.Comment; +import org.hswebframework.utils.ClassUtils; +import org.hswebframework.web.api.crud.entity.Entity; import org.hswebframework.web.authorization.define.*; +import org.hswebframework.web.crud.web.reactive.ReactiveCrudController; +import org.hswebframework.web.crud.web.reactive.ReactiveQueryController; +import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController; +import org.hswebframework.web.crud.web.reactive.ReactiveServiceQueryController; import org.hswebframework.web.system.authorization.api.entity.ActionEntity; +import org.hswebframework.web.system.authorization.api.entity.OptionalField; import org.hswebframework.web.system.authorization.api.entity.PermissionEntity; +import org.hswebframework.web.utils.AnnotationUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.event.EventListener; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ReflectionUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import javax.persistence.Column; +import java.lang.reflect.Field; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -23,9 +36,41 @@ public class PermissionSynchronization implements CommandLineRunner { private MergedAuthorizeDefinition definition = new MergedAuthorizeDefinition(); + private Map> entityFieldsMapping = new HashMap<>(); + @EventListener public void handleResourceParseEvent(AuthorizeDefinitionInitializedEvent event) { definition.merge(event.getAllDefinition()); + for (AuthorizeDefinition authorizeDefinition : event.getAllDefinition()) { + if (authorizeDefinition.getResources().getResources().isEmpty()) { + continue; + } + String id = authorizeDefinition.getResources().getResources().iterator().next().getId(); + if (entityFieldsMapping.containsKey(id)) { + return; + } + if (authorizeDefinition instanceof AopAuthorizeDefinition) { + Class target = ((AopAuthorizeDefinition) authorizeDefinition).getTargetClass(); + if (ReactiveQueryController.class.isAssignableFrom(target) + || ReactiveServiceQueryController.class.isAssignableFrom(target)) { + Class entity = ClassUtils.getGenericType(target); + if (Entity.class.isAssignableFrom(entity)) { + Set fields = new HashSet<>(); + ReflectionUtils.doWithFields(entity, field -> { + if (null != field.getAnnotation(Column.class) && !"id".equals(field.getName())) { + OptionalField optionalField = new OptionalField(); + optionalField.setName(field.getName()); + Optional.ofNullable(field.getAnnotation(Comment.class)) + .map(Comment::value) + .ifPresent(optionalField::setDescribe); + fields.add(optionalField); + } + }); + entityFieldsMapping.put(id, new ArrayList<>(fields)); + } + } + } + } } protected PermissionEntity convert(Map old, ResourceDefinition definition) { @@ -36,13 +81,18 @@ public class PermissionSynchronization implements CommandLineRunner { .build()); entity.setId(definition.getId()); + + if (CollectionUtils.isEmpty(entity.getOptionalFields())) { + entity.setOptionalFields(entityFieldsMapping.get(entity.getId())); + } + Map oldAction = new HashMap<>(); if (entity.getActions() != null) { entity.getActions().forEach(a -> oldAction.put(a.getAction(), a)); } for (ResourceActionDefinition definitionAction : definition.getActions()) { - ActionEntity action = oldAction.getOrDefault(definition.getId(),ActionEntity + ActionEntity action = oldAction.getOrDefault(definitionAction.getId(), ActionEntity .builder() .action(definitionAction.getId()) .name(definitionAction.getName()) @@ -57,7 +107,7 @@ public class PermissionSynchronization implements CommandLineRunner { types.addAll(definitionAction.getDataAccess().getDataAccessTypes().stream().map(DataAccessTypeDefinition::getId).collect(Collectors.toSet())); action.setProperties(properties); - oldAction.put(action.getAction(),action); + oldAction.put(action.getAction(), action); } entity.setActions(new ArrayList<>(oldAction.values()));