diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/HardcodedLDAPRoleStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/HardcodedLDAPRoleStorageMapper.java
index 56fb541195..a5d2cbb0d3 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/HardcodedLDAPRoleStorageMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/HardcodedLDAPRoleStorageMapper.java
@@ -30,7 +30,7 @@ import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
-import java.util.Set;
+import java.util.stream.Stream;
/**
* @author Marek Posolda
@@ -54,27 +54,27 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
return new UserModelDelegate(delegate) {
@Override
- public Set getRealmRoleMappings() {
- Set roles = super.getRealmRoleMappings();
+ public Stream getRealmRoleMappingsStream() {
+ Stream realmRoleMappings = super.getRealmRoleMappingsStream();
RoleModel role = getRole(realm);
if (role != null && role.getContainer().equals(realm)) {
- roles.add(role);
+ realmRoleMappings = Stream.concat(realmRoleMappings, Stream.of(role));
}
- return roles;
+ return realmRoleMappings;
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- Set roles = super.getClientRoleMappings(app);
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ Stream clientRoleMappings = super.getClientRoleMappingsStream(app);
RoleModel role = getRole(realm);
if (role != null && role.getContainer().equals(app)) {
- roles.add(role);
+ return Stream.concat(clientRoleMappings, Stream.of(role));
}
- return roles;
+ return clientRoleMappings;
}
@Override
@@ -83,15 +83,15 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
}
@Override
- public Set getRoleMappings() {
- Set roles = super.getRoleMappings();
+ public Stream getRoleMappingsStream() {
+ Stream roleMappings = super.getRoleMappingsStream();
RoleModel role = getRole(realm);
if (role != null) {
- roles.add(role);
+ roleMappings = Stream.concat(roleMappings, Stream.of(role));
}
- return roles;
+ return roleMappings;
}
@Override
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java
index 46f4d8c57b..05b15ad45b 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java
@@ -46,9 +46,11 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Stream;
+import java.util.stream.Collectors;
/**
* Map realm roles or roles of particular client to LDAP groups
@@ -330,47 +332,42 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
}
@Override
- public Set getRealmRoleMappings() {
+ public Stream getRealmRoleMappingsStream() {
if (roleContainer.equals(realm)) {
- Set ldapRoleMappings = getLDAPRoleMappingsConverted();
+ Stream ldapRoleMappings = getLDAPRoleMappingsConverted();
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
// Use just role mappings from LDAP
return ldapRoleMappings;
} else {
// Merge mappings from both DB and LDAP
- Set modelRoleMappings = super.getRealmRoleMappings();
- ldapRoleMappings.addAll(modelRoleMappings);
- return ldapRoleMappings;
+ return Stream.concat(ldapRoleMappings, super.getRealmRoleMappingsStream());
}
} else {
- return super.getRealmRoleMappings();
+ return super.getRealmRoleMappingsStream();
}
}
@Override
- public Set getClientRoleMappings(ClientModel client) {
+ public Stream getClientRoleMappingsStream(ClientModel client) {
if (roleContainer.equals(client)) {
- Set ldapRoleMappings = getLDAPRoleMappingsConverted();
+ Stream ldapRoleMappings = getLDAPRoleMappingsConverted();
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
// Use just role mappings from LDAP
return ldapRoleMappings;
} else {
// Merge mappings from both DB and LDAP
- Set modelRoleMappings = super.getClientRoleMappings(client);
- ldapRoleMappings.addAll(modelRoleMappings);
- return ldapRoleMappings;
+ return Stream.concat(ldapRoleMappings, super.getClientRoleMappingsStream(client));
}
} else {
- return super.getClientRoleMappings(client);
+ return super.getClientRoleMappingsStream(client);
}
}
@Override
public boolean hasRole(RoleModel role) {
- Set roles = getRoleMappings();
- return RoleUtils.hasRole(roles, role)
+ return RoleUtils.hasRole(getRoleMappingsStream(), role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
}
@@ -392,47 +389,38 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
}
@Override
- public Set getRoleMappings() {
- Set modelRoleMappings = super.getRoleMappings();
+ public Stream getRoleMappingsStream() {
+ Stream modelRoleMappings = super.getRoleMappingsStream();
- Set ldapRoleMappings = getLDAPRoleMappingsConverted();
+ Stream ldapRoleMappings = getLDAPRoleMappingsConverted();
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
// For LDAP-only we want to retrieve role mappings of target container just from LDAP
- Set modelRolesCopy = new HashSet<>(modelRoleMappings);
- for (RoleModel role : modelRolesCopy) {
- if (role.getContainer().equals(roleContainer)) {
- modelRoleMappings.remove(role);
- }
- }
+ modelRoleMappings = modelRoleMappings.filter(role -> !Objects.equals(role.getContainer(), roleContainer));
}
- modelRoleMappings.addAll(ldapRoleMappings);
- return modelRoleMappings;
+ return Stream.concat(modelRoleMappings, ldapRoleMappings);
}
- protected Set getLDAPRoleMappingsConverted() {
+ protected Stream getLDAPRoleMappingsConverted() {
if (cachedLDAPRoleMappings != null) {
- return new HashSet<>(cachedLDAPRoleMappings);
+ return cachedLDAPRoleMappings.stream();
}
List ldapRoles = getLDAPRoleMappings(ldapUser);
-
- Set roles = new HashSet<>();
String roleNameLdapAttr = config.getRoleNameLdapAttribute();
- for (LDAPObject role : ldapRoles) {
- String roleName = role.getAttributeAsString(roleNameLdapAttr);
- RoleModel modelRole = roleContainer.getRole(roleName);
- if (modelRole == null) {
- // Add role to local DB
- modelRole = roleContainer.addRole(roleName);
- }
- roles.add(modelRole);
- }
+ cachedLDAPRoleMappings = ldapRoles.stream()
+ .map(role -> {
+ String roleName = role.getAttributeAsString(roleNameLdapAttr);
+ RoleModel modelRole = roleContainer.getRole(roleName);
+ if (modelRole == null) {
+ // Add role to local DB
+ modelRole = roleContainer.addRole(roleName);
+ }
+ return modelRole;
+ }).collect(Collectors.toSet());
- cachedLDAPRoleMappings = new HashSet<>(roles);
-
- return roles;
+ return cachedLDAPRoleMappings.stream();
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java
index 989dd1e12d..c7b210c7d4 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java
@@ -21,14 +21,13 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.CachedObject;
import org.keycloak.models.cache.infinispan.entities.CachedClient;
+import org.keycloak.models.utils.RoleUtils;
import java.security.MessageDigest;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -271,20 +270,8 @@ public class ClientAdapter implements ClientModel, CachedObject {
updated.deleteScopeMapping(role);
}
- public Set getRealmScopeMappings() {
- Set roleMappings = getScopeMappings();
-
- Set appRoles = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- if (((RealmModel) container).getId().equals(cachedRealm.getId())) {
- appRoles.add(role);
- }
- }
- }
-
- return appRoles;
+ public Stream getRealmScopeMappingsStream() {
+ return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, cachedRealm));
}
public RealmModel getRealm() {
@@ -496,9 +483,9 @@ public class ClientAdapter implements ClientModel, CachedObject {
}
@Override
- public List getDefaultRoles() {
- if (isUpdated()) return updated.getDefaultRoles();
- return cached.getDefaultRoles();
+ public Stream getDefaultRolesStream() {
+ if (isUpdated()) return updated.getDefaultRolesStream();
+ return cached.getDefaultRoles().stream();
}
@Override
@@ -662,7 +649,8 @@ public class ClientAdapter implements ClientModel, CachedObject {
if (isUpdated()) return updated.hasScope(role);
if (cached.isFullScopeAllowed() || cached.getScope().contains(role.getId())) return true;
- if (getScopeMappingsStream().anyMatch(r -> r.hasRole(role))) return true;
+ if (RoleUtils.hasRole(getScopeMappingsStream(), role))
+ return true;
return getRolesStream().anyMatch(r -> (Objects.equals(r, role) || r.hasRole(role)));
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientScopeAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientScopeAdapter.java
index b45e1a946b..c3a1d0fc4f 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientScopeAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientScopeAdapter.java
@@ -20,12 +20,11 @@ package org.keycloak.models.cache.infinispan;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.infinispan.entities.CachedClientScope;
+import org.keycloak.models.utils.RoleUtils;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
@@ -173,20 +172,8 @@ public class ClientScopeAdapter implements ClientScopeModel {
updated.deleteScopeMapping(role);
}
- public Set getRealmScopeMappings() {
- Set roleMappings = getScopeMappings();
-
- Set appRoles = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- if (((RealmModel) container).getId().equals(cachedRealm.getId())) {
- appRoles.add(role);
- }
- }
- }
-
- return appRoles;
+ public Stream getRealmScopeMappingsStream() {
+ return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, cachedRealm));
}
@Override
@@ -194,12 +181,7 @@ public class ClientScopeAdapter implements ClientScopeModel {
if (isUpdated()) return updated.hasScope(role);
if (cached.getScope().contains(role.getId())) return true;
- Set roles = getScopeMappings();
-
- for (RoleModel mapping : roles) {
- if (mapping.hasRole(role)) return true;
- }
- return false;
+ return RoleUtils.hasRole(getScopeMappingsStream(), role);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java
index ba33407166..df900dc157 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java
@@ -21,9 +21,9 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.infinispan.entities.CachedGroup;
+import org.keycloak.models.utils.RoleUtils;
import java.util.HashSet;
import java.util.List;
@@ -149,35 +149,15 @@ public class GroupAdapter implements GroupModel {
}
@Override
- public Set getRealmRoleMappings() {
- if (isUpdated()) return updated.getRealmRoleMappings();
- Set roleMappings = getRoleMappings();
- Set realmMappings = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- if (((RealmModel) container).getId().equals(realm.getId())) {
- realmMappings.add(role);
- }
- }
- }
- return realmMappings;
+ public Stream getRealmRoleMappingsStream() {
+ if (isUpdated()) return updated.getRealmRoleMappingsStream();
+ return getRoleMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- if (isUpdated()) return updated.getClientRoleMappings(app);
- Set roleMappings = getRoleMappings();
- Set appMappings = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof ClientModel) {
- if (((ClientModel) container).getId().equals(app.getId())) {
- appMappings.add(role);
- }
- }
- }
- return appMappings;
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ if (isUpdated()) return updated.getClientRoleMappingsStream(app);
+ return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
}
@Override
@@ -185,11 +165,7 @@ public class GroupAdapter implements GroupModel {
if (isUpdated()) return updated.hasRole(role);
if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true;
- Set mappings = getRoleMappings();
- for (RoleModel mapping: mappings) {
- if (mapping.hasRole(role)) return true;
- }
- return false;
+ return getRoleMappingsStream().anyMatch(r -> r.hasRole(role));
}
@Override
@@ -199,20 +175,20 @@ public class GroupAdapter implements GroupModel {
}
@Override
- public Set getRoleMappings() {
- if (isUpdated()) return updated.getRoleMappings();
+ public Stream getRoleMappingsStream() {
+ if (isUpdated()) return updated.getRoleMappingsStream();
Set roles = new HashSet<>();
for (String id : cached.getRoleMappings(modelSupplier)) {
RoleModel roleById = keycloakSession.roles().getRoleById(realm, id);
if (roleById == null) {
// chance that role was removed, so just delegate to persistence and get user invalidated
getDelegateForUpdate();
- return updated.getRoleMappings();
+ return updated.getRoleMappingsStream();
}
roles.add(roleById);
}
- return roles;
+ return roles.stream();
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java
index 151b645945..3af7ad6238 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java
@@ -725,9 +725,9 @@ public class RealmAdapter implements CachedRealmModel {
}
@Override
- public List getDefaultRoles() {
- if (isUpdated()) return updated.getDefaultRoles();
- return cached.getDefaultRoles();
+ public Stream getDefaultRolesStream() {
+ if (isUpdated()) return updated.getDefaultRolesStream();
+ return cached.getDefaultRoles().stream();
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java
index a775f09e94..dfec89e635 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java
@@ -26,12 +26,13 @@ import org.keycloak.models.cache.infinispan.entities.CachedRole;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author Bill Burke
@@ -125,21 +126,22 @@ public class RoleAdapter implements RoleModel {
}
@Override
- public Set getComposites() {
- if (isUpdated()) return updated.getComposites();
+ public Stream getCompositesStream() {
+ if (isUpdated()) return updated.getCompositesStream();
if (composites == null) {
composites = new HashSet<>();
- for (String id : cached.getComposites()) {
- RoleModel role = realm.getRoleById(id);
- if (role == null) {
- throw new IllegalStateException("Could not find composite in role " + getName() + ": " + id);
- }
- composites.add(role);
- }
+ composites = cached.getComposites().stream()
+ .map(id -> {
+ RoleModel role = realm.getRoleById(id);
+ if (role == null) {
+ throw new IllegalStateException("Could not find composite in role " + getName() + ": " + id);
+ }
+ return role;
+ }).collect(Collectors.toSet());
}
- return composites;
+ return composites.stream();
}
@Override
@@ -201,16 +203,16 @@ public class RoleAdapter implements RoleModel {
}
@Override
- public List getAttribute(String name) {
+ public Stream getAttributeStream(String name) {
if (updated != null) {
- return updated.getAttribute(name);
+ return updated.getAttributeStream(name);
}
List result = cached.getAttributes(modelSupplier).get(name);
if (result == null) {
- result = Collections.emptyList();
+ return Stream.empty();
}
- return result;
+ return result.stream();
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java
index 93459c65fb..0c499f79a2 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java
@@ -21,7 +21,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.cache.CachedUserModel;
@@ -276,35 +275,15 @@ public class UserAdapter implements CachedUserModel {
}
@Override
- public Set getRealmRoleMappings() {
- if (updated != null) return updated.getRealmRoleMappings();
- Set roleMappings = getRoleMappings();
- Set realmMappings = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- if (((RealmModel) container).getId().equals(realm.getId())) {
- realmMappings.add(role);
- }
- }
- }
- return realmMappings;
+ public Stream getRealmRoleMappingsStream() {
+ if (updated != null) return updated.getRealmRoleMappingsStream();
+ return getRoleMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- if (updated != null) return updated.getClientRoleMappings(app);
- Set roleMappings = getRoleMappings();
- Set appMappings = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof ClientModel) {
- if (((ClientModel) container).getId().equals(app.getId())) {
- appMappings.add(role);
- }
- }
- }
- return appMappings;
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ if (updated != null) return updated.getClientRoleMappingsStream(app);
+ return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
}
@Override
@@ -312,11 +291,8 @@ public class UserAdapter implements CachedUserModel {
if (updated != null) return updated.hasRole(role);
if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true;
- Set mappings = getRoleMappings();
- for (RoleModel mapping: mappings) {
- if (mapping.hasRole(role)) return true;
- }
- return RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
+ return getRoleMappingsStream().anyMatch(r -> r.hasRole(role)) ?
+ true : RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
}
@Override
@@ -326,20 +302,20 @@ public class UserAdapter implements CachedUserModel {
}
@Override
- public Set getRoleMappings() {
- if (updated != null) return updated.getRoleMappings();
+ public Stream getRoleMappingsStream() {
+ if (updated != null) return updated.getRoleMappingsStream();
Set roles = new HashSet<>();
for (String id : cached.getRoleMappings(modelSupplier)) {
RoleModel roleById = keycloakSession.roles().getRoleById(realm, id);
if (roleById == null) {
// chance that role was removed, so just delete to persistence and get user invalidated
getDelegateForUpdate();
- return updated.getRoleMappings();
+ return updated.getRoleMappingsStream();
}
roles.add(roleById);
}
- return roles;
+ return roles.stream();
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClient.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClient.java
index ddd40a41f0..e40c3ab3ed 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClient.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClient.java
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.stream.Collectors;
/**
* @author Bill Burke
@@ -92,9 +93,7 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
fullScopeAllowed = model.isFullScopeAllowed();
redirectUris.addAll(model.getRedirectUris());
webOrigins.addAll(model.getWebOrigins());
- for (RoleModel role : model.getScopeMappings()) {
- scope.add(role.getId());
- }
+ scope.addAll(model.getScopeMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()));
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper);
}
@@ -102,7 +101,7 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
managementUrl = model.getManagementUrl();
rootUrl = model.getRootUrl();
baseUrl = model.getBaseUrl();
- defaultRoles.addAll(model.getDefaultRoles());
+ defaultRoles.addAll(model.getDefaultRolesStream().collect(Collectors.toList()));
bearerOnly = model.isBearerOnly();
consentRequired = model.isConsentRequired();
standardFlowEnabled = model.isStandardFlowEnabled();
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClientScope.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClientScope.java
index 83b4f35cd0..9563539cc7 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClientScope.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedClientScope.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* @author Bill Burke
@@ -50,9 +51,7 @@ public class CachedClientScope extends AbstractRevisioned implements InRealm {
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper);
}
- for (RoleModel role : model.getScopeMappings()) {
- scope.add(role.getId());
- }
+ scope.addAll(model.getScopeMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()));
attributes.putAll(model.getAttributes());
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedGroup.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedGroup.java
index eaca4b514e..70f362cbf4 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedGroup.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedGroup.java
@@ -48,7 +48,7 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
this.name = group.getName();
this.parentId = group.getParentId();
this.attributes = new DefaultLazyLoader<>(source -> new MultivaluedHashMap<>(source.getAttributes()), MultivaluedHashMap::new);
- this.roleMappings = new DefaultLazyLoader<>(source -> source.getRoleMappings().stream().map(RoleModel::getId).collect(Collectors.toSet()), Collections::emptySet);
+ this.roleMappings = new DefaultLazyLoader<>(source -> source.getRoleMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()), Collections::emptySet);
this.subGroups = new DefaultLazyLoader<>(source -> source.getSubGroupsStream().map(GroupModel::getId).collect(Collectors.toSet()), Collections::emptySet);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java
index d00e1d9af3..ff2460d0ab 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java
@@ -252,7 +252,7 @@ public class CachedRealm extends AbstractExtendableRevisioned {
adminEventsEnabled = model.isAdminEventsEnabled();
adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled();
- defaultRoles = model.getDefaultRoles();
+ defaultRoles = model.getDefaultRolesStream().collect(Collectors.toList());
ClientModel masterAdminClient = model.getMasterAdminClient();
this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRole.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRole.java
index 151a9888a9..1368417505 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRole.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRole.java
@@ -26,6 +26,7 @@ import org.keycloak.models.cache.infinispan.LazyLoader;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
/**
* @author Bill Burke
@@ -47,9 +48,7 @@ public class CachedRole extends AbstractRevisioned implements InRealm {
name = model.getName();
this.realm = realm.getId();
if (composite) {
- for (RoleModel child : model.getComposites()) {
- composites.add(child.getId());
- }
+ composites.addAll(model.getCompositesStream().map(RoleModel::getId).collect(Collectors.toSet()));
}
attributes = new DefaultLazyLoader<>(roleModel -> new MultivaluedHashMap<>(roleModel.getAttributes()), MultivaluedHashMap::new);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java
index b0a5d5d9f3..68433cd5dc 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java
@@ -64,7 +64,7 @@ public class CachedUser extends AbstractExtendableRevisioned implements InRealm
this.notBefore = notBefore;
this.requiredActions = new DefaultLazyLoader<>(UserModel::getRequiredActions, Collections::emptySet);
this.attributes = new DefaultLazyLoader<>(userModel -> new MultivaluedHashMap<>(userModel.getAttributes()), MultivaluedHashMap::new);
- this.roleMappings = new DefaultLazyLoader<>(userModel -> userModel.getRoleMappings().stream().map(RoleModel::getId).collect(Collectors.toSet()), Collections::emptySet);
+ this.roleMappings = new DefaultLazyLoader<>(userModel -> userModel.getRoleMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()), Collections::emptySet);
this.groups = new DefaultLazyLoader<>(userModel -> userModel.getGroupsStream().map(GroupModel::getId).collect(Collectors.toCollection(LinkedHashSet::new)), LinkedHashSet::new);
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index 206b4ecacd..aece277059 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -23,7 +23,6 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientAttributeEntity;
import org.keycloak.models.jpa.entities.ClientEntity;
@@ -31,6 +30,7 @@ import org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.RoleUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import javax.persistence.EntityManager;
@@ -46,7 +46,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.Predicate;
import java.util.stream.Stream;
/**
@@ -239,20 +238,8 @@ public class ClientAdapter implements ClientModel, JpaModel {
}
@Override
- public Set getRealmScopeMappings() {
- Set roleMappings = getScopeMappings();
-
- Set appRoles = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- if (((RealmModel) container).getId().equals(realm.getId())) {
- appRoles.add(role);
- }
- }
- }
-
- return appRoles;
+ public Stream getRealmScopeMappingsStream() {
+ return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
}
@Override
@@ -690,24 +677,17 @@ public class ClientAdapter implements ClientModel, JpaModel {
public boolean hasScope(RoleModel role) {
if (isFullScopeAllowed()) return true;
- Predicate hasRoleOrEquals = r -> (Objects.equals(r, role) || r.hasRole(role));
-
- if (getScopeMappingsStream().anyMatch(hasRoleOrEquals)) {
+ if (RoleUtils.hasRole(getScopeMappingsStream(), role))
return true;
- }
- return getRolesStream().anyMatch(hasRoleOrEquals);
+ return RoleUtils.hasRole(getRolesStream(), role);
}
@Override
- public List getDefaultRoles() {
+ public Stream getDefaultRolesStream() {
Collection entities = entity.getDefaultRoles();
- List roles = new ArrayList();
- if (entities == null) return roles;
- for (RoleEntity entity : entities) {
- roles.add(entity.getName());
- }
- return roles;
+ if (entities == null) return Stream.empty();
+ return entities.stream().map(RoleEntity::getName);
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java
index 8677935a5f..a44dfe9af1 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java
@@ -22,13 +22,13 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientScopeAttributeEntity;
import org.keycloak.models.jpa.entities.ClientScopeEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.RoleUtils;
import javax.persistence.EntityManager;
import java.util.HashMap;
@@ -210,20 +210,8 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel getRealmScopeMappings() {
- Set roleMappings = getScopeMappings();
-
- Set appRoles = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- if (container.getId().equals(realm.getId())) {
- appRoles.add(role);
- }
- }
- }
-
- return appRoles;
+ public Stream getRealmScopeMappingsStream() {
+ return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
}
@Override
@@ -247,13 +235,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel roles = getScopeMappings();
- if (roles.contains(role)) return true;
-
- for (RoleModel mapping : roles) {
- if (mapping.hasRole(role)) return true;
- }
- return false;
+ return RoleUtils.hasRole(getScopeMappingsStream(), role);
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
index f537d84b07..e69f66a88f 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
@@ -21,7 +21,6 @@ import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.GroupAttributeEntity;
import org.keycloak.models.jpa.entities.GroupEntity;
@@ -217,8 +216,7 @@ public class GroupAdapter implements GroupModel , JpaModel {
@Override
public boolean hasRole(RoleModel role) {
- Set roles = getRoleMappings();
- return RoleUtils.hasRole(roles, role);
+ return RoleUtils.hasRole(getRoleMappingsStream(), role);
}
protected TypedQuery getGroupRoleMappingEntityTypedQuery(RoleModel role) {
@@ -240,34 +238,18 @@ public class GroupAdapter implements GroupModel , JpaModel {
}
@Override
- public Set getRealmRoleMappings() {
- Set roleMappings = getRoleMappings();
-
- Set realmRoles = new HashSet();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- realmRoles.add(role);
- }
- }
- return realmRoles;
+ public Stream getRealmRoleMappingsStream() {
+ return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
}
@Override
- public Set getRoleMappings() {
+ public Stream getRoleMappingsStream() {
// we query ids only as the role might be cached and following the @ManyToOne will result in a load
// even if we're getting just the id.
TypedQuery query = em.createNamedQuery("groupRoleMappingIds", String.class);
query.setParameter("group", getEntity());
- List ids = query.getResultList();
- Set roles = new HashSet();
- for (String roleId : ids) {
- RoleModel roleById = realm.getRoleById(roleId);
- if (roleById == null) continue;
- roles.add(roleById);
- }
- return roles;
+ return closing(query.getResultStream().map(realm::getRoleById).filter(Objects::nonNull));
}
@Override
@@ -285,20 +267,8 @@ public class GroupAdapter implements GroupModel , JpaModel {
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- Set roleMappings = getRoleMappings();
-
- Set roles = new HashSet();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof ClientModel) {
- ClientModel appModel = (ClientModel)container;
- if (appModel.getId().equals(app.getId())) {
- roles.add(role);
- }
- }
- }
- return roles;
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
index 116ca2b99e..29a8af000b 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
@@ -340,7 +340,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
}
session.users().preRemove(realm, role);
RoleContainerModel container = role.getContainer();
- if (container.getDefaultRoles().contains(role.getName())) {
+ if (container.getDefaultRolesStream().anyMatch(r -> Objects.equals(r, role.getName()))) {
container.removeDefaultRoles(role.getName());
}
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 144e3be69f..1ef1252dbb 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -718,14 +718,10 @@ public class RealmAdapter implements RealmModel, JpaModel {
@Override
- public List getDefaultRoles() {
+ public Stream getDefaultRolesStream() {
Collection entities = realm.getDefaultRoles();
- if (entities == null || entities.isEmpty()) return Collections.emptyList();
- List roles = new LinkedList<>();
- for (RoleEntity entity : entities) {
- roles.add(entity.getName());
- }
- return Collections.unmodifiableList(roles);
+ if (entities == null || entities.isEmpty()) return Stream.empty();
+ return entities.stream().map(RoleEntity::getName);
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
index 18ce834d0d..36cea63db1 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
@@ -34,7 +34,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
+import java.util.Objects;
+import java.util.stream.Stream;
/**
* @author Bill Burke
@@ -88,7 +89,7 @@ public class RoleAdapter implements RoleModel, JpaModel {
@Override
public boolean isComposite() {
- return getComposites().size() > 0;
+ return getCompositesStream().count() > 0;
}
@Override
@@ -107,16 +108,8 @@ public class RoleAdapter implements RoleModel, JpaModel {
}
@Override
- public Set getComposites() {
- Set set = new HashSet();
-
- for (RoleEntity composite : getEntity().getCompositeRoles()) {
- set.add(new RoleAdapter(session, realm, em, composite));
-
- // todo I want to do this, but can't as you get stack overflow
- // set.add(session.realms().getRoleById(composite.getId(), realm));
- }
- return set;
+ public Stream getCompositesStream() {
+ return getEntity().getCompositeRoles().stream().map(c -> new RoleAdapter(session, realm, em, c));
}
@Override
@@ -175,14 +168,10 @@ public class RoleAdapter implements RoleModel, JpaModel {
}
@Override
- public List getAttribute(String name) {
- List attributes = new ArrayList<>();
- for (RoleAttributeEntity attribute : role.getAttributes()) {
- if (attribute.getName().equals(name)) {
- attributes.add(attribute.getValue());
- }
- }
- return attributes;
+ public Stream getAttributeStream(String name) {
+ return role.getAttributes().stream()
+ .filter(a -> Objects.equals(a.getName(), name))
+ .map(RoleAttributeEntity::getValue);
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 8a366ded31..3b8b62a62b 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -22,7 +22,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.GroupEntity;
@@ -472,8 +471,7 @@ public class UserAdapter implements UserModel, JpaModel {
@Override
public boolean hasRole(RoleModel role) {
- Set roles = getRoleMappings();
- return RoleUtils.hasRole(roles, role)
+ return RoleUtils.hasRole(getRoleMappingsStream(), role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
}
@@ -500,34 +498,18 @@ public class UserAdapter implements UserModel, JpaModel {
}
@Override
- public Set getRealmRoleMappings() {
- Set roleMappings = getRoleMappings();
-
- Set realmRoles = new HashSet();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- realmRoles.add(role);
- }
- }
- return realmRoles;
+ public Stream getRealmRoleMappingsStream() {
+ return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
}
@Override
- public Set getRoleMappings() {
+ public Stream getRoleMappingsStream() {
// we query ids only as the role might be cached and following the @ManyToOne will result in a load
// even if we're getting just the id.
TypedQuery query = em.createNamedQuery("userRoleMappingIds", String.class);
query.setParameter("user", getEntity());
- List ids = query.getResultList();
- Set roles = new HashSet();
- for (String roleId : ids) {
- RoleModel roleById = realm.getRoleById(roleId);
- if (roleById == null) continue;
- roles.add(roleById);
- }
- return roles;
+ return closing(query.getResultStream().map(realm::getRoleById).filter(Objects::nonNull));
}
@Override
@@ -545,20 +527,8 @@ public class UserAdapter implements UserModel, JpaModel {
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- Set roleMappings = getRoleMappings();
-
- Set roles = new HashSet();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof ClientModel) {
- ClientModel appModel = (ClientModel) container;
- if (appModel.getId().equals(app.getId())) {
- roles.add(role);
- }
- }
- }
- return roles;
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
index 11e6b303e7..ed397449b8 100644
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
@@ -544,17 +544,10 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public Set getRoleMappings(RealmModel realm, String userId) {
- Set set = new HashSet<>();
+ public Stream getRoleMappingsStream(RealmModel realm, String userId) {
TypedQuery query = em.createNamedQuery("feduserRoleMappings", FederatedUserRoleMappingEntity.class);
query.setParameter("userId", userId);
- List results = query.getResultList();
- if (results.size() == 0) return set;
- for (FederatedUserRoleMappingEntity entity : results) {
- RoleModel role = realm.getRoleById(entity.getRoleId());
- set.add(role);
- }
- return set;
+ return closing(query.getResultStream().map(FederatedUserRoleMappingEntity::getRoleId).map(realm::getRoleById));
}
@Override
diff --git a/model/map/src/main/java/org/keycloak/models/map/client/AbstractClientModel.java b/model/map/src/main/java/org/keycloak/models/map/client/AbstractClientModel.java
index 44b451d553..a5ba3123d7 100644
--- a/model/map/src/main/java/org/keycloak/models/map/client/AbstractClientModel.java
+++ b/model/map/src/main/java/org/keycloak/models/map/client/AbstractClientModel.java
@@ -22,9 +22,10 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.map.common.AbstractEntity;
+import org.keycloak.models.utils.RoleUtils;
+
import java.util.Objects;
import java.util.Set;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -54,11 +55,8 @@ public abstract class AbstractClientModel implements C
}
@Override
- public Set getRealmScopeMappings() {
- String realmId = realm.getId();
- return getScopeMappingsStream()
- .filter(rm -> Objects.equals(rm.getContainerId(), realmId))
- .collect(Collectors.toSet());
+ public Stream getRealmScopeMappingsStream() {
+ return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
}
@Override
diff --git a/model/map/src/main/java/org/keycloak/models/map/client/MapClientAdapter.java b/model/map/src/main/java/org/keycloak/models/map/client/MapClientAdapter.java
index 262ec3e69e..b97e1c62a6 100644
--- a/model/map/src/main/java/org/keycloak/models/map/client/MapClientAdapter.java
+++ b/model/map/src/main/java/org/keycloak/models/map/client/MapClientAdapter.java
@@ -457,8 +457,8 @@ public abstract class MapClientAdapter extends AbstractClientModel getDefaultRoles() {
- return entity.getDefaultRoles();
+ public Stream getDefaultRolesStream() {
+ return entity.getDefaultRoles().stream();
}
@Override
diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DefaultEvaluation.java b/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DefaultEvaluation.java
index 2b144436ae..e192c099ea 100644
--- a/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DefaultEvaluation.java
+++ b/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DefaultEvaluation.java
@@ -18,13 +18,10 @@
package org.keycloak.authorization.policy.evaluation;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.Decision;
@@ -52,7 +49,7 @@ public class DefaultEvaluation implements Evaluation {
private Policy policy;
private final Policy parentPolicy;
private final AuthorizationProvider authorizationProvider;
- private Map> decisionCache;
+ private final Map> decisionCache;
private final Realm realm;
private Effect effect;
@@ -192,9 +189,7 @@ public class DefaultEvaluation implements Evaluation {
return false;
}
- Set roleMappings = user.getRoleMappings().stream()
- .filter(role -> !role.isClientRole())
- .collect(Collectors.toSet());
+ Stream roleMappings = user.getRoleMappingsStream().filter(isNotClientRole);
return RoleUtils.hasRole(roleMappings, session.getContext().getRealm().getRole(roleName));
}
@@ -209,15 +204,16 @@ public class DefaultEvaluation implements Evaluation {
return false;
}
- Set roleMappings = user.getRoleMappings().stream()
- .filter(role -> role.isClientRole() && ClientModel.class.cast(role.getContainer()).getClientId().equals(clientId))
+ Set roleMappings = user.getRoleMappingsStream()
+ .filter(RoleModel::isClientRole)
+ .filter(role -> Objects.equals(((ClientModel) role.getContainer()).getClientId(), clientId))
.collect(Collectors.toSet());
if (roleMappings.isEmpty()) {
return false;
}
- RoleModel role = realm.getClientById(ClientModel.class.cast(roleMappings.iterator().next().getContainer()).getId()).getRole(roleName);
+ RoleModel role = realm.getClientById(roleMappings.iterator().next().getContainer().getId()).getRole(roleName);
if (Objects.isNull(role)) {
return false;
@@ -237,16 +233,16 @@ public class DefaultEvaluation implements Evaluation {
@Override
public List getUserRealmRoles(String id) {
- return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappings().stream()
- .filter(role -> !role.isClientRole())
+ return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappingsStream()
+ .filter(isNotClientRole)
.map(RoleModel::getName)
.collect(Collectors.toList());
}
@Override
public List getUserClientRoles(String id, String clientId) {
- return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappings().stream()
- .filter(role -> role.isClientRole())
+ return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappingsStream()
+ .filter(RoleModel::isClientRole)
.map(RoleModel::getName)
.collect(Collectors.toList());
}
@@ -274,4 +270,6 @@ public class DefaultEvaluation implements Evaluation {
this.effect = effect;
this.decision.onDecision(this);
}
+
+ private Predicate isNotClientRole = ((Predicate) RoleModel::isClientRole).negate();
}
diff --git a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_4_2.java b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_4_2.java
index c395cbe774..cbf89653e1 100644
--- a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_4_2.java
+++ b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_4_2.java
@@ -23,16 +23,8 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RealmRepresentation;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
/**
* @author Bruno Oliveira
*/
@@ -65,10 +57,7 @@ public class MigrateTo3_4_2 implements Migration {
private void clearScope(ClientModel cli) {
if (cli.isFullScopeAllowed()) cli.setFullScopeAllowed(false);
- Set scope = cli.getScopeMappings();
- if (scope.size() > 0) {
- for (RoleModel role : scope) cli.deleteScopeMapping(role);
- }
+ cli.getScopeMappingsStream().forEach(cli::deleteScopeMapping);
}
@Override
diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index 1b4cc73d6c..d2bb0a9540 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -191,12 +191,9 @@ public final class KeycloakModelUtils {
return false;
}
- Set compositeRoles = composite.getComposites();
+ Set compositeRoles = composite.getCompositesStream().collect(Collectors.toSet());
return compositeRoles.contains(role) ||
- compositeRoles.stream()
- .filter(x -> x.isComposite() && searchFor(role, x, visited))
- .findFirst()
- .isPresent();
+ compositeRoles.stream().anyMatch(x -> x.isComposite() && searchFor(role, x, visited));
}
/**
@@ -510,19 +507,21 @@ public final class KeycloakModelUtils {
}).filter(Objects::nonNull).findFirst().orElse(null);
}
+ /**
+ * @deprecated Use {@link #getClientScopeMappingsStream(ClientModel, ScopeContainerModel)} getClientScopeMappingsStream} instead.
+ * @param client {@link ClientModel}
+ * @param container {@link ScopeContainerModel}
+ * @return
+ */
+ @Deprecated
public static Set getClientScopeMappings(ClientModel client, ScopeContainerModel container) {
- Set mappings = container.getScopeMappings();
- Set result = new HashSet<>();
- for (RoleModel role : mappings) {
- RoleContainerModel roleContainer = role.getContainer();
- if (roleContainer instanceof ClientModel) {
- if (client.getId().equals(((ClientModel)roleContainer).getId())) {
- result.add(role);
- }
+ return getClientScopeMappingsStream(client, container).collect(Collectors.toSet());
+ }
- }
- }
- return result;
+ public static Stream getClientScopeMappingsStream(ClientModel client, ScopeContainerModel container) {
+ return container.getScopeMappingsStream()
+ .filter(role -> role.getContainer() instanceof ClientModel &&
+ Objects.equals(client.getId(), role.getContainer().getId()));
}
// Used in various role mappers
diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 18d695cba9..54a0666ced 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -119,7 +119,7 @@ public class ModelToRepresentation {
rep.setPath(buildGroupPath(group));
if (!full) return rep;
// Role mappings
- Set roles = group.getRoleMappings();
+ Set roles = group.getRoleMappingsStream().collect(Collectors.toSet());
List realmRoleNames = new ArrayList<>();
Map> clientRoleNames = new HashMap<>();
for (RoleModel role : roles) {
@@ -409,10 +409,9 @@ public class ModelToRepresentation {
if (realm.getClientAuthenticationFlow() != null) rep.setClientAuthenticationFlow(realm.getClientAuthenticationFlow().getAlias());
if (realm.getDockerAuthenticationFlow() != null) rep.setDockerAuthenticationFlow(realm.getDockerAuthenticationFlow().getAlias());
- List defaultRoles = realm.getDefaultRoles();
+ List defaultRoles = realm.getDefaultRolesStream().collect(Collectors.toList());
if (!defaultRoles.isEmpty()) {
- List roleStrings = new ArrayList<>(defaultRoles);
- rep.setDefaultRoles(roleStrings);
+ rep.setDefaultRoles(defaultRoles);
}
List defaultGroups = realm.getDefaultGroupsStream()
.map(ModelToRepresentation::buildGroupPath).collect(Collectors.toList());
@@ -650,8 +649,9 @@ public class ModelToRepresentation {
rep.setWebOrigins(new LinkedList<>(webOrigins));
}
- if (!clientModel.getDefaultRoles().isEmpty()) {
- rep.setDefaultRoles(clientModel.getDefaultRoles().toArray(new String[0]));
+ String[] defaultRoles = clientModel.getDefaultRolesStream().toArray(String[]::new);
+ if (defaultRoles.length > 0) {
+ rep.setDefaultRoles(defaultRoles);
}
if (!clientModel.getRegisteredNodes().isEmpty()) {
diff --git a/server-spi-private/src/main/java/org/keycloak/storage/adapter/InMemoryUserAdapter.java b/server-spi-private/src/main/java/org/keycloak/storage/adapter/InMemoryUserAdapter.java
index 596281e890..2f5fd09c8b 100644
--- a/server-spi-private/src/main/java/org/keycloak/storage/adapter/InMemoryUserAdapter.java
+++ b/server-spi-private/src/main/java/org/keycloak/storage/adapter/InMemoryUserAdapter.java
@@ -260,36 +260,18 @@ public class InMemoryUserAdapter extends UserModelDefaultMethods {
}
@Override
- public Set getRealmRoleMappings() {
- Set allRoles = getRoleMappings();
-
- // Filter to retrieve just realm roles
- Set realmRoles = new HashSet<>();
- for (RoleModel role : allRoles) {
- if (role.getContainer() instanceof RealmModel) {
- realmRoles.add(role);
- }
- }
- return realmRoles;
+ public Stream getRealmRoleMappingsStream() {
+ return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- Set result = new HashSet<>();
- Set roles = getRoleMappings();
-
- for (RoleModel role : roles) {
- if (app.equals(role.getContainer())) {
- result.add(role);
- }
- }
- return result;
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
}
@Override
public boolean hasRole(RoleModel role) {
- Set roles = getRoleMappings();
- return RoleUtils.hasRole(roles, role)
+ return RoleUtils.hasRole(getRoleMappingsStream(), role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
}
@@ -300,13 +282,8 @@ public class InMemoryUserAdapter extends UserModelDefaultMethods {
}
@Override
- public Set getRoleMappings() {
- if (roleIds.isEmpty()) return new HashSet<>();
- Set roles = new HashSet<>();
- for (String id : roleIds) {
- roles.add(realm.getRoleById(id));
- }
- return roles;
+ public Stream getRoleMappingsStream() {
+ return roleIds.stream().map(realm::getRoleById);
}
@Override
diff --git a/server-spi-private/src/main/java/org/keycloak/storage/client/UnsupportedOperationsClientStorageAdapter.java b/server-spi-private/src/main/java/org/keycloak/storage/client/UnsupportedOperationsClientStorageAdapter.java
index 2f61ed360c..80d86a0445 100644
--- a/server-spi-private/src/main/java/org/keycloak/storage/client/UnsupportedOperationsClientStorageAdapter.java
+++ b/server-spi-private/src/main/java/org/keycloak/storage/client/UnsupportedOperationsClientStorageAdapter.java
@@ -20,8 +20,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.RoleModel;
-import java.util.Collections;
-import java.util.List;
import java.util.stream.Stream;
/**
@@ -67,8 +65,8 @@ public abstract class UnsupportedOperationsClientStorageAdapter implements Clien
}
@Override
- public final List getDefaultRoles() {
- return Collections.EMPTY_LIST;
+ public final Stream getDefaultRolesStream() {
+ return Stream.empty();
}
@Override
diff --git a/server-spi/src/main/java/org/keycloak/models/ClientSessionContext.java b/server-spi/src/main/java/org/keycloak/models/ClientSessionContext.java
index 72d3b6069c..c60ca6d93b 100644
--- a/server-spi/src/main/java/org/keycloak/models/ClientSessionContext.java
+++ b/server-spi/src/main/java/org/keycloak/models/ClientSessionContext.java
@@ -18,6 +18,8 @@
package org.keycloak.models;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Request-scoped context object
@@ -35,7 +37,12 @@ public interface ClientSessionContext {
/**
* @return expanded roles (composite roles already applied)
*/
- Set getRoles();
+ @Deprecated
+ default Set getRoles() {
+ return getRolesStream().collect(Collectors.toSet());
+ }
+
+ Stream getRolesStream();
Set getProtocolMappers();
diff --git a/server-spi/src/main/java/org/keycloak/models/RoleContainerModel.java b/server-spi/src/main/java/org/keycloak/models/RoleContainerModel.java
index 68d582a296..67091852fa 100755
--- a/server-spi/src/main/java/org/keycloak/models/RoleContainerModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/RoleContainerModel.java
@@ -70,13 +70,18 @@ public interface RoleContainerModel {
Stream searchForRolesStream(String search, Integer first, Integer max);
- List getDefaultRoles();
+ @Deprecated
+ default List getDefaultRoles() {
+ return getDefaultRolesStream().collect(Collectors.toList());
+ }
+
+ Stream getDefaultRolesStream();
void addDefaultRole(String name);
default void updateDefaultRoles(String... defaultRoles) {
List defaultRolesArray = Arrays.asList(defaultRoles);
- Collection entities = getDefaultRoles();
+ Collection entities = getDefaultRolesStream().collect(Collectors.toList());
Set already = new HashSet<>();
ArrayList remove = new ArrayList<>();
for (String rel : entities) {
diff --git a/server-spi/src/main/java/org/keycloak/models/RoleMapperModel.java b/server-spi/src/main/java/org/keycloak/models/RoleMapperModel.java
index 46c31988b4..bf049d7291 100755
--- a/server-spi/src/main/java/org/keycloak/models/RoleMapperModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/RoleMapperModel.java
@@ -18,6 +18,8 @@
package org.keycloak.models;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author Bill Burke
@@ -27,15 +29,36 @@ public interface RoleMapperModel {
/**
* Returns set of realm roles that are directly set to this object.
* @return see description
+ * @deprecated Use {@link #getRealmRoleMappingsStream()} getRealmRoleMappingsStream} instead.
*/
- Set getRealmRoleMappings();
+ @Deprecated
+ default Set getRealmRoleMappings() {
+ return getRealmRoleMappingsStream().collect(Collectors.toSet());
+ }
+
+ /**
+ * Returns stream of realm roles that are directly set to this object.
+ * @return stream of {@link RoleModel}
+ */
+ Stream getRealmRoleMappingsStream();
/**
* Returns set of client roles that are directly set to this object for the given client.
* @param app Client to get the roles for
* @return see description
+ * @deprecated Use {@link #getClientRoleMappingsStream(ClientModel)} getClientRoleMappingsStream} instead.
*/
- Set getClientRoleMappings(ClientModel app);
+ @Deprecated
+ default Set getClientRoleMappings(ClientModel app) {
+ return getClientRoleMappingsStream(app).collect(Collectors.toSet());
+ }
+
+ /**
+ * Returns stream of client roles that are directly set to this object for the given client.
+ * @param app Client to get the roles for
+ * @return stream of {@link RoleModel}
+ */
+ Stream getClientRoleMappingsStream(ClientModel app);
/**
* Returns {@code true} if this object is directly or indirectly assigned the given role, {@code false} otherwise.
@@ -60,8 +83,18 @@ public interface RoleMapperModel {
/**
* Returns set of all role (both realm all client) that are directly set to this object.
* @return
+ * @deprecated Use {@link #getRoleMappingsStream()} getRoleMappingsStream} instead.
*/
- Set getRoleMappings();
+ @Deprecated
+ default Set getRoleMappings() {
+ return getRoleMappingsStream().collect(Collectors.toSet());
+ }
+
+ /**
+ * Returns stream of all role (both realm all client) that are directly set to this object.
+ * @return stream of {@link RoleModel}
+ */
+ Stream getRoleMappingsStream();
/**
* Removes the given role mapping from this object.
diff --git a/server-spi/src/main/java/org/keycloak/models/RoleModel.java b/server-spi/src/main/java/org/keycloak/models/RoleModel.java
index d93c94c2b1..8c78907bf5 100755
--- a/server-spi/src/main/java/org/keycloak/models/RoleModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/RoleModel.java
@@ -21,6 +21,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author Bill Burke
@@ -43,7 +45,12 @@ public interface RoleModel {
void removeCompositeRole(RoleModel role);
- Set getComposites();
+ @Deprecated
+ default Set getComposites() {
+ return getCompositesStream().collect(Collectors.toSet());
+ }
+
+ Stream getCompositesStream();
boolean isClientRole();
@@ -61,7 +68,12 @@ public interface RoleModel {
String getFirstAttribute(String name);
- List getAttribute(String name);
+ @Deprecated
+ default List getAttribute(String name) {
+ return getAttributeStream(name).collect(Collectors.toList());
+ }
+
+ Stream getAttributeStream(String name);
Map> getAttributes();
}
diff --git a/server-spi/src/main/java/org/keycloak/models/ScopeContainerModel.java b/server-spi/src/main/java/org/keycloak/models/ScopeContainerModel.java
index c3327a7d84..9e215b56c6 100755
--- a/server-spi/src/main/java/org/keycloak/models/ScopeContainerModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/ScopeContainerModel.java
@@ -37,9 +37,20 @@ public interface ScopeContainerModel {
/**
* From the scope mappings returned by {@link #getScopeMappings()} returns only those
* that belong to the realm that owns this scope container.
- * @return
+ * @return set of {@link RealmModel}
+ * @deprecated Use {@link #getRealmScopeMappingsStream()} getRealmScopeMappingsStream} instead.
*/
- Set getRealmScopeMappings();
+ @Deprecated
+ default Set getRealmScopeMappings() {
+ return getRealmScopeMappingsStream().collect(Collectors.toSet());
+ }
+
+ /**
+ * From the scope mappings returned by {@link #getScopeMappingsStream()} ()} returns only those
+ * that belong to the realm that owns this scope container.
+ * @return stream of {@link RoleModel}
+ */
+ Stream getRealmScopeMappingsStream();
void addScopeMapping(RoleModel role);
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/DefaultRoles.java b/server-spi/src/main/java/org/keycloak/models/utils/DefaultRoles.java
index 3a3bfaed80..b2cbb555be 100644
--- a/server-spi/src/main/java/org/keycloak/models/utils/DefaultRoles.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/DefaultRoles.java
@@ -21,11 +21,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -33,20 +28,16 @@ import java.util.stream.Stream;
* @version $Revision: 1 $
*/
public class DefaultRoles {
- public static Set getDefaultRoles(RealmModel realm) {
- Set set = new HashSet<>();
- for (String r : realm.getDefaultRoles()) {
- set.add(realm.getRole(r));
- }
-
- Function> defaultRoles = i -> i.getDefaultRoles().stream().map(i::getRole).collect(Collectors.toSet());
- realm.getClientsStream().map(defaultRoles).forEach(set::addAll);
-
- return set;
+ public static Stream getDefaultRoles(RealmModel realm) {
+ Stream realmDefaultRoles = realm.getDefaultRolesStream().map(realm::getRole);
+ Stream clientDefaultRoles = realm.getClientsStream().flatMap(DefaultRoles::toClientDefaultRoles);
+ return Stream.concat(realmDefaultRoles, clientDefaultRoles);
}
public static void addDefaultRoles(RealmModel realm, UserModel userModel) {
- for (RoleModel role : getDefaultRoles(realm)) {
- userModel.grantRole(role);
- }
+ getDefaultRoles(realm).forEach(userModel::grantRole);
+ }
+
+ private static Stream toClientDefaultRoles(ClientModel c) {
+ return c.getDefaultRolesStream().map(c::getRole);
}
}
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/RoleUtils.java b/server-spi/src/main/java/org/keycloak/models/utils/RoleUtils.java
index c9d8d9c1d9..302f2b3551 100644
--- a/server-spi/src/main/java/org/keycloak/models/utils/RoleUtils.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/RoleUtils.java
@@ -17,13 +17,17 @@
package org.keycloak.models.utils;
+import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -90,6 +94,15 @@ public class RoleUtils {
return false;
}
+ /**
+ * @param roles
+ * @param targetRole
+ * @return true if targetRole is in roles (directly or indirectly via composite role)
+ */
+ public static boolean hasRole(Stream roles, RoleModel targetRole) {
+ return roles.anyMatch(role -> Objects.equals(role, targetRole) || role.hasRole(targetRole));
+ }
+
/**
* Checks whether the {@code targetRole} is contained in the given group or its parents
* (if requested)
@@ -163,7 +176,7 @@ public class RoleUtils {
sb.add(current);
if (current.isComposite()) {
- current.getComposites().stream()
+ current.getCompositesStream()
.filter(r -> !visited.contains(r))
.forEach(r -> {
visited.add(r);
@@ -205,16 +218,38 @@ public class RoleUtils {
* @return all user role mappings including all groups of user. Composite roles will be expanded
*/
public static Set getDeepUserRoleMappings(UserModel user) {
- Set roleMappings = new HashSet<>(user.getRoleMappings());
+ Set roleMappings = user.getRoleMappingsStream().collect(Collectors.toSet());
user.getGroupsStream().forEach(group -> addGroupRoles(group, roleMappings));
return expandCompositeRoles(roleMappings);
}
private static void addGroupRoles(GroupModel group, Set roleMappings) {
- roleMappings.addAll(group.getRoleMappings());
+ roleMappings.addAll(group.getRoleMappingsStream().collect(Collectors.toSet()));
if (group.getParentId() == null) return;
addGroupRoles(group.getParent(), roleMappings);
}
+ public static boolean isRealmRole(RoleModel r) {
+ return r.getContainer() instanceof RealmModel;
+ }
+
+ public static boolean isRealmRole(RoleModel r, RealmModel realm) {
+ if (isRealmRole(r)) {
+ if (Objects.equals(r.getContainer().getId(), realm.getId()))
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isClientRole(RoleModel r, ClientModel c) {
+ RoleContainerModel container = r.getContainer();
+ if (container instanceof ClientModel) {
+ ClientModel appModel = (ClientModel) container;
+ if (Objects.equals(appModel.getId(), c.getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/UserModelDelegate.java b/server-spi/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
index aa86d229a7..ca1c9da21f 100755
--- a/server-spi/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
@@ -161,13 +161,13 @@ public class UserModelDelegate implements UserModel {
}
@Override
- public Set getRealmRoleMappings() {
- return delegate.getRealmRoleMappings();
+ public Stream getRealmRoleMappingsStream() {
+ return delegate.getRealmRoleMappingsStream();
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- return delegate.getClientRoleMappings(app);
+ public Stream getClientRoleMappingsStream(ClientModel app) {
+ return delegate.getClientRoleMappingsStream(app);
}
@Override
@@ -181,8 +181,8 @@ public class UserModelDelegate implements UserModel {
}
@Override
- public Set getRoleMappings() {
- return delegate.getRoleMappings();
+ public Stream getRoleMappingsStream() {
+ return delegate.getRoleMappingsStream();
}
@Override
diff --git a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java
index b3fbd6af70..315fe1efb7 100644
--- a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java
+++ b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java
@@ -22,7 +22,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModelDefaultMethods;
@@ -135,40 +134,18 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
}
@Override
- public Set getRealmRoleMappings() {
- Set roleMappings = getRoleMappings();
-
- Set realmRoles = new HashSet<>();
- for (RoleModel role : roleMappings) {
- RoleContainerModel container = role.getContainer();
- if (container instanceof RealmModel) {
- realmRoles.add(role);
- }
- }
- return realmRoles;
+ public Stream getRealmRoleMappingsStream() {
+ return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
}
@Override
- public Set getClientRoleMappings(ClientModel app) {
- Set roleMappings = getRoleMappings();
-
- Set