Skip to content

Commit 470c1a0

Browse files
committed
增加DimensionManager
1 parent 0658d64 commit 470c1a0

File tree

8 files changed

+305
-46
lines changed

8 files changed

+305
-46
lines changed

hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/DimensionProvider.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,57 @@
33
import reactor.core.publisher.Flux;
44
import reactor.core.publisher.Mono;
55

6+
import java.util.Collection;
7+
8+
/**
9+
* 维度提供商,用户管理维度信息
10+
*
11+
* @author zhouhao
12+
* @since 4.0
13+
*/
614
public interface DimensionProvider {
715

16+
/**
17+
* 获取全部支持的维度
18+
*
19+
* @return 全部支持的维度
20+
*/
821
Flux<? extends DimensionType> getAllType();
922

23+
/**
24+
* 获取用户获取维度信息
25+
*
26+
* @param userId 用户ID
27+
* @return 维度列表
28+
*/
1029
Flux<? extends Dimension> getDimensionByUserId(String userId);
1130

31+
/**
32+
* 根据维度类型和ID获取维度信息
33+
*
34+
* @param type 类型
35+
* @param id ID
36+
* @return 维度信息
37+
*/
1238
Mono<? extends Dimension> getDimensionById(DimensionType type, String id);
1339

14-
Flux<String> getUserIdByDimensionId(String dimensionId);
40+
/**
41+
* 根据维度类型和Id获取多个维度
42+
* @param type 类型
43+
* @param idList ID
44+
* @return 维度信息
45+
*/
46+
default Flux<? extends Dimension> getDimensionsById(DimensionType type, Collection<String> idList){
47+
return Flux
48+
.fromIterable(idList)
49+
.flatMap(id->this.getDimensionById(type,id));
50+
}
1551

52+
/**
53+
* 根据维度ID获取用户ID
54+
*
55+
* @param dimensionId 维度ID
56+
* @return 用户ID
57+
*/
58+
Flux<String> getUserIdByDimensionId(String dimensionId);
1659
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.hswebframework.web.authorization.dimension;
2+
3+
import reactor.core.publisher.Flux;
4+
5+
import java.util.Collection;
6+
7+
/**
8+
* 维度管理器
9+
*
10+
* @author zhouhao
11+
* @since 4.0.12
12+
*/
13+
public interface DimensionManager {
14+
15+
/**
16+
* 获取用户维度
17+
*
18+
* @param type 维度类型
19+
* @param userId 用户ID
20+
* @return 用户维度信息
21+
*/
22+
Flux<DimensionUserDetail> getUserDimension(Collection<String> userId);
23+
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.hswebframework.web.authorization.dimension;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.Setter;
7+
8+
@Getter
9+
@Setter
10+
@AllArgsConstructor(staticName = "of")
11+
@NoArgsConstructor
12+
public class DimensionUserBind {
13+
private String userId;
14+
15+
private String dimensionType;
16+
17+
private String dimensionId;
18+
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.hswebframework.web.authorization.dimension;
2+
3+
import reactor.core.publisher.Flux;
4+
5+
import java.util.Collection;
6+
7+
public interface DimensionUserBindProvider {
8+
9+
Flux<DimensionUserBind> getDimensionBindInfo(Collection<String> userIdList);
10+
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.hswebframework.web.authorization.dimension;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.Setter;
7+
import org.hswebframework.web.authorization.Dimension;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
@Getter
13+
@Setter
14+
@AllArgsConstructor(staticName = "of")
15+
@NoArgsConstructor
16+
public class DimensionUserDetail {
17+
private String userId;
18+
19+
private List<Dimension> dimensions;
20+
21+
public DimensionUserDetail merge(DimensionUserDetail detail) {
22+
DimensionUserDetail newDetail = new DimensionUserDetail();
23+
newDetail.setUserId(userId);
24+
newDetail.setDimensions(new ArrayList<>());
25+
if (null != dimensions) {
26+
newDetail.dimensions.addAll(dimensions);
27+
}
28+
if (null != detail.getDimensions()) {
29+
newDetail.dimensions.addAll(detail.getDimensions());
30+
}
31+
return newDetail;
32+
}
33+
}

hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/DefaultAuthorizationAutoConfiguration.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import org.hswebframework.web.authorization.*;
44
import org.hswebframework.web.authorization.builder.AuthenticationBuilderFactory;
55
import org.hswebframework.web.authorization.builder.DataAccessConfigBuilderFactory;
6+
import org.hswebframework.web.authorization.dimension.DimensionManager;
7+
import org.hswebframework.web.authorization.dimension.DimensionUserBindProvider;
68
import org.hswebframework.web.authorization.simple.builder.DataAccessConfigConverter;
79
import org.hswebframework.web.authorization.simple.builder.SimpleAuthenticationBuilderFactory;
810
import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
911
import org.hswebframework.web.authorization.token.*;
1012
import org.hswebframework.web.authorization.twofactor.TwoFactorValidatorManager;
1113
import org.hswebframework.web.authorization.twofactor.defaults.DefaultTwoFactorValidatorManager;
1214
import org.hswebframework.web.convert.CustomMessageConverter;
15+
import org.springframework.beans.factory.ObjectProvider;
1316
import org.springframework.beans.factory.annotation.Autowired;
1417
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
1518
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -100,4 +103,15 @@ public Object convert(Class clazz, byte[] message) {
100103
}
101104
};
102105
}
106+
107+
@Bean
108+
@ConditionalOnMissingBean(DimensionManager.class)
109+
public DimensionManager defaultDimensionManager(ObjectProvider<DimensionUserBindProvider>bindProviders,
110+
ObjectProvider<DimensionProvider> providers){
111+
DefaultDimensionManager manager = new DefaultDimensionManager();
112+
bindProviders.forEach(manager::addBindProvider);
113+
providers.forEach(manager::addProvider);
114+
115+
return manager;
116+
}
103117
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package org.hswebframework.web.authorization.simple;
2+
3+
import org.hswebframework.web.authorization.Dimension;
4+
import org.hswebframework.web.authorization.DimensionProvider;
5+
import org.hswebframework.web.authorization.dimension.DimensionManager;
6+
import org.hswebframework.web.authorization.dimension.DimensionUserBind;
7+
import org.hswebframework.web.authorization.dimension.DimensionUserBindProvider;
8+
import org.hswebframework.web.authorization.dimension.DimensionUserDetail;
9+
import reactor.core.publisher.Flux;
10+
import reactor.core.publisher.Mono;
11+
import reactor.util.function.Tuple2;
12+
import reactor.util.function.Tuples;
13+
14+
import java.util.*;
15+
import java.util.concurrent.CopyOnWriteArrayList;
16+
import java.util.function.Function;
17+
import java.util.stream.Collectors;
18+
19+
public class DefaultDimensionManager implements DimensionManager {
20+
21+
private final List<DimensionProvider> dimensionProviders = new CopyOnWriteArrayList<>();
22+
private final List<DimensionUserBindProvider> bindProviders = new CopyOnWriteArrayList<>();
23+
24+
private final Mono<Map<String, DimensionProvider>> providerMapping = Flux
25+
.defer(() -> Flux.fromIterable(dimensionProviders))
26+
.flatMap(provider -> provider
27+
.getAllType()
28+
.map(type -> Tuples.of(type.getId(), provider)))
29+
.collectMap(Tuple2::getT1, Tuple2::getT2);
30+
31+
public DefaultDimensionManager() {
32+
33+
}
34+
35+
public void addProvider(DimensionProvider provider) {
36+
dimensionProviders.add(provider);
37+
}
38+
39+
public void addBindProvider(DimensionUserBindProvider bindProvider) {
40+
bindProviders.add(bindProvider);
41+
}
42+
43+
private Mono<Map<String, DimensionProvider>> providerMapping() {
44+
return providerMapping;
45+
}
46+
47+
@Override
48+
public Flux<DimensionUserDetail> getUserDimension(Collection<String> userId) {
49+
return this
50+
.providerMapping()
51+
.flatMapMany(providerMapping -> Flux
52+
.fromIterable(bindProviders)
53+
//获取绑定信息
54+
.flatMap(provider -> provider.getDimensionBindInfo(userId))
55+
.groupBy(DimensionUserBind::getDimensionType)
56+
.flatMap(group -> {
57+
String type = String.valueOf(group.key());
58+
Flux<DimensionUserBind> binds = group.cache();
59+
DimensionProvider provider = providerMapping.get(type);
60+
if (null == provider) {
61+
return Mono.empty();
62+
}
63+
//获取维度信息
64+
return binds
65+
.map(DimensionUserBind::getDimensionId)
66+
.collect(Collectors.toSet())
67+
.flatMapMany(idList -> provider.getDimensionsById(SimpleDimensionType.of(type), idList))
68+
.collectMap(Dimension::getId, Function.identity())
69+
.flatMapMany(mapping -> binds
70+
.groupBy(DimensionUserBind::getUserId)
71+
.flatMap(userGroup -> Mono
72+
.zip(
73+
Mono.just(String.valueOf(userGroup.key())),
74+
userGroup
75+
.<Dimension>handle((bind, sink) -> {
76+
Dimension dimension = mapping.get(bind.getDimensionId());
77+
if (dimension != null) {
78+
sink.next(dimension);
79+
}
80+
})
81+
.collectList(),
82+
DimensionUserDetail::of
83+
))
84+
);
85+
})
86+
)
87+
.groupBy(DimensionUserDetail::getUserId)
88+
.flatMap(group->group.reduce(DimensionUserDetail::merge));
89+
}
90+
}

0 commit comments

Comments
 (0)