role cached queries
This commit is contained in:
parent
daa09f9a41
commit
4dcdaf4985
21 changed files with 631 additions and 266 deletions
|
@ -463,11 +463,18 @@ public class ClientAdapter implements ClientModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateDefaultRoles(String[] defaultRoles) {
|
||||
public void updateDefaultRoles(String... defaultRoles) {
|
||||
getDelegateForUpdate();
|
||||
updated.updateDefaultRoles(defaultRoles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultRoles(String... defaultRoles) {
|
||||
getDelegateForUpdate();
|
||||
updated.removeDefaultRoles(defaultRoles);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBearerOnly() {
|
||||
if (updated != null) return updated.isBearerOnly();
|
||||
|
@ -542,12 +549,10 @@ public class ClientAdapter implements ClientModel {
|
|||
|
||||
@Override
|
||||
public RoleModel getRole(String name) {
|
||||
if (updated != null) return updated.getRole(name);
|
||||
String id = cached.getRoles().get(name);
|
||||
if (id == null) {
|
||||
return null;
|
||||
for (RoleModel role : getRoles()) {
|
||||
if (role.getName().equals(name)) return role;
|
||||
}
|
||||
return cacheSession.getRoleById(id, cachedRealm);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -575,15 +580,7 @@ public class ClientAdapter implements ClientModel {
|
|||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles() {
|
||||
if (updated != null) return updated.getRoles();
|
||||
|
||||
Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||
for (String id : cached.getRoles().values()) {
|
||||
RoleModel roleById = cacheSession.getRoleById(id, cachedRealm);
|
||||
if (roleById == null) continue;
|
||||
roles.add(roleById);
|
||||
}
|
||||
return roles;
|
||||
return cacheSession.getClientRoles(cachedRealm, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -581,11 +581,18 @@ public class RealmAdapter implements RealmModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateDefaultRoles(String[] defaultRoles) {
|
||||
public void updateDefaultRoles(String... defaultRoles) {
|
||||
getDelegateForUpdate();
|
||||
updated.updateDefaultRoles(defaultRoles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultRoles(String... defaultRoles) {
|
||||
getDelegateForUpdate();
|
||||
updated.removeDefaultRoles(defaultRoles);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientModel> getClients() {
|
||||
return cacheSession.getClients(this);
|
||||
|
@ -870,12 +877,18 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public RoleModel getRole(String name) {
|
||||
if (updated != null) return updated.getRole(name);
|
||||
String id = cached.getRealmRoles().get(name);
|
||||
if (id == null) return null;
|
||||
return cacheSession.getRoleById(id, this);
|
||||
for (RoleModel role : getRoles()) {
|
||||
if (role.getName().equals(name)) return role;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles() {
|
||||
return cacheSession.getRealmRoles(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String name) {
|
||||
getDelegateForUpdate();
|
||||
|
@ -899,18 +912,6 @@ public class RealmAdapter implements RealmModel {
|
|||
return updated.removeRole(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles() {
|
||||
if (updated != null) return updated.getRoles();
|
||||
|
||||
Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||
for (String id : cached.getRealmRoles().values()) {
|
||||
RoleModel roleById = cacheSession.getRoleById(id, this);
|
||||
if (roleById == null) continue;
|
||||
roles.add(roleById);
|
||||
}
|
||||
return Collections.unmodifiableSet(roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdentityFederationEnabled() {
|
||||
|
|
|
@ -37,7 +37,8 @@ import org.keycloak.models.cache.infinispan.entities.CachedRealmRole;
|
|||
import org.keycloak.models.cache.infinispan.entities.CachedRole;
|
||||
import org.keycloak.models.cache.infinispan.entities.ClientListQuery;
|
||||
import org.keycloak.models.cache.infinispan.entities.RealmListQuery;
|
||||
import org.keycloak.models.cache.infinispan.entities.Revisioned;
|
||||
import org.keycloak.models.cache.infinispan.entities.RoleListQuery;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -77,7 +78,7 @@ import java.util.Set;
|
|||
* - realm client lists need to be invalidated and evited whenever a client is added or removed from a realm. RealmProvider
|
||||
* now has addClient/removeClient at its top level. All adapaters should use these methods so that the appropriate invalidations
|
||||
* can be registered.
|
||||
* - whenever a client is added/removed the realm of the client is added to a clientListInvalidations set
|
||||
* - whenever a client is added/removed the realm of the client is added to a listInvalidations set
|
||||
* this set must be checked before sending back or caching a cached query. This check is required to
|
||||
* avoid caching an uncommitted removal/add in a query cache.
|
||||
* - when a client is removed, any queries that contain that client must also be removed.
|
||||
|
@ -104,6 +105,8 @@ import java.util.Set;
|
|||
public class StreamCacheRealmProvider implements CacheRealmProvider {
|
||||
protected static final Logger logger = Logger.getLogger(StreamCacheRealmProvider.class);
|
||||
public static final String REALM_CLIENTS_QUERY_SUFFIX = ".realm.clients";
|
||||
public static final String ROLES_QUERY_SUFFIX = ".roles";
|
||||
public static final String ROLE_BY_NAME_QUERY_SUFFIX = ".role.by-name";
|
||||
protected StreamRealmCache cache;
|
||||
protected KeycloakSession session;
|
||||
protected RealmProvider delegate;
|
||||
|
@ -115,7 +118,7 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
|
|||
protected Map<String, ClientTemplateModel> managedClientTemplates = new HashMap<>();
|
||||
protected Map<String, RoleModel> managedRoles = new HashMap<>();
|
||||
protected Map<String, GroupModel> managedGroups = new HashMap<>();
|
||||
protected Set<String> clientListInvalidations = new HashSet<>();
|
||||
protected Set<String> listInvalidations = new HashSet<>();
|
||||
protected Set<String> invalidations = new HashSet<>();
|
||||
|
||||
protected boolean clearAll;
|
||||
|
@ -386,7 +389,7 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
|
|||
invalidations.add(client.getId());
|
||||
cache.clientAdded(realm.getId(), client.getId(), invalidations);
|
||||
// this is needed so that a new client that hasn't been committed isn't cached in a query
|
||||
clientListInvalidations.add(realm.getId());
|
||||
listInvalidations.add(realm.getId());
|
||||
return client;
|
||||
}
|
||||
|
||||
|
@ -394,10 +397,17 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
|
|||
return realm + REALM_CLIENTS_QUERY_SUFFIX;
|
||||
}
|
||||
|
||||
private String getRolesCacheKey(String container) {
|
||||
return container + ROLES_QUERY_SUFFIX;
|
||||
}
|
||||
private String getRoleByNameCacheKey(String container, String name) {
|
||||
return container + "." + name + ROLES_QUERY_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientModel> getClients(RealmModel realm) {
|
||||
String cacheKey = getRealmClientsQueryCacheKey(realm.getId());
|
||||
boolean queryDB = invalidations.contains(cacheKey) || clientListInvalidations.contains(realm.getId());
|
||||
boolean queryDB = invalidations.contains(cacheKey) || listInvalidations.contains(realm.getId());
|
||||
if (queryDB) {
|
||||
return getDelegate().getClients(realm);
|
||||
}
|
||||
|
@ -430,6 +440,7 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
|
|||
return list;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean removeClient(String id, RealmModel realm) {
|
||||
ClientModel client = getClientById(id, realm);
|
||||
|
@ -437,7 +448,7 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
|
|||
// need to invalidate realm client query cache every time client list is changed
|
||||
invalidations.add(getRealmClientsQueryCacheKey(realm.getId()));
|
||||
invalidations.add(getClientByClientIdCacheKey(client.getClientId(), realm));
|
||||
clientListInvalidations.add(realm.getId());
|
||||
listInvalidations.add(realm.getId());
|
||||
registerClientInvalidation(id);
|
||||
cache.clientRemoval(realm.getId(), id, invalidations);
|
||||
for (RoleModel role : client.getRoles()) {
|
||||
|
@ -451,6 +462,177 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
|
|||
if (delegate != null) delegate.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String name) {
|
||||
return addRealmRole(realm, KeycloakModelUtils.generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String id, String name) {
|
||||
invalidations.add(getRolesCacheKey(realm.getId()));
|
||||
// this is needed so that a new role that hasn't been committed isn't cached in a query
|
||||
listInvalidations.add(realm.getId());
|
||||
RoleModel role = getDelegate().addRealmRole(realm, name);
|
||||
invalidations.add(role.getId());
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRealmRoles(RealmModel realm) {
|
||||
String cacheKey = getRolesCacheKey(realm.getId());
|
||||
boolean queryDB = invalidations.contains(cacheKey) || listInvalidations.contains(realm.getId());
|
||||
if (queryDB) {
|
||||
return getDelegate().getRealmRoles(realm);
|
||||
}
|
||||
|
||||
RoleListQuery query = cache.get(cacheKey, RoleListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("getRealmRoles cache hit: {0}", realm.getName());
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
Set<RoleModel> model = getDelegate().getRealmRoles(realm);
|
||||
if (model == null) return null;
|
||||
Set<String> ids = new HashSet<>();
|
||||
for (RoleModel role : model) ids.add(role.getId());
|
||||
query = new RoleListQuery(loaded, cacheKey, realm, ids);
|
||||
logger.tracev("adding realm roles cache miss: realm {0} key {1}", realm.getName(), cacheKey);
|
||||
cache.addRevisioned(query);
|
||||
return model;
|
||||
}
|
||||
Set<RoleModel> list = new HashSet<>();
|
||||
for (String id : query.getRoles()) {
|
||||
RoleModel role = session.realms().getRoleById(id, realm);
|
||||
if (role == null) {
|
||||
invalidations.add(cacheKey);
|
||||
return getDelegate().getRealmRoles(realm);
|
||||
}
|
||||
list.add(role);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getClientRoles(RealmModel realm, ClientModel client) {
|
||||
String cacheKey = getRolesCacheKey(client.getId());
|
||||
boolean queryDB = invalidations.contains(cacheKey) || listInvalidations.contains(client.getId());
|
||||
if (queryDB) {
|
||||
return getDelegate().getClientRoles(realm, client);
|
||||
}
|
||||
|
||||
RoleListQuery query = cache.get(cacheKey, RoleListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("getClientRoles cache hit: {0}", client.getClientId());
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
Set<RoleModel> model = getDelegate().getClientRoles(realm, client);
|
||||
if (model == null) return null;
|
||||
Set<String> ids = new HashSet<>();
|
||||
for (RoleModel role : model) ids.add(role.getId());
|
||||
query = new RoleListQuery(loaded, cacheKey, realm, ids, client.getClientId());
|
||||
logger.tracev("adding client roles cache miss: client {0} key {1}", client.getClientId(), cacheKey);
|
||||
cache.addRevisioned(query);
|
||||
return model;
|
||||
}
|
||||
Set<RoleModel> list = new HashSet<>();
|
||||
for (String id : query.getRoles()) {
|
||||
RoleModel role = session.realms().getRoleById(id, realm);
|
||||
if (role == null) {
|
||||
invalidations.add(cacheKey);
|
||||
return getDelegate().getClientRoles(realm, client);
|
||||
}
|
||||
list.add(role);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String name) {
|
||||
return addClientRole(realm, client, KeycloakModelUtils.generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String id, String name) {
|
||||
invalidations.add(getRolesCacheKey(client.getId()));
|
||||
// this is needed so that a new role that hasn't been committed isn't cached in a query
|
||||
listInvalidations.add(client.getId());
|
||||
RoleModel role = getDelegate().addClientRole(realm, client, id, name);
|
||||
invalidations.add(role.getId());
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRealmRole(RealmModel realm, String name) {
|
||||
String cacheKey = getRoleByNameCacheKey(realm.getId(), name);
|
||||
boolean queryDB = invalidations.contains(cacheKey) || listInvalidations.contains(realm.getId());
|
||||
if (queryDB) {
|
||||
return getDelegate().getRealmRole(realm, name);
|
||||
}
|
||||
|
||||
RoleListQuery query = cache.get(cacheKey, RoleListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("getRealmRole cache hit: {0}.{1}", realm.getName(), name);
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
RoleModel model = getDelegate().getRealmRole(realm, name);
|
||||
if (model == null) return null;
|
||||
query = new RoleListQuery(loaded, cacheKey, realm, model.getId());
|
||||
logger.tracev("adding realm role cache miss: client {0} key {1}", realm.getName(), cacheKey);
|
||||
cache.addRevisioned(query);
|
||||
return model;
|
||||
}
|
||||
RoleModel role = getRoleById(query.getRoles().iterator().next(), realm);
|
||||
if (role == null) {
|
||||
invalidations.add(cacheKey);
|
||||
return getDelegate().getRealmRole(realm, name);
|
||||
}
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getClientRole(RealmModel realm, ClientModel client, String name) {
|
||||
String cacheKey = getRoleByNameCacheKey(client.getId(), name);
|
||||
boolean queryDB = invalidations.contains(cacheKey) || listInvalidations.contains(client.getId());
|
||||
if (queryDB) {
|
||||
return getDelegate().getClientRole(realm, client, name);
|
||||
}
|
||||
|
||||
RoleListQuery query = cache.get(cacheKey, RoleListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("getClientRole cache hit: {0}.{1}", client.getClientId(), name);
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
RoleModel model = getDelegate().getClientRole(realm, client, name);
|
||||
if (model == null) return null;
|
||||
query = new RoleListQuery(loaded, cacheKey, realm, model.getId(), client.getClientId());
|
||||
logger.tracev("adding client role cache miss: client {0} key {1}", client.getClientId(), cacheKey);
|
||||
cache.addRevisioned(query);
|
||||
return model;
|
||||
}
|
||||
RoleModel role = getRoleById(query.getRoles().iterator().next(), realm);
|
||||
if (role == null) {
|
||||
invalidations.add(cacheKey);
|
||||
return getDelegate().getClientRole(realm, client, name);
|
||||
}
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeRole(RealmModel realm, RoleModel role) {
|
||||
invalidations.add(getRolesCacheKey(role.getContainer().getId()));
|
||||
invalidations.add(getRoleByNameCacheKey(role.getContainer().getId(), role.getName()));
|
||||
listInvalidations.add(role.getContainer().getId());
|
||||
invalidations.add(role.getId());
|
||||
return getDelegate().removeRole(realm, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRoleById(String id, RealmModel realm) {
|
||||
CachedRole cached = cache.get(id, CachedRole.class);
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.keycloak.models.cache.infinispan.stream.HasRolePredicate;
|
|||
import org.keycloak.models.cache.infinispan.stream.InClientPredicate;
|
||||
import org.keycloak.models.cache.infinispan.stream.InRealmPredicate;
|
||||
import org.keycloak.models.cache.infinispan.stream.RealmQueryPredicate;
|
||||
import org.keycloak.models.cache.infinispan.stream.RoleQueryPredicate;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -287,9 +288,6 @@ public class StreamRealmCache {
|
|||
} else if (object instanceof CachedClient) {
|
||||
CachedClient cached = (CachedClient)object;
|
||||
Predicate<Map.Entry<String, Revisioned>> predicate = getClientRemovalPredicate(cached.getRealm(), cached.getId());
|
||||
for (String roleId : cached.getRoles().values()) {
|
||||
predicate.or(getRoleRemovalPredicate(roleId));
|
||||
}
|
||||
return predicate;
|
||||
} else if (object instanceof CachedRole) {
|
||||
CachedRole cached = (CachedRole)object;
|
||||
|
|
|
@ -67,7 +67,6 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
protected boolean implicitFlowEnabled;
|
||||
protected boolean directAccessGrantsEnabled;
|
||||
protected boolean serviceAccountsEnabled;
|
||||
protected Map<String, String> roles = new HashMap<String, String>();
|
||||
protected int nodeReRegistrationTimeout;
|
||||
protected Map<String, Integer> registeredNodes;
|
||||
protected String clientTemplate;
|
||||
|
@ -110,7 +109,6 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
implicitFlowEnabled = model.isImplicitFlowEnabled();
|
||||
directAccessGrantsEnabled = model.isDirectAccessGrantsEnabled();
|
||||
serviceAccountsEnabled = model.isServiceAccountsEnabled();
|
||||
cacheRoles(model);
|
||||
|
||||
nodeReRegistrationTimeout = model.getNodeReRegistrationTimeout();
|
||||
registeredNodes = new TreeMap<>(model.getRegisteredNodes());
|
||||
|
@ -122,12 +120,6 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
useTemplateScope = model.useTemplateScope();
|
||||
}
|
||||
|
||||
protected void cacheRoles(ClientModel model) {
|
||||
for (RoleModel role : model.getRoles()) {
|
||||
roles.put(role.getName(), role.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
@ -244,10 +236,6 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
return serviceAccountsEnabled;
|
||||
}
|
||||
|
||||
public Map<String, String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public int getNodeReRegistrationTimeout() {
|
||||
return nodeReRegistrationTimeout;
|
||||
}
|
||||
|
|
|
@ -145,8 +145,6 @@ public class CachedRealm extends AbstractRevisioned {
|
|||
|
||||
protected List<String> defaultGroups = new LinkedList<String>();
|
||||
protected Set<String> groups = new HashSet<String>();
|
||||
protected Map<String, String> realmRoles = new HashMap<String, String>();
|
||||
protected List<String> clients = new LinkedList<>();
|
||||
protected List<String> clientTemplates= new LinkedList<>();
|
||||
protected boolean internationalizationEnabled;
|
||||
protected Set<String> supportedLocales;
|
||||
|
@ -240,10 +238,6 @@ public class CachedRealm extends AbstractRevisioned {
|
|||
ClientModel masterAdminClient = model.getMasterAdminClient();
|
||||
this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null;
|
||||
|
||||
cacheRealmRoles(model);
|
||||
|
||||
cacheClients(model);
|
||||
|
||||
cacheClientTemplates(model);
|
||||
|
||||
internationalizationEnabled = model.isInternationalizationEnabled();
|
||||
|
@ -288,19 +282,6 @@ public class CachedRealm extends AbstractRevisioned {
|
|||
}
|
||||
}
|
||||
|
||||
protected void cacheClients(RealmModel model) {
|
||||
for (ClientModel client : model.getClients()) {
|
||||
clients.add(client.getId());
|
||||
}
|
||||
}
|
||||
|
||||
protected void cacheRealmRoles(RealmModel model) {
|
||||
for (RoleModel role : model.getRoles()) {
|
||||
realmRoles.put(role.getName(), role.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getMasterAdminClient() {
|
||||
return masterAdminClient;
|
||||
}
|
||||
|
@ -321,14 +302,6 @@ public class CachedRealm extends AbstractRevisioned {
|
|||
return defaultRoles;
|
||||
}
|
||||
|
||||
public Map<String, String> getRealmRoles() {
|
||||
return realmRoles;
|
||||
}
|
||||
|
||||
public List<String> getClients() {
|
||||
return clients;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
|
68
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/RoleListQuery.java
vendored
Executable file
68
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/RoleListQuery.java
vendored
Executable file
|
@ -0,0 +1,68 @@
|
|||
package org.keycloak.models.cache.infinispan.entities;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.cache.infinispan.entities.AbstractRevisioned;
|
||||
import org.keycloak.models.cache.infinispan.entities.ClientQuery;
|
||||
import org.keycloak.models.cache.infinispan.entities.RoleQuery;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RoleListQuery extends AbstractRevisioned implements RoleQuery, InClient {
|
||||
private final Set<String> roles;
|
||||
private final String realm;
|
||||
private final String realmName;
|
||||
private String client;
|
||||
|
||||
public RoleListQuery(Long revisioned, String id, RealmModel realm, Set<String> roles) {
|
||||
super(revisioned, id);
|
||||
this.realm = realm.getId();
|
||||
this.realmName = realm.getName();
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public RoleListQuery(Long revisioned, String id, RealmModel realm, String role) {
|
||||
super(revisioned, id);
|
||||
this.realm = realm.getId();
|
||||
this.realmName = realm.getName();
|
||||
this.roles = new HashSet<>();
|
||||
this.roles.add(role);
|
||||
}
|
||||
|
||||
public RoleListQuery(Long revision, String id, RealmModel realm, Set<String> roles, String client) {
|
||||
this(revision, id, realm, roles);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public RoleListQuery(Long revision, String id, RealmModel realm, String role, String client) {
|
||||
this(revision, id, realm, role);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientId() {
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RoleListQuery{" +
|
||||
"id='" + getId() + "'" +
|
||||
"realmName='" + realmName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package org.keycloak.models.cache.infinispan.stream;
|
|||
import org.keycloak.models.cache.infinispan.entities.CachedGroup;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedRole;
|
||||
import org.keycloak.models.cache.infinispan.entities.Revisioned;
|
||||
import org.keycloak.models.cache.infinispan.entities.RoleQuery;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
@ -36,6 +37,10 @@ public class HasRolePredicate implements Predicate<Map.Entry<String, Revisioned>
|
|||
CachedGroup cachedRole = (CachedGroup)value;
|
||||
if (cachedRole.getRoleMappings().contains(role)) return true;
|
||||
}
|
||||
if (value instanceof RoleQuery) {
|
||||
RoleQuery roleQuery = (RoleQuery)value;
|
||||
if (roleQuery.getRoles().contains(role)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -612,31 +612,17 @@ public class ClientAdapter implements ClientModel {
|
|||
|
||||
@Override
|
||||
public RoleModel getRole(String name) {
|
||||
TypedQuery<String> query = em.createNamedQuery("getClientRoleIdByName", String.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("client", entity.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
if (roles.size() == 0) return null;
|
||||
return session.realms().getRoleById(roles.get(0), realm);
|
||||
return session.realms().getClientRole(realm, this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String name) {
|
||||
return this.addRole(KeycloakModelUtils.generateId(), name);
|
||||
return session.realms().addClientRole(realm, this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String id, String name) {
|
||||
RoleEntity roleEntity = new RoleEntity();
|
||||
roleEntity.setId(id);
|
||||
roleEntity.setName(name);
|
||||
roleEntity.setClient(entity);
|
||||
roleEntity.setClientRole(true);
|
||||
roleEntity.setRealmId(realm.getId());
|
||||
entity.getRoles().add(roleEntity);
|
||||
em.persist(roleEntity);
|
||||
em.flush();
|
||||
return new RoleAdapter(session, realm, em, roleEntity);
|
||||
return session.realms().addClientRole(realm, this, id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -650,7 +636,6 @@ public class ClientAdapter implements ClientModel {
|
|||
RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em);
|
||||
if (!role.isClientRole()) return false;
|
||||
|
||||
entity.getRoles().remove(role);
|
||||
entity.getDefaultRoles().remove(role);
|
||||
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
|
||||
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", role).executeUpdate();
|
||||
|
@ -666,24 +651,7 @@ public class ClientAdapter implements ClientModel {
|
|||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles() {
|
||||
Set<RoleModel> list = new HashSet<RoleModel>();
|
||||
TypedQuery<RoleEntity> query = em.createNamedQuery("getClientRoles", RoleEntity.class);
|
||||
query.setParameter("client", entity);
|
||||
List<RoleEntity> roles = query.getResultList();
|
||||
for (RoleEntity roleEntity : roles) {
|
||||
list.add(new RoleAdapter(session, realm, em, roleEntity));
|
||||
}
|
||||
|
||||
/*
|
||||
TypedQuery<String> query = em.createNamedQuery("getClientRoleIds", String.class);
|
||||
query.setParameter("client", entity.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
for (String id : roles) {
|
||||
list.add(session.realms().getRoleById(id, realm));
|
||||
}
|
||||
*/
|
||||
return list;
|
||||
|
||||
return session.realms().getClientRoles(realm, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -733,10 +701,10 @@ public class ClientAdapter implements ClientModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateDefaultRoles(String[] defaultRoles) {
|
||||
public void updateDefaultRoles(String... defaultRoles) {
|
||||
Collection<RoleEntity> entities = entity.getDefaultRoles();
|
||||
Set<String> already = new HashSet<String>();
|
||||
List<RoleEntity> remove = new ArrayList<RoleEntity>();
|
||||
List<RoleEntity> remove = new ArrayList<>();
|
||||
for (RoleEntity rel : entities) {
|
||||
if (!contains(rel.getName(), defaultRoles)) {
|
||||
remove.add(rel);
|
||||
|
@ -756,6 +724,24 @@ public class ClientAdapter implements ClientModel {
|
|||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultRoles(String... defaultRoles) {
|
||||
Collection<RoleEntity> entities = entity.getDefaultRoles();
|
||||
List<RoleEntity> remove = new ArrayList<RoleEntity>();
|
||||
for (RoleEntity rel : entities) {
|
||||
if (contains(rel.getName(), defaultRoles)) {
|
||||
remove.add(rel);
|
||||
}
|
||||
}
|
||||
for (RoleEntity entity : remove) {
|
||||
entities.remove(entity);
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getNodeReRegistrationTimeout() {
|
||||
return entity.getNodeReRegistrationTimeout();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.connections.jpa.util.JpaUtils;
|
||||
import org.keycloak.migration.MigrationModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
|
@ -25,6 +26,7 @@ import org.keycloak.models.GroupModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RealmProvider;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientTemplateEntity;
|
||||
|
@ -37,8 +39,10 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.TypedQuery;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -135,15 +139,15 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
for (String client : clients) {
|
||||
session.realms().removeClient(client, adapter);
|
||||
}
|
||||
/*
|
||||
for (ClientEntity a : new LinkedList<>(realm.getClients())) {
|
||||
adapter.removeClient(a.getId());
|
||||
}
|
||||
*/
|
||||
|
||||
for (ClientTemplateEntity a : new LinkedList<>(realm.getClientTemplates())) {
|
||||
adapter.removeClientTemplate(a.getId());
|
||||
}
|
||||
|
||||
for (RoleModel role : adapter.getRoles()) {
|
||||
session.realms().removeRole(adapter, role);
|
||||
}
|
||||
|
||||
em.remove(realm);
|
||||
|
||||
em.flush();
|
||||
|
@ -155,6 +159,112 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String name) {
|
||||
return addRealmRole(realm, KeycloakModelUtils.generateId(), name);
|
||||
|
||||
}
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String id, String name) {
|
||||
RoleEntity entity = new RoleEntity();
|
||||
entity.setId(id);
|
||||
entity.setName(name);
|
||||
RealmEntity ref = em.getReference(RealmEntity.class, realm.getId());
|
||||
entity.setRealm(ref);
|
||||
entity.setRealmId(realm.getId());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
return new RoleAdapter(session, realm, em, entity);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRealmRole(RealmModel realm, String name) {
|
||||
TypedQuery<String> query = em.createNamedQuery("getRealmRoleIdByName", String.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("realm", realm.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
if (roles.size() == 0) return null;
|
||||
return session.realms().getRoleById(roles.get(0), realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String name) {
|
||||
return addClientRole(realm, client, KeycloakModelUtils.generateId(), name);
|
||||
}
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String id, String name) {
|
||||
ClientEntity clientEntity = em.getReference(ClientEntity.class, client.getId());
|
||||
RoleEntity roleEntity = new RoleEntity();
|
||||
roleEntity.setId(id);
|
||||
roleEntity.setName(name);
|
||||
roleEntity.setClient(clientEntity);
|
||||
roleEntity.setClientRole(true);
|
||||
roleEntity.setRealmId(realm.getId());
|
||||
em.persist(roleEntity);
|
||||
em.flush();
|
||||
return new RoleAdapter(session, realm, em, roleEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRealmRoles(RealmModel realm) {
|
||||
TypedQuery<String> query = em.createNamedQuery("getRealmRoleIds", String.class);
|
||||
query.setParameter("realm", realm.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
|
||||
if (roles.isEmpty()) return Collections.EMPTY_SET;
|
||||
Set<RoleModel> list = new HashSet<RoleModel>();
|
||||
for (String id : roles) {
|
||||
list.add(session.realms().getRoleById(id, realm));
|
||||
}
|
||||
return Collections.unmodifiableSet(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getClientRole(RealmModel realm, ClientModel client, String name) {
|
||||
TypedQuery<String> query = em.createNamedQuery("getClientRoleIdByName", String.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("client", client.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
if (roles.size() == 0) return null;
|
||||
return session.realms().getRoleById(roles.get(0), realm);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getClientRoles(RealmModel realm, ClientModel client) {
|
||||
Set<RoleModel> list = new HashSet<RoleModel>();
|
||||
TypedQuery<String> query = em.createNamedQuery("getClientRoleIds", String.class);
|
||||
query.setParameter("client", client.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
for (String id : roles) {
|
||||
list.add(session.realms().getRoleById(id, realm));
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeRole(RealmModel realm, RoleModel role) {
|
||||
session.users().preRemove(realm, role);
|
||||
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
|
||||
RoleContainerModel container = role.getContainer();
|
||||
if (container.getDefaultRoles().contains(role.getName())) {
|
||||
container.removeDefaultRoles(role.getName());
|
||||
}
|
||||
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
|
||||
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteTemplateScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteGroupRoleMappingsByRole").setParameter("roleId", roleEntity.getId()).executeUpdate();
|
||||
|
||||
em.remove(roleEntity);
|
||||
em.flush();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRoleById(String id, RealmModel realm) {
|
||||
RoleEntity entity = em.find(RoleEntity.class, id);
|
||||
|
|
|
@ -682,6 +682,21 @@ public class RealmAdapter implements RealmModel {
|
|||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultRoles(String... defaultRoles) {
|
||||
Collection<RoleEntity> entities = realm.getDefaultRoles();
|
||||
List<RoleEntity> remove = new ArrayList<RoleEntity>();
|
||||
for (RoleEntity rel : entities) {
|
||||
if (contains(rel.getName(), defaultRoles)) {
|
||||
remove.add(rel);
|
||||
}
|
||||
}
|
||||
for (RoleEntity entity : remove) {
|
||||
entities.remove(entity);
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GroupModel> getDefaultGroups() {
|
||||
Collection<GroupEntity> entities = realm.getDefaultGroups();
|
||||
|
@ -980,66 +995,27 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public RoleModel getRole(String name) {
|
||||
TypedQuery<String> query = em.createNamedQuery("getRealmRoleIdByName", String.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("realm", realm.getId());
|
||||
List<String> roles = query.getResultList();
|
||||
if (roles.size() == 0) return null;
|
||||
return session.realms().getRoleById(roles.get(0), this);
|
||||
return session.realms().getRealmRole(this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String name) {
|
||||
return this.addRole(KeycloakModelUtils.generateId(), name);
|
||||
return session.realms().addRealmRole(this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String id, String name) {
|
||||
RoleEntity entity = new RoleEntity();
|
||||
entity.setId(id);
|
||||
entity.setName(name);
|
||||
entity.setRealm(realm);
|
||||
entity.setRealmId(realm.getId());
|
||||
realm.getRoles().add(entity);
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
return new RoleAdapter(session, this, em, entity);
|
||||
return session.realms().addRealmRole(this, id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeRole(RoleModel role) {
|
||||
if (role == null) {
|
||||
return false;
|
||||
}
|
||||
if (!role.getContainer().equals(this)) return false;
|
||||
session.users().preRemove(this, role);
|
||||
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
||||
realm.getRoles().remove(roleEntity);
|
||||
realm.getDefaultRoles().remove(roleEntity);
|
||||
|
||||
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
|
||||
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteTemplateScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteGroupRoleMappingsByRole").setParameter("roleId", roleEntity.getId()).executeUpdate();
|
||||
|
||||
em.remove(roleEntity);
|
||||
em.flush();
|
||||
|
||||
return true;
|
||||
return session.realms().removeRole(this, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles() {
|
||||
Collection<RoleEntity> roles = realm.getRoles();
|
||||
if (roles == null) return Collections.EMPTY_SET;
|
||||
Set<RoleModel> list = new HashSet<RoleModel>();
|
||||
for (RoleEntity entity : roles) {
|
||||
list.add(new RoleAdapter(session, this, em, entity));
|
||||
// can't get it from cache cuz of stack overflow
|
||||
// list.add(session.realms().getRoleById(entity.getId(), this));
|
||||
}
|
||||
return Collections.unmodifiableSet(list);
|
||||
return session.realms().getRealmRoles(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -157,9 +157,6 @@ public class ClientEntity {
|
|||
@Column(name="NODE_REREG_TIMEOUT")
|
||||
private int nodeReRegistrationTimeout;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, mappedBy = "client")
|
||||
Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
@JoinTable(name="CLIENT_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="CLIENT_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")})
|
||||
Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
|
||||
|
@ -354,14 +351,6 @@ public class ClientEntity {
|
|||
this.managementUrl = managementUrl;
|
||||
}
|
||||
|
||||
public Collection<RoleEntity> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Collection<RoleEntity> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Collection<RoleEntity> getDefaultRoles() {
|
||||
return defaultRoles;
|
||||
}
|
||||
|
|
|
@ -150,9 +150,6 @@ public class RealmEntity {
|
|||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||
Collection<ClientTemplateEntity> clientTemplates = new ArrayList<>();
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, mappedBy = "realm")
|
||||
Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="NAME")
|
||||
@Column(name="VALUE")
|
||||
|
@ -418,21 +415,6 @@ public class RealmEntity {
|
|||
public void setRequiredCredentials(Collection<RequiredCredentialEntity> requiredCredentials) {
|
||||
this.requiredCredentials = requiredCredentials;
|
||||
}
|
||||
public Collection<RoleEntity> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Collection<RoleEntity> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public void addRole(RoleEntity role) {
|
||||
if (roles == null) {
|
||||
roles = new ArrayList<RoleEntity>();
|
||||
}
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
public Map<String, String> getSmtpConfig() {
|
||||
return smtpConfig;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ import java.util.Collection;
|
|||
@NamedQuery(name="getClientRoleIds", query="select role.id from RoleEntity role where role.client.id = :client"),
|
||||
@NamedQuery(name="getClientRoleByName", query="select role from RoleEntity role where role.name = :name and role.client = :client"),
|
||||
@NamedQuery(name="getClientRoleIdByName", query="select role.id from RoleEntity role where role.name = :name and role.client.id = :client"),
|
||||
@NamedQuery(name="getRealmRoles", query="select role from RoleEntity role where role.clientRole = false and role.realm = :realm"),
|
||||
@NamedQuery(name="getRealmRoleIds", query="select role.id from RoleEntity role where role.clientRole = false and role.realm.id = :realm"),
|
||||
@NamedQuery(name="getRealmRoleByName", query="select role from RoleEntity role where role.clientRole = false and role.name = :name and role.realm = :realm"),
|
||||
@NamedQuery(name="getRealmRoleIdByName", query="select role.id from RoleEntity role where role.clientRole = false and role.name = :name and role.realm.id = :realm")
|
||||
})
|
||||
|
@ -108,6 +110,8 @@ public class RoleEntity {
|
|||
this.realmId = realmId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -567,34 +567,18 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
|
|||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter getRole(String name) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("name").is(name)
|
||||
.and("clientId").is(getId())
|
||||
.get();
|
||||
MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
|
||||
if (role == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new RoleAdapter(session, getRealm(), role, invocationContext);
|
||||
}
|
||||
public RoleModel getRole(String name) {
|
||||
return session.realms().getClientRole(realm, this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter addRole(String name) {
|
||||
return this.addRole(null, name);
|
||||
public RoleModel addRole(String name) {
|
||||
return session.realms().addClientRole(realm, this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter addRole(String id, String name) {
|
||||
MongoRoleEntity roleEntity = new MongoRoleEntity();
|
||||
roleEntity.setId(id);
|
||||
roleEntity.setName(name);
|
||||
roleEntity.setClientId(getId());
|
||||
|
||||
getMongoStore().insertEntity(roleEntity, invocationContext);
|
||||
|
||||
return new RoleAdapter(session, getRealm(), roleEntity, this, invocationContext);
|
||||
public RoleModel addRole(String id, String name) {
|
||||
return session.realms().addClientRole(realm, this, id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -605,17 +589,7 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
|
|||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles() {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("clientId").is(getId())
|
||||
.get();
|
||||
List<MongoRoleEntity> roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext);
|
||||
|
||||
Set<RoleModel> result = new HashSet<RoleModel>();
|
||||
for (MongoRoleEntity role : roles) {
|
||||
result.add(new RoleAdapter(session, getRealm(), role, this, invocationContext));
|
||||
}
|
||||
|
||||
return result;
|
||||
return session.realms().getClientRoles(realm, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -653,7 +627,7 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateDefaultRoles(String[] defaultRoles) {
|
||||
public void updateDefaultRoles(String... defaultRoles) {
|
||||
List<String> roleNames = new ArrayList<String>();
|
||||
for (String roleName : defaultRoles) {
|
||||
RoleModel role = getRole(roleName);
|
||||
|
@ -668,6 +642,17 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
|
|||
updateMongoEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultRoles(String... defaultRoles) {
|
||||
List<String> roleNames = new ArrayList<String>();
|
||||
for (String role : getMongoEntity().getDefaultRoles()) {
|
||||
if (!RealmAdapter.contains(role, defaultRoles)) roleNames.add(role);
|
||||
}
|
||||
getMongoEntity().setDefaultRoles(roleNames);
|
||||
updateMongoEntity();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getNodeReRegistrationTimeout() {
|
||||
return getMongoEntity().getNodeReRegistrationTimeout();
|
||||
|
|
|
@ -40,7 +40,9 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
@ -209,6 +211,107 @@ public class MongoRealmProvider implements RealmProvider {
|
|||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String name) {
|
||||
return addRealmRole(realm, KeycloakModelUtils.generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String id, String name) {
|
||||
MongoRoleEntity roleEntity = new MongoRoleEntity();
|
||||
roleEntity.setId(id);
|
||||
roleEntity.setName(name);
|
||||
roleEntity.setRealmId(realm.getId());
|
||||
|
||||
getMongoStore().insertEntity(roleEntity, invocationContext);
|
||||
|
||||
return new RoleAdapter(session, realm, roleEntity, realm, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRealmRoles(RealmModel realm) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("realmId").is(realm.getId())
|
||||
.get();
|
||||
List<MongoRoleEntity> roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext);
|
||||
|
||||
|
||||
if (roles == null) return Collections.EMPTY_SET;
|
||||
Set<RoleModel> result = new HashSet<RoleModel>();
|
||||
for (MongoRoleEntity role : roles) {
|
||||
result.add(session.realms().getRoleById(role.getId(), realm));
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(result);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getClientRoles(RealmModel realm, ClientModel client) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("clientId").is(client.getId())
|
||||
.get();
|
||||
List<MongoRoleEntity> roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext);
|
||||
|
||||
Set<RoleModel> result = new HashSet<RoleModel>();
|
||||
for (MongoRoleEntity role : roles) {
|
||||
result.add(session.realms().getRoleById(role.getId(), realm));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRealmRole(RealmModel realm, String name) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("name").is(name)
|
||||
.and("realmId").is(realm.getId())
|
||||
.get();
|
||||
MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
|
||||
if (role == null) {
|
||||
return null;
|
||||
} else {
|
||||
return session.realms().getRoleById(role.getId(), realm);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getClientRole(RealmModel realm, ClientModel client, String name) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("name").is(name)
|
||||
.and("clientId").is(client.getId())
|
||||
.get();
|
||||
MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
|
||||
if (role == null) {
|
||||
return null;
|
||||
} else {
|
||||
return session.realms().getRoleById(role.getId(), realm);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String name) {
|
||||
return addClientRole(realm, client, KeycloakModelUtils.generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String id, String name) {
|
||||
MongoRoleEntity roleEntity = new MongoRoleEntity();
|
||||
roleEntity.setId(id);
|
||||
roleEntity.setName(name);
|
||||
roleEntity.setClientId(client.getId());
|
||||
|
||||
getMongoStore().insertEntity(roleEntity, invocationContext);
|
||||
|
||||
return new RoleAdapter(session, realm, roleEntity, client, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeRole(RealmModel realm, RoleModel role) {
|
||||
session.users().preRemove(realm, role);
|
||||
return getMongoStore().removeEntity(MongoRoleEntity.class, role.getId(), invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeClient(String id, RealmModel realm) {
|
||||
if (id == null) return false;
|
||||
|
|
|
@ -595,47 +595,30 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter getRole(String name) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("name").is(name)
|
||||
.and("realmId").is(getId())
|
||||
.get();
|
||||
MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
|
||||
if (role == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new RoleAdapter(session, this, role, this, invocationContext);
|
||||
}
|
||||
public RoleModel getRole(String name) {
|
||||
return session.realms().getRealmRole(this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String name) {
|
||||
return this.addRole(null, name);
|
||||
return session.realms().addRealmRole(this, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String id, String name) {
|
||||
MongoRoleEntity roleEntity = new MongoRoleEntity();
|
||||
roleEntity.setId(id);
|
||||
roleEntity.setName(name);
|
||||
roleEntity.setRealmId(getId());
|
||||
|
||||
getMongoStore().insertEntity(roleEntity, invocationContext);
|
||||
|
||||
return new RoleAdapter(session, this, roleEntity, this, invocationContext);
|
||||
return session.realms().addRealmRole(this, id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeRole(RoleModel role) {
|
||||
return removeRoleById(role.getId());
|
||||
return session.realms().removeRole(this, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeRoleById(String id) {
|
||||
RoleModel role = getRoleById(id);
|
||||
if (role == null) return false;
|
||||
session.users().preRemove(this, role);
|
||||
return getMongoStore().removeEntity(MongoRoleEntity.class, id, invocationContext);
|
||||
return removeRole(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -657,7 +640,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
|
||||
@Override
|
||||
public RoleModel getRoleById(String id) {
|
||||
return model.getRoleById(id, this);
|
||||
return session.realms().getRoleById(id, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -780,6 +763,24 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
updateRealm();
|
||||
}
|
||||
|
||||
public static boolean contains(String str, String[] array) {
|
||||
for (String s : array) {
|
||||
if (str.equals(s)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeDefaultRoles(String... defaultRoles) {
|
||||
List<String> roleNames = new ArrayList<String>();
|
||||
for (String role : realm.getDefaultRoles()) {
|
||||
if (!contains(role, defaultRoles)) roleNames.add(role);
|
||||
}
|
||||
realm.setDefaultRoles(roleNames);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GroupModel> getDefaultGroups() {
|
||||
List<String> entities = realm.getDefaultGroups();
|
||||
|
|
|
@ -85,12 +85,6 @@ public interface ClientModel extends RoleContainerModel, ProtocolMapperContaine
|
|||
|
||||
void setBaseUrl(String url);
|
||||
|
||||
List<String> getDefaultRoles();
|
||||
|
||||
void addDefaultRole(String name);
|
||||
|
||||
void updateDefaultRoles(String[] defaultRoles);
|
||||
|
||||
|
||||
boolean isBearerOnly();
|
||||
void setBearerOnly(boolean only);
|
||||
|
|
|
@ -181,12 +181,6 @@ public interface RealmModel extends RoleContainerModel {
|
|||
|
||||
RoleModel getRoleById(String id);
|
||||
|
||||
List<String> getDefaultRoles();
|
||||
|
||||
void addDefaultRole(String name);
|
||||
|
||||
void updateDefaultRoles(String[] defaultRoles);
|
||||
|
||||
List<GroupModel> getDefaultGroups();
|
||||
|
||||
void addDefaultGroup(GroupModel group);
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.keycloak.migration.MigrationModel;
|
|||
import org.keycloak.provider.Provider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -45,6 +46,24 @@ public interface RealmProvider extends Provider {
|
|||
ClientModel getClientByClientId(String clientId, RealmModel realm);
|
||||
|
||||
|
||||
RoleModel addRealmRole(RealmModel realm, String name);
|
||||
|
||||
RoleModel addRealmRole(RealmModel realm, String id, String name);
|
||||
|
||||
RoleModel getRealmRole(RealmModel realm, String name);
|
||||
|
||||
RoleModel addClientRole(RealmModel realm, ClientModel client, String name);
|
||||
|
||||
RoleModel addClientRole(RealmModel realm, ClientModel client, String id, String name);
|
||||
|
||||
Set<RoleModel> getRealmRoles(RealmModel realm);
|
||||
|
||||
RoleModel getClientRole(RealmModel realm, ClientModel client, String name);
|
||||
|
||||
Set<RoleModel> getClientRoles(RealmModel realm, ClientModel client);
|
||||
|
||||
boolean removeRole(RealmModel realm, RoleModel role);
|
||||
|
||||
RoleModel getRoleById(String id, RealmModel realm);
|
||||
|
||||
boolean removeClient(String id, RealmModel realm);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.models;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -24,6 +25,8 @@ import java.util.Set;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RoleContainerModel {
|
||||
String getId();
|
||||
|
||||
RoleModel getRole(String name);
|
||||
|
||||
RoleModel addRole(String name);
|
||||
|
@ -34,4 +37,11 @@ public interface RoleContainerModel {
|
|||
|
||||
Set<RoleModel> getRoles();
|
||||
|
||||
List<String> getDefaultRoles();
|
||||
|
||||
void addDefaultRole(String name);
|
||||
|
||||
void updateDefaultRoles(String... defaultRoles);
|
||||
|
||||
void removeDefaultRoles(String... defaultRoles);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue