-
Notifications
You must be signed in to change notification settings - Fork 612
/
ClusterRoleMapper.java
129 lines (113 loc) · 4.72 KB
/
ClusterRoleMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package org.infinispan.security.mappers;
import java.security.Principal;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import org.infinispan.Cache;
import org.infinispan.commons.marshall.ProtoStreamTypeIds;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.context.Flag;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.factories.annotations.Start;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;
import org.infinispan.protostream.annotations.ProtoTypeId;
import org.infinispan.registry.InternalCacheRegistry;
import org.infinispan.security.MutablePrincipalRoleMapper;
import org.infinispan.security.PrincipalRoleMapper;
import org.infinispan.security.PrincipalRoleMapperContext;
/**
* ClusterRoleMapper. This class implements both a {@link MutablePrincipalRoleMapper} storing the mappings in a
* persistent replicated internal cache named <tt>org.infinispan.ROLES</tt>
*
* @author Tristan Tarrant
* @since 7.0
*/
@Scope(Scopes.GLOBAL)
public class ClusterRoleMapper implements MutablePrincipalRoleMapper {
private EmbeddedCacheManager cacheManager;
private static final String CLUSTER_ROLE_MAPPER_CACHE = "org.infinispan.ROLES";
private Cache<String, RoleSet> clusterRoleMap;
private Cache<String, RoleSet> clusterRoleReadMap;
@Start
void start() {
clusterRoleMap = cacheManager.getCache(CLUSTER_ROLE_MAPPER_CACHE);
clusterRoleReadMap = clusterRoleMap.getAdvancedCache().withFlags(Flag.SKIP_CACHE_LOAD, Flag.CACHE_MODE_LOCAL);
}
@Override
public Set<String> principalToRoles(Principal principal) {
if (clusterRoleReadMap == null) {
return Collections.singleton(principal.getName());
}
RoleSet roleSet = clusterRoleReadMap.get(principal.getName());
if (roleSet != null && !roleSet.roles.isEmpty()) {
return roleSet.roles;
} else {
return Collections.singleton(principal.getName());
}
}
@Override
public void setContext(PrincipalRoleMapperContext context) {
this.cacheManager = context.getCacheManager();
GlobalConfiguration globalConfiguration = SecurityActions.getCacheManagerConfiguration(cacheManager);
CacheMode cacheMode = globalConfiguration.isClustered() ? CacheMode.REPL_SYNC : CacheMode.LOCAL;
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg.clustering().cacheMode(cacheMode)
.stateTransfer().fetchInMemoryState(true).awaitInitialTransfer(globalConfiguration.isClustered())
.security().authorization().disable();
GlobalComponentRegistry registry = SecurityActions.getGlobalComponentRegistry(cacheManager);
InternalCacheRegistry internalCacheRegistry = registry.getComponent(InternalCacheRegistry.class);
internalCacheRegistry.registerInternalCache(CLUSTER_ROLE_MAPPER_CACHE, cfg.build(), EnumSet.of(InternalCacheRegistry.Flag.PERSISTENT));
registry.registerComponent(this, PrincipalRoleMapper.class);
}
@Override
public void grant(String roleName, String principalName) {
RoleSet roleSet = clusterRoleMap.computeIfAbsent(principalName, n -> new RoleSet());
roleSet.roles.add(roleName);
clusterRoleMap.put(principalName, roleSet);
}
@Override
public void deny(String roleName, String principalName) {
RoleSet roleSet = clusterRoleMap.computeIfAbsent(principalName, n -> new RoleSet());
roleSet.roles.remove(roleName);
clusterRoleMap.put(principalName, roleSet);
}
@Override
public Set<String> list(String principalName) {
RoleSet roleSet = clusterRoleMap.get(principalName);
if (roleSet != null) {
return Collections.unmodifiableSet(roleSet.roles);
} else {
return Collections.singleton(principalName);
}
}
@Override
public String listAll() {
StringBuilder sb = new StringBuilder();
for (RoleSet set : clusterRoleMap.values()) {
sb.append(set.roles.toString());
}
return sb.toString();
}
@ProtoTypeId(ProtoStreamTypeIds.ROLE_SET)
public static class RoleSet {
@ProtoField(number = 1, collectionImplementation = HashSet.class)
final Set<String> roles;
RoleSet() {
this(new HashSet());
}
@ProtoFactory
RoleSet(Set<String> roles) {
this.roles = roles;
}
public Set<String> getRoles() {
return roles;
}
}
}