refactor: 优化权限注解

This commit is contained in:
zhouhao
2025-06-13 14:32:05 +08:00
parent 9e2aa16747
commit c8e5eaf0e7
9 changed files with 31 additions and 128 deletions

View File

@@ -12,6 +12,4 @@ import java.lang.annotation.*;
@ResourceAction(id = Permission.ACTION_ADD, name = "新增")
public @interface CreateAction {
@AliasFor(annotation = ResourceAction.class,attribute = "dataAccess")
DataAccess dataAccess() default @DataAccess(ignore = true);
}

View File

@@ -9,6 +9,7 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Deprecated
public @interface DataAccessType {
String id(); //标识

View File

@@ -5,13 +5,11 @@ import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@ResourceAction(id = Permission.ACTION_DELETE, name = "删除")
public @interface DeleteAction {
@AliasFor(annotation = ResourceAction.class,attribute = "dataAccess")
DataAccess dataAccess() default @DataAccess(ignore = true);
}

View File

@@ -10,6 +10,7 @@ import java.lang.annotation.*;
@Documented
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Authorize
@Deprecated
public @interface DimensionDataAccess {
Mapping[] mapping() default {};

View File

@@ -5,14 +5,11 @@ import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@ResourceAction(id = Permission.ACTION_QUERY, name = "查询")
public @interface QueryAction {
@AliasFor(annotation = ResourceAction.class,attribute = "dataAccess")
DataAccess dataAccess() default @DataAccess(ignore = true);
}

View File

@@ -5,6 +5,9 @@ import org.hswebframework.web.authorization.Permission;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 对资源操作的描述,通常用来进行权限控制.
* <p>
@@ -29,10 +32,11 @@ import java.lang.annotation.*;
* @see org.hswebframework.web.authorization.Authentication
* @see Permission#getActions()
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Target({ANNOTATION_TYPE, FIELD, METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Repeatable(ResourceAction.List.class)
public @interface ResourceAction {
/**
* 操作标识
@@ -57,9 +61,12 @@ public @interface ResourceAction {
*/
Logical logical() default Logical.DEFAULT;
/**
* @deprecated 已弃用, 4.1中移除
*/
@Deprecated
DataAccess[] dataAccess() default @DataAccess(ignore = true);
@Target({ANNOTATION_TYPE, FIELD, METHOD})
@Retention(RUNTIME)
@Documented
@Inherited
@interface List {
ResourceAction[] value();
}
}

View File

@@ -1,7 +1,6 @@
package org.hswebframework.web.authorization.annotation;
import org.hswebframework.web.authorization.Permission;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
@@ -11,14 +10,12 @@ import java.lang.annotation.*;
* @author zhouhao
* @since 4.0
*/
@Target(ElementType.METHOD)
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@ResourceAction(id = Permission.ACTION_SAVE, name = "保存")
public @interface SaveAction {
@Deprecated
@AliasFor(annotation = ResourceAction.class, attribute = "dataAccess")
DataAccess dataAccess() default @DataAccess(ignore = true);
}

View File

@@ -17,12 +17,10 @@ import java.util.stream.Stream;
public class AopAuthorizeDefinitionParser {
private static final Set<Class<? extends Annotation>> types = new HashSet<>(Arrays.asList(
Authorize.class,
DataAccess.class,
Dimension.class,
Resource.class,
ResourceAction.class,
DataAccessType.class
Authorize.class,
Dimension.class,
Resource.class,
ResourceAction.class
));
private final Set<Annotation> methodAnnotation;
@@ -45,12 +43,12 @@ public class AopAuthorizeDefinitionParser {
classAnnotation = AnnotatedElementUtils.findAllMergedAnnotations(targetClass, types);
classAnnotationGroup = classAnnotation
.stream()
.collect(Collectors.groupingBy(Annotation::annotationType));
.stream()
.collect(Collectors.groupingBy(Annotation::annotationType));
methodAnnotationGroup = methodAnnotation
.stream()
.collect(Collectors.groupingBy(Annotation::annotationType));
.stream()
.collect(Collectors.groupingBy(Annotation::annotationType));
}
private void initClassAnnotation() {
@@ -78,73 +76,13 @@ public class AopAuthorizeDefinitionParser {
}
}
private void initClassDataAccessAnnotation() {
for (Annotation annotation : classAnnotation) {
if (annotation instanceof DataAccessType ||
annotation instanceof DataAccess) {
for (ResourceDefinition resource : definition.getResources().getResources()) {
for (ResourceActionDefinition action : resource.getActions()) {
if (annotation instanceof DataAccessType) {
definition.putAnnotation(action, (DataAccessType) annotation);
} else {
definition.putAnnotation(action, (DataAccess) annotation);
}
}
}
}
}
}
private void initMethodDataAccessAnnotation() {
for (Annotation annotation : methodAnnotation) {
if (annotation instanceof ResourceAction) {
getAnnotationByType(Resource.class)
.map(res -> definition.getResources().getResource(res.id()).orElse(null))
.filter(Objects::nonNull)
.forEach(res -> {
ResourceAction ra = (ResourceAction) annotation;
ResourceActionDefinition action = definition.putAnnotation(res, ra);
getAnnotationByType(DataAccessType.class)
.findFirst()
.ifPresent(dat -> definition.putAnnotation(action, dat));
});
}
Optional<ResourceActionDefinition> actionDefinition = getAnnotationByType(Resource.class)
.map(res -> definition.getResources().getResource(res.id()).orElse(null))
.filter(Objects::nonNull)
.flatMap(res -> getAnnotationByType(ResourceAction.class)
.map(ra -> res.getAction(ra.id())
.orElse(null))
)
.filter(Objects::nonNull)
.findFirst();
if (annotation instanceof DataAccessType) {
actionDefinition.ifPresent(ra -> definition.putAnnotation(ra, (DataAccessType) annotation));
}
if (annotation instanceof DataAccess) {
actionDefinition.ifPresent(ra -> {
definition.putAnnotation(ra, (DataAccess) annotation);
getAnnotationByType(DataAccessType.class)
.findFirst()
.ifPresent(dat -> definition.putAnnotation(ra, dat));
});
}
}
}
AopAuthorizeDefinition parse() {
//没有任何注解
if (CollectionUtils.isEmpty(classAnnotation) && CollectionUtils.isEmpty(methodAnnotation)) {
return EmptyAuthorizeDefinition.instance;
}
initClassAnnotation();
initClassDataAccessAnnotation();
initMethodAnnotation();
initMethodDataAccessAnnotation();
return definition;
}
@@ -152,9 +90,9 @@ public class AopAuthorizeDefinitionParser {
private <T extends Annotation> Stream<T> getAnnotationByType(Class<T> type) {
return Optional.ofNullable(methodAnnotationGroup.getOrDefault(type, classAnnotationGroup.get(type)))
.map(Collection::stream)
.orElseGet(Stream::empty)
.map(type::cast);
.map(Collection::stream)
.orElseGet(Stream::empty)
.map(type::cast);
}
}

View File

@@ -55,15 +55,6 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition {
return allowAnonymous;
}
private static final Set<Class<? extends Annotation>> types = new HashSet<>(Arrays.asList(
Authorize.class,
DataAccess.class,
Dimension.class,
Resource.class,
ResourceAction.class,
DataAccessType.class
));
public static AopAuthorizeDefinition from(Class<?> targetClass, Method method) {
AopAuthorizeDefinitionParser parser = new AopAuthorizeDefinitionParser(targetClass, method);
@@ -121,37 +112,12 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition {
actionDefinition.setId(ann.id());
actionDefinition.setName(ann.name());
actionDefinition.setDescription(String.join("\n", ann.description()));
for (DataAccess dataAccess : ann.dataAccess()) {
putAnnotation(actionDefinition, dataAccess);
}
definition.addAction(actionDefinition);
return actionDefinition;
}
public void putAnnotation(ResourceActionDefinition definition, DataAccess ann) {
if (ann.ignore()) {
return;
}
DataAccessTypeDefinition typeDefinition = new DataAccessTypeDefinition();
for (DataAccessType dataAccessType : ann.type()) {
if (dataAccessType.ignore()) {
continue;
}
typeDefinition.setId(dataAccessType.id());
typeDefinition.setName(dataAccessType.name());
typeDefinition.setController(dataAccessType.controller());
typeDefinition.setConfiguration(dataAccessType.configuration());
typeDefinition.setDescription(String.join("\n", dataAccessType.description()));
}
if (ObjectUtils.isEmpty(typeDefinition.getId())) {
return;
}
definition.getDataAccess()
.getDataAccessTypes()
.add(typeDefinition);
}
public void putAnnotation(ResourceActionDefinition definition, DataAccessType dataAccessType) {
if (dataAccessType.ignore()) {
return;