feat:搞定用户关联授权逻辑

This commit is contained in:
wangyu 2022-01-10 23:55:06 +08:00
parent 6528c43626
commit e09b5efbfe
6 changed files with 192 additions and 46 deletions

View File

@ -0,0 +1,56 @@
package com.flyfish.framework.domain.authorized;
import com.flyfish.framework.builder.CriteriaBuilder;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.domain.po.Department;
import lombok.Setter;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.data.mongodb.core.query.Criteria;
import java.util.Collections;
import java.util.Set;
/**
* 公共方法封装
*
* @param <T> 泛型
*/
@Setter
public abstract class AbstractAuthorizedQo<T extends AuthorizedDomain> extends NameLikeQo<T> {
// 是否已发布
protected Boolean published;
/**
* 获取可见的权限ids
*
* @return 结果
*/
protected Set<String> authorizeIds() {
if (user instanceof AuthorizedUserDetails) {
return ((AuthorizedUserDetails) user).getAuthorityCodes();
}
return Collections.singleton(Department.PUBLIC);
}
/**
* 构造发布状态查询
*
* @return 结果
*/
protected Criteria withPublished() {
if (null != published) {
if (BooleanUtils.isTrue(published)) {
return Criteria.where("published").is(true);
}
return Criteria.where("$or").is(
CriteriaBuilder.createCriteriaList(
Criteria.where("published").isNull(),
Criteria.where("published").is(false)
)
);
}
return null;
}
}

View File

@ -1,18 +1,12 @@
package com.flyfish.framework.domain.authorized; package com.flyfish.framework.domain.authorized;
import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.builder.CriteriaBuilder;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.domain.po.Department;
import com.flyfish.framework.enums.UserType; import com.flyfish.framework.enums.UserType;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import java.util.Collections;
import java.util.Set;
/** /**
* 带鉴权的查询实体主要以部门隔绝 * 带鉴权的查询实体主要以部门隔绝
* *
@ -20,23 +14,7 @@ import java.util.Set;
*/ */
@Getter @Getter
@Setter @Setter
public class AuthorizedQo<T extends AuthorizedDomain> extends NameLikeQo<T> { public class AuthorizedQo<T extends AuthorizedDomain> extends AbstractAuthorizedQo<T> {
// 是否已发布
@Getter(AccessLevel.NONE)
private Boolean published;
/**
* 获取可见的权限ids
*
* @return 结果
*/
private Set<String> authorizeIds() {
if (user instanceof AuthorizedUserDetails) {
return ((AuthorizedUserDetails) user).getAuthorityCodes();
}
return Collections.singleton(Department.PUBLIC);
}
@Override @Override
public CriteriaBuilder<T> criteriaBuilder() { public CriteriaBuilder<T> criteriaBuilder() {
@ -62,23 +40,4 @@ public class AuthorizedQo<T extends AuthorizedDomain> extends NameLikeQo<T> {
)); ));
} }
/**
* 构造发布状态查询
*
* @return 结果
*/
private Criteria withPublished() {
if (null != published) {
if (BooleanUtils.isTrue(published)) {
return Criteria.where("published").is(true);
}
return Criteria.where("$or").is(
CriteriaBuilder.createCriteriaList(
Criteria.where("published").isNull(),
Criteria.where("published").is(false)
)
);
}
return null;
}
} }

View File

@ -0,0 +1,28 @@
package com.flyfish.framework.domain.authorized.advanced;
import com.flyfish.framework.annotations.Order;
import com.flyfish.framework.annotations.Property;
import com.flyfish.framework.domain.authorized.AuthorizedDomain;
import com.flyfish.framework.domain.po.User;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.DBRef;
import java.util.List;
/**
* 具有特例拥有权限的实体
*
* @author wangyu
*/
@Getter
@Setter
public abstract class OwnedAuthorizedDomain extends AuthorizedDomain {
// 关联账号
@Property("关联账号")
@Order(Integer.MAX_VALUE)
@DBRef
private List<User> owners;
}

View File

@ -0,0 +1,53 @@
package com.flyfish.framework.domain.authorized.advanced;
import com.flyfish.framework.builder.CriteriaBuilder;
import com.flyfish.framework.domain.authorized.AbstractAuthorizedQo;
import com.flyfish.framework.domain.authorized.AuthorizedUserDetails;
import com.flyfish.framework.enums.UserType;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.BooleanUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
/**
* 拥有归属权的授权查询
*
* @param <T> 泛型
* @author wangyu
* 将会额外查询归属者的内容
*/
@Getter
@Setter
public class OwnedAuthorizedQo<T extends OwnedAuthorizedDomain> extends AbstractAuthorizedQo<T> {
@Override
public CriteriaBuilder<T> criteriaBuilder() {
// 超级管理员拥有查看所有草稿的权限
if (user.getType() == UserType.SUPER_ADMIN) {
return super.criteriaBuilder().with(this::withPublished);
}
// 查询草稿只查询自己的
if (BooleanUtils.isFalse(published)) {
return super.criteriaBuilder()
.with(this::withPublished)
.with(() -> Criteria.where("$or").is(
CriteriaBuilder.createCriteriaList(
Criteria.where("creatorId").is(user.getId()),
Criteria.where("owners.$id").is(new ObjectId(user.getId()))
)
));
}
// 普通查询根据权限配置查询
return super.criteriaBuilder()
.with(this::withPublished)
.with(() -> Criteria.where("$or").is(
CriteriaBuilder.createCriteriaList(
Criteria.where("authorizeId").in(authorizeIds()),
Criteria.where("creatorId").is(user.getId())
.and("authorizeId").in(((AuthorizedUserDetails) user).getVisibleDeparts()),
Criteria.where("owners.$id").is(new ObjectId(user.getId()))
)
));
}
}

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.flyfish.framework.annotations.Properties; import com.flyfish.framework.annotations.Properties;
import com.flyfish.framework.annotations.*; import com.flyfish.framework.annotations.*;
import com.flyfish.framework.beans.enums.ValidationCandidate; import com.flyfish.framework.beans.enums.ValidationCandidate;
import com.flyfish.framework.beans.meta.builtin.BeanUris;
import com.flyfish.framework.beans.meta.parser.BeanPropertyAnnotations; import com.flyfish.framework.beans.meta.parser.BeanPropertyAnnotations;
import com.flyfish.framework.beans.meta.parser.SimpleBeanPropertyAnnotations; import com.flyfish.framework.beans.meta.parser.SimpleBeanPropertyAnnotations;
import com.flyfish.framework.domain.base.Qo; import com.flyfish.framework.domain.base.Qo;
@ -25,6 +26,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
@ -217,9 +219,10 @@ public class BeanProperty {
case LIST: case LIST:
if (null != field) { if (null != field) {
// 是附件展现附件列表 // 是附件展现附件列表
ReflectionUtils.getGenericType(field) Class<?> elementClass = ReflectionUtils.getGenericType(field).orElse(Object.class);
.filter(property::isAttachment) if (property.isAttachment(elementClass)) {
.ifPresent(item -> property.prop("attachment", true)); property.prop("attachment", true);
}
annotations annotations
.as(SubBean.class) .as(SubBean.class)
.map(MergedAnnotation::synthesize) .map(MergedAnnotation::synthesize)
@ -245,6 +248,12 @@ public class BeanProperty {
property.setType(BeanPropertyType.DB_REF); property.setType(BeanPropertyType.DB_REF);
property.prop("uri", ref).prop("mode", "multiple"); property.prop("uri", ref).prop("mode", "multiple");
})) }))
.or()
.as(DBRef.class)
.then(a -> processDbRef(elementClass).ifPresent(ref -> {
property.setType(BeanPropertyType.DB_REF);
property.prop("uri", ref).prop("mode", "multiple");
}))
.end(); .end();
} }
break; break;
@ -338,7 +347,11 @@ public class BeanProperty {
*/ */
private static Optional<String> processDbRef(Class<?> clazz) { private static Optional<String> processDbRef(Class<?> clazz) {
return Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(clazz, Document.class)) return Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(clazz, Document.class))
.map(Document::value); .map(document -> {
String collection = document.value();
return StringUtils.isNotBlank(collection) ? collection :
BeanUris.getUri(clazz).orElse(StringFormats.camel2Line(clazz.getSimpleName()));
});
} }
/** /**

View File

@ -0,0 +1,37 @@
package com.flyfish.framework.beans.meta.builtin;
import com.flyfish.framework.domain.po.Department;
import com.flyfish.framework.domain.po.Permission;
import com.flyfish.framework.domain.po.Role;
import com.flyfish.framework.domain.po.User;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* 内置的uris
*
* @author wangyu
*/
public class BeanUris {
private static final Map<Class<?>, String> uris = new HashMap<>();
static {
uris.put(User.class, "users");
uris.put(Department.class, "departments");
uris.put(Role.class, "roles");
uris.put(Permission.class, "permissions");
}
/**
* 获取uri
*
* @param clazz
* @return 结果
*/
public static Optional<String> getUri(Class<?> clazz) {
return Optional.ofNullable(uris.get(clazz));
}
}