From 5d5e56dde3bc841c7d1d0261cfcaf372cdf119bc Mon Sep 17 00:00:00 2001 From: Martin Kanis Date: Wed, 2 Sep 2020 09:30:06 +0200 Subject: [PATCH] KEYCLOAK-15199 Complement methods for accessing roles with Stream variants --- .../HardcodedLDAPRoleStorageMapper.java | 26 +++---- .../role/RoleLDAPStorageMapper.java | 70 ++++++++----------- .../cache/infinispan/ClientAdapter.java | 28 +++----- .../cache/infinispan/ClientScopeAdapter.java | 26 ++----- .../models/cache/infinispan/GroupAdapter.java | 48 ++++--------- .../models/cache/infinispan/RealmAdapter.java | 6 +- .../models/cache/infinispan/RoleAdapter.java | 32 +++++---- .../models/cache/infinispan/UserAdapter.java | 48 ++++--------- .../infinispan/entities/CachedClient.java | 7 +- .../entities/CachedClientScope.java | 5 +- .../infinispan/entities/CachedGroup.java | 2 +- .../infinispan/entities/CachedRealm.java | 2 +- .../cache/infinispan/entities/CachedRole.java | 5 +- .../cache/infinispan/entities/CachedUser.java | 2 +- .../keycloak/models/jpa/ClientAdapter.java | 36 +++------- .../models/jpa/ClientScopeAdapter.java | 26 ++----- .../org/keycloak/models/jpa/GroupAdapter.java | 44 ++---------- .../keycloak/models/jpa/JpaRealmProvider.java | 2 +- .../org/keycloak/models/jpa/RealmAdapter.java | 10 +-- .../org/keycloak/models/jpa/RoleAdapter.java | 29 +++----- .../org/keycloak/models/jpa/UserAdapter.java | 44 ++---------- .../jpa/JpaUserFederatedStorageProvider.java | 11 +-- .../map/client/AbstractClientModel.java | 10 ++- .../models/map/client/MapClientAdapter.java | 4 +- .../policy/evaluation/DefaultEvaluation.java | 32 ++++----- .../migration/migrators/MigrateTo3_4_2.java | 13 +--- .../models/utils/KeycloakModelUtils.java | 31 ++++---- .../models/utils/ModelToRepresentation.java | 12 ++-- .../storage/adapter/InMemoryUserAdapter.java | 37 ++-------- ...pportedOperationsClientStorageAdapter.java | 6 +- .../keycloak/models/ClientSessionContext.java | 9 ++- .../keycloak/models/RoleContainerModel.java | 9 ++- .../org/keycloak/models/RoleMapperModel.java | 39 ++++++++++- .../java/org/keycloak/models/RoleModel.java | 16 ++++- .../keycloak/models/ScopeContainerModel.java | 15 +++- .../keycloak/models/utils/DefaultRoles.java | 27 +++---- .../org/keycloak/models/utils/RoleUtils.java | 41 ++++++++++- .../models/utils/UserModelDelegate.java | 12 ++-- .../storage/adapter/AbstractUserAdapter.java | 46 +++--------- .../AbstractUserAdapterFederatedStorage.java | 50 ++++--------- .../UserRoleMappingsFederatedStorage.java | 9 ++- .../exportimport/util/ExportUtils.java | 11 ++- .../protocol/saml/mappers/RoleListMapper.java | 7 +- .../SAMLAudienceResolveProtocolMapper.java | 38 ++++------ .../services/managers/UserSessionManager.java | 3 +- .../resources/IdentityBrokerService.java | 5 +- .../admin/ClientRoleMappingsResource.java | 33 +++------ .../resources/admin/RoleByIdResource.java | 11 +-- .../admin/RoleContainerResource.java | 8 +-- .../resources/admin/RoleMapperResource.java | 29 +++----- .../resources/admin/RoleResource.java | 43 +++--------- .../admin/ScopeMappedClientResource.java | 26 +++---- .../resources/admin/ScopeMappedResource.java | 35 +++------- .../util/DefaultClientSessionContext.java | 8 ++- .../openshift/OpenshiftSAClientAdapter.java | 8 +-- .../org/keycloak/utils/RoleResolveUtil.java | 8 +-- .../HardcodedClientStorageProvider.java | 4 +- .../HardcodedGroupStorageProvider.java | 15 ++-- .../HardcodedRoleStorageProvider.java | 8 +-- .../federation/ldap/LDAPRoleMapperTest.java | 17 +++-- .../federation/ldap/LDAPRoleMappingsTest.java | 37 +++++----- .../LDAPRoleMappingsNoImportTest.java | 19 ++--- .../FederatedStorageExportImportTest.java | 6 +- .../keycloak/testsuite/model/CacheTest.java | 16 ++--- .../testsuite/model/ClientModelTest.java | 13 ++-- .../model/CompositeRolesModelTest.java | 7 +- .../testsuite/util/cli/UserCommands.java | 29 ++++---- 67 files changed, 539 insertions(+), 832 deletions(-) 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 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 public boolean hasRole(RoleModel role) { - Set roles = getRoleMappings(); - return RoleUtils.hasRole(roles, role) + return RoleUtils.hasRole(getRoleMappingsStream(), role) || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); } @@ -189,16 +166,15 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods { return true; } - protected Set getRoleMappingsInternal() { - return Collections.emptySet(); + protected Stream getRoleMappingsInternal() { + return Stream.empty(); } @Override - public Set getRoleMappings() { - Set set = new HashSet<>(); - if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm)); - set.addAll(getRoleMappingsInternal()); - return set; + public Stream getRoleMappingsStream() { + Stream roleMappings = getRoleMappingsInternal(); + if (appendDefaultRolesToRoleMappings()) return Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm)); + return roleMappings; } diff --git a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java index 074dc67e56..fee1dafc5a 100644 --- a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java +++ b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.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; @@ -160,17 +159,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau * @return */ @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); } /** @@ -182,26 +172,13 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau * @return */ @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 public boolean hasRole(RoleModel role) { - Set roles = getRoleMappings(); - return RoleUtils.hasRole(roles, role) + return RoleUtils.hasRole(getRoleMappingsStream(), role) || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); } @@ -222,8 +199,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau return true; } - protected Set getRoleMappingsInternal() { - return Collections.emptySet(); + protected Stream getRoleMappingsInternal() { + return Stream.empty(); } /** @@ -234,15 +211,14 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau * @return */ @Override - public Set getRoleMappings() { - Set set = new HashSet<>(getFederatedRoleMappings()); - if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm)); - set.addAll(getRoleMappingsInternal()); - return set; + public Stream getRoleMappingsStream() { + Stream roleMappings = getFederatedRoleMappings(); + if (appendDefaultRolesToRoleMappings()) roleMappings = Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm)); + return Stream.concat(roleMappings, getRoleMappingsInternal()); } - protected Set getFederatedRoleMappings() { - return getFederatedStorage().getRoleMappings(realm, this.getId()); + protected Stream getFederatedRoleMappings() { + return getFederatedStorage().getRoleMappingsStream(realm, this.getId()); } @Override diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java index c2edba1f3d..9b5a311bed 100644 --- a/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java +++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java @@ -20,6 +20,8 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * @author Bill Burke @@ -29,7 +31,12 @@ public interface UserRoleMappingsFederatedStorage { void grantRole(RealmModel realm, String userId, RoleModel role); - Set getRoleMappings(RealmModel realm,String userId); + @Deprecated + default Set getRoleMappings(RealmModel realm,String userId) { + return getRoleMappingsStream(realm, userId).collect(Collectors.toSet()); + } + + Stream getRoleMappingsStream(RealmModel realm, String userId); void deleteRoleMapping(RealmModel realm, String userId, RoleModel role); } diff --git a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index be591e879f..34fb971e77 100755 --- a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -48,7 +48,6 @@ import org.keycloak.credential.CredentialModel; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientScopeModel; import org.keycloak.models.FederatedIdentityModel; -import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; @@ -164,7 +163,7 @@ public class ExportUtils { // Scopes of clients for (ClientModel client : allClients) { - Set clientScopes = client.getScopeMappings(); + Set clientScopes = client.getScopeMappingsStream().collect(Collectors.toSet()); ScopeMappingRepresentation scopeMappingRep = null; for (RoleModel scope : clientScopes) { if (scope.getContainer() instanceof RealmModel) { @@ -201,7 +200,7 @@ public class ExportUtils { // Scopes of client scopes for (ClientScopeModel clientScope : realm.getClientScopes()) { - Set clientScopes = clientScope.getScopeMappings(); + Set clientScopes = clientScope.getScopeMappingsStream().collect(Collectors.toSet()); ScopeMappingRepresentation scopeMappingRep = null; for (RoleModel scope : clientScopes) { if (scope.getContainer() instanceof RealmModel) { @@ -428,7 +427,7 @@ public class ExportUtils { public static RoleRepresentation exportRole(RoleModel role) { RoleRepresentation roleRep = ModelToRepresentation.toRepresentation(role); - Set composites = role.getComposites(); + Set composites = role.getCompositesStream().collect(Collectors.toSet()); if (composites != null && composites.size() > 0) { Set compositeRealmRoles = null; Map> compositeClientRoles = null; @@ -493,7 +492,7 @@ public class ExportUtils { // Role mappings if (options.isGroupsAndRolesIncluded()) { - Set roles = user.getRoleMappings(); + Set roles = user.getRoleMappingsStream().collect(Collectors.toSet()); List realmRoleNames = new ArrayList<>(); Map> clientRoleNames = new HashMap<>(); for (RoleModel role : roles) { @@ -673,7 +672,7 @@ public class ExportUtils { // Role mappings if (options.isGroupsAndRolesIncluded()) { - Set roles = session.userFederatedStorage().getRoleMappings(realm, id); + Set roles = session.userFederatedStorage().getRoleMappingsStream(realm, id).collect(Collectors.toSet()); List realmRoleNames = new ArrayList<>(); Map> clientRoleNames = new HashMap<>(); for (RoleModel role : roles) { diff --git a/services/src/main/java/org/keycloak/protocol/saml/mappers/RoleListMapper.java b/services/src/main/java/org/keycloak/protocol/saml/mappers/RoleListMapper.java index dd2587d29e..c56ddabe16 100755 --- a/services/src/main/java/org/keycloak/protocol/saml/mappers/RoleListMapper.java +++ b/services/src/main/java/org/keycloak/protocol/saml/mappers/RoleListMapper.java @@ -21,11 +21,8 @@ import org.keycloak.dom.saml.v2.assertion.AttributeStatementType; import org.keycloak.dom.saml.v2.assertion.AttributeType; import org.keycloak.models.ClientSessionContext; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.ProtocolMapperModel; -import org.keycloak.models.RoleModel; import org.keycloak.models.UserSessionModel; -import org.keycloak.models.utils.RoleUtils; import org.keycloak.protocol.ProtocolMapper; import org.keycloak.protocol.ProtocolMapperUtils; import org.keycloak.protocol.saml.SamlProtocol; @@ -33,12 +30,10 @@ import org.keycloak.provider.ProviderConfigProperty; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; /** @@ -144,7 +139,7 @@ public class RoleListMapper extends AbstractSAMLProtocolMapper implements SAMLRo } } - List allRoleNames = clientSessionCtx.getRoles().stream() + List allRoleNames = clientSessionCtx.getRolesStream() // todo need a role mapping .map(roleModel -> roleNameMappers.stream() .map(entry -> entry.mapper.mapName(entry.model, roleModel)) diff --git a/services/src/main/java/org/keycloak/protocol/saml/mappers/SAMLAudienceResolveProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/saml/mappers/SAMLAudienceResolveProtocolMapper.java index 40272c3ec3..87e5e4bf59 100644 --- a/services/src/main/java/org/keycloak/protocol/saml/mappers/SAMLAudienceResolveProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/saml/mappers/SAMLAudienceResolveProtocolMapper.java @@ -18,9 +18,7 @@ package org.keycloak.protocol.saml.mappers; import java.net.URI; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.jboss.logging.Logger; import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType; import org.keycloak.dom.saml.v2.protocol.ResponseType; @@ -82,29 +80,23 @@ public class SAMLAudienceResolveProtocolMapper extends AbstractSAMLProtocolMappe AudienceRestrictionType aud = SAMLAudienceProtocolMapper.locateAudienceRestriction(response); if (aud != null) { // get all the roles the user has and calculate the clientIds to add - Set roles = clientSessionCtx.getRoles(); - Set audiences = new HashSet<>(); // add as audience any SAML clientId with role included (same as OIDC) - for (RoleModel role : roles) { - logger.tracef("Managing role: %s", role.getName()); - if (role.isClientRole()) { - ClientModel app = (ClientModel) role.getContainer(); + clientSessionCtx.getRolesStream() + .peek(r -> logger.tracef("Managing role: %s", r.getName())) + .filter(RoleModel::isClientRole) + .map(r -> (ClientModel) r.getContainer()) // only adding SAML clients that are not this clientId (which is added by default) - if (SamlProtocol.LOGIN_PROTOCOL.equals(app.getProtocol()) && - !app.getClientId().equals(clientSessionCtx.getClientSession().getClient().getClientId())) { - audiences.add(app.getClientId()); - } - } - } - logger.debugf("Calculated audiences to add: %s", audiences); - // add the audiences - for (String audience : audiences) { - try { - aud.addAudience(URI.create(audience)); - } catch (IllegalArgumentException e) { - logger.warnf(e, "Invalid URI syntax for audience: %s", audience); - } - } + .filter(app -> SamlProtocol.LOGIN_PROTOCOL.equals(app.getProtocol()) && + !app.getClientId().equals(clientSessionCtx.getClientSession().getClient().getClientId())) + .map(ClientModel::getClientId) + .peek(audience -> logger.debugf("Audience to add: %s", audience)) + .forEach(audience -> { + try { + aud.addAudience(URI.create(audience)); + } catch (IllegalArgumentException e) { + logger.warnf(e, "Invalid URI syntax for audience: %s", audience); + } + }); } return response; } diff --git a/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java b/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java index 44dcb3a9e7..653b9c29ac 100644 --- a/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java +++ b/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java @@ -33,6 +33,7 @@ import org.keycloak.services.ServicesLogger; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** @@ -131,7 +132,7 @@ public class UserSessionManager { } // Check if offline_access is allowed here. Even through composite roles - return clientSessionCtx.getRoles().contains(offlineAccessRole); + return clientSessionCtx.getRolesStream().collect(Collectors.toSet()).contains(offlineAccessRole); } private UserSessionModel createOfflineUserSession(UserModel user, UserSessionModel userSession) { diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java index 6bf7e06237..6440e01733 100755 --- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java +++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java @@ -25,8 +25,6 @@ import org.keycloak.authentication.AuthenticationProcessor; import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator; import org.keycloak.authentication.authenticators.broker.util.PostBrokerLoginConstants; import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext; -import org.keycloak.broker.oidc.KeycloakOIDCIdentityProviderFactory; -import org.keycloak.broker.oidc.mappers.UserAttributeMapper; import org.keycloak.broker.provider.AuthenticationRequest; import org.keycloak.broker.provider.BrokeredIdentityContext; import org.keycloak.broker.provider.IdentityBrokerException; @@ -123,6 +121,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; +import java.util.stream.Collectors; /** *

@@ -279,7 +278,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal // Ensure user has role and client has "role scope" for this role ClientSessionContext ctx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, session); - Set userAccountRoles = ctx.getRoles(); + Set userAccountRoles = ctx.getRolesStream().collect(Collectors.toSet()); if (!userAccountRoles.contains(manageAccountRole)) { RoleModel linkRole = accountService.getRole(AccountRoles.MANAGE_ACCOUNT_LINKS); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java index def76853ab..1e5703eda6 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java @@ -45,12 +45,10 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -94,15 +92,10 @@ public class ClientRoleMappingsResource { @GET @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getClientRoleMappings() { + public Stream getClientRoleMappings() { viewPermission.require(); - Set mappings = user.getClientRoleMappings(client); - List mapRep = new ArrayList(); - for (RoleModel roleModel : mappings) { - mapRep.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - return mapRep; + return user.getClientRoleMappingsStream(client).map(ModelToRepresentation::toBriefRepresentation); } /** @@ -184,19 +177,13 @@ public class ClientRoleMappingsResource { managePermission.require(); if (roles == null) { - Set roleModels = user.getClientRoleMappings(client); - roles = new LinkedList<>(); - - for (RoleModel roleModel : roleModels) { - if (roleModel.getContainer() instanceof ClientModel) { - ClientModel client = (ClientModel) roleModel.getContainer(); - if (!client.getId().equals(this.client.getId())) continue; - } - auth.roles().requireMapRole(roleModel); - user.deleteRoleMapping(roleModel); - roles.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - + roles = user.getClientRoleMappingsStream(client) + .peek(roleModel -> { + auth.roles().requireMapRole(roleModel); + user.deleteRoleMapping(roleModel); + }) + .map(ModelToRepresentation::toBriefRepresentation) + .collect(Collectors.toList()); } else { for (RoleRepresentation role : roles) { RoleModel roleModel = client.getRole(role.getName()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java index 1bfb8a3d11..2f2f489108 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java @@ -25,6 +25,7 @@ import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; +import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.representations.idm.ManagementPermissionReference; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator; @@ -43,6 +44,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.util.List; import java.util.Set; +import java.util.stream.Stream; /** * Sometimes its easier to just interact with roles by their ID instead of container/role-name @@ -165,12 +167,12 @@ public class RoleByIdResource extends RoleResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public Set getRoleComposites(final @PathParam("role-id") String id) { + public Stream getRoleComposites(final @PathParam("role-id") String id) { if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'"); RoleModel role = getRoleModel(id); auth.roles().requireView(role); - return getRoleComposites(role); + return role.getCompositesStream().map(ModelToRepresentation::toBriefRepresentation); } /** @@ -183,10 +185,9 @@ public class RoleByIdResource extends RoleResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public Set getRealmRoleComposites(final @PathParam("role-id") String id) { + public Stream getRealmRoleComposites(final @PathParam("role-id") String id) { RoleModel role = getRoleModel(id); auth.roles().requireView(role); - auth.roles().requireView(role); return getRealmRoleComposites(role); } @@ -201,7 +202,7 @@ public class RoleByIdResource extends RoleResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public Set getClientRoleComposites(final @PathParam("role-id") String id, + public Stream getClientRoleComposites(final @PathParam("role-id") String id, final @PathParam("clientUuid") String clientUuid) { RoleModel role = getRoleModel(id); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java index 5f7717c54d..5ead123fa6 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java @@ -259,13 +259,13 @@ public class RoleContainerResource extends RoleResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public Set getRoleComposites(final @PathParam("role-name") String roleName) { + public Stream getRoleComposites(final @PathParam("role-name") String roleName) { auth.roles().requireView(roleContainer); RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role"); } - return getRoleComposites(role); + return role.getCompositesStream().map(ModelToRepresentation::toBriefRepresentation); } /** @@ -278,7 +278,7 @@ public class RoleContainerResource extends RoleResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public Set getRealmRoleComposites(final @PathParam("role-name") String roleName) { + public Stream getRealmRoleComposites(final @PathParam("role-name") String roleName) { auth.roles().requireView(roleContainer); RoleModel role = roleContainer.getRole(roleName); if (role == null) { @@ -298,7 +298,7 @@ public class RoleContainerResource extends RoleResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public Set getClientRoleComposites(final @PathParam("role-name") String roleName, + public Stream getClientRoleComposites(final @PathParam("role-name") String roleName, final @PathParam("clientUuid") String clientUuid) { auth.roles().requireView(roleContainer); RoleModel role = roleContainer.getRole(roleName); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java index 6abf8cb610..720e4e2de1 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java @@ -53,12 +53,11 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -124,7 +123,7 @@ public class RoleMapperResource { ClientModel clientModel; ClientMappingsRepresentation mappings; - for (RoleModel roleMapping : roleMapper.getRoleMappings()) { + for (RoleModel roleMapping : roleMapper.getRoleMappingsStream().collect(Collectors.toSet())) { RoleContainerModel container = roleMapping.getContainer(); if (container instanceof RealmModel) { realmRolesRepresentation.add(ModelToRepresentation.toBriefRepresentation(roleMapping)); @@ -157,15 +156,10 @@ public class RoleMapperResource { @GET @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getRealmRoleMappings() { + public Stream getRealmRoleMappings() { viewPermission.require(); - Set realmMappings = roleMapper.getRealmRoleMappings(); - List realmMappingsRep = new ArrayList(); - for (RoleModel roleModel : realmMappings) { - realmMappingsRep.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - return realmMappingsRep; + return roleMapper.getRealmRoleMappingsStream().map(ModelToRepresentation::toBriefRepresentation); } /** @@ -250,14 +244,13 @@ public class RoleMapperResource { logger.debug("deleteRealmRoleMappings"); if (roles == null) { - Set roleModels = roleMapper.getRealmRoleMappings(); - roles = new LinkedList<>(); - - for (RoleModel roleModel : roleModels) { - auth.roles().requireMapRole(roleModel); - roleMapper.deleteRoleMapping(roleModel); - roles.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } + roles = roleMapper.getRealmRoleMappingsStream() + .peek(roleModel -> { + auth.roles().requireMapRole(roleModel); + roleMapper.deleteRoleMapping(roleModel); + }) + .map(ModelToRepresentation::toBriefRepresentation) + .collect(Collectors.toList()); } else { for (RoleRepresentation role : roles) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java index 8a5faaf238..4b887ddb76 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java @@ -28,11 +28,8 @@ import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluato import javax.ws.rs.NotFoundException; import javax.ws.rs.core.UriInfo; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.stream.Stream; /** * @resource Roles @@ -93,36 +90,16 @@ public abstract class RoleResource { adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success(); } - protected Set getRoleComposites(RoleModel role) { - if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet(); - - Set composites = new HashSet(role.getComposites().size()); - for (RoleModel composite : role.getComposites()) { - composites.add(ModelToRepresentation.toBriefRepresentation(composite)); - } - return composites; + protected Stream getRealmRoleComposites(RoleModel role) { + return role.getCompositesStream() + .filter(composite -> composite.getContainer() instanceof RealmModel) + .map(ModelToRepresentation::toBriefRepresentation); } - protected Set getRealmRoleComposites(RoleModel role) { - if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet(); - - Set composites = new HashSet(role.getComposites().size()); - for (RoleModel composite : role.getComposites()) { - if (composite.getContainer() instanceof RealmModel) - composites.add(ModelToRepresentation.toBriefRepresentation(composite)); - } - return composites; - } - - protected Set getClientRoleComposites(ClientModel app, RoleModel role) { - if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet(); - - Set composites = new HashSet(role.getComposites().size()); - for (RoleModel composite : role.getComposites()) { - if (composite.getContainer().equals(app)) - composites.add(ModelToRepresentation.toBriefRepresentation(composite)); - } - return composites; + protected Stream getClientRoleComposites(ClientModel app, RoleModel role) { + return role.getCompositesStream() + .filter(composite -> Objects.equals(composite.getContainer(), app)) + .map(ModelToRepresentation::toBriefRepresentation); } protected void deleteComposites(AdminEventBuilder adminEvent, UriInfo uriInfo, List roles, RoleModel role) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java index b6deedea22..70edf7eb81 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java @@ -40,12 +40,10 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; -import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -86,15 +84,11 @@ public class ScopeMappedClientResource { @GET @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getClientScopeMappings() { + public Stream getClientScopeMappings() { viewPermission.require(); - Set mappings = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer); //scopedClient.getClientScopeMappings(client); - List mapRep = new ArrayList(); - for (RoleModel roleModel : mappings) { - mapRep.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - return mapRep; + return KeycloakModelUtils.getClientScopeMappingsStream(scopedClient, scopeContainer) + .map(ModelToRepresentation::toBriefRepresentation); } /** @@ -172,14 +166,10 @@ public class ScopeMappedClientResource { managePermission.require(); if (roles == null) { - Set roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client); - roles = new LinkedList<>(); - - for (RoleModel roleModel : roleModels) { - scopeContainer.deleteScopeMapping(roleModel); - roles.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - + roles = KeycloakModelUtils.getClientScopeMappingsStream(scopedClient, scopeContainer) + .peek(scopeContainer::deleteScopeMapping) + .map(ModelToRepresentation::toBriefRepresentation) + .collect(Collectors.toList()); } else { for (RoleRepresentation role : roles) { RoleModel roleModel = scopedClient.getRole(role.getName()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 879d26ed0b..5da45336c8 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -43,12 +43,9 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; -import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -100,12 +97,10 @@ public class ScopeMappedResource { } MappingsRepresentation all = new MappingsRepresentation(); - Set realmMappings = scopeContainer.getRealmScopeMappings(); - if (!realmMappings.isEmpty()) { - List realmRep = new LinkedList<>(); - for (RoleModel roleModel : realmMappings) { - realmRep.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } + List realmRep = scopeContainer.getRealmScopeMappingsStream() + .map(ModelToRepresentation::toBriefRepresentation) + .collect(Collectors.toList()); + if (!realmRep.isEmpty()) { all.setRealmMappings(realmRep); } @@ -130,19 +125,15 @@ public class ScopeMappedResource { @GET @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getRealmScopeMappings() { + public Stream getRealmScopeMappings() { viewPermission.require(); if (scopeContainer == null) { throw new NotFoundException("Could not find client"); } - Set realmMappings = scopeContainer.getRealmScopeMappings(); - List realmMappingsRep = new ArrayList(); - for (RoleModel roleModel : realmMappings) { - realmMappingsRep.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - return realmMappingsRep; + return scopeContainer.getRealmScopeMappingsStream() + .map(ModelToRepresentation::toBriefRepresentation); } /** @@ -238,14 +229,10 @@ public class ScopeMappedResource { } if (roles == null) { - Set roleModels = scopeContainer.getRealmScopeMappings(); - roles = new LinkedList<>(); - - for (RoleModel roleModel : roleModels) { - scopeContainer.deleteScopeMapping(roleModel); - roles.add(ModelToRepresentation.toBriefRepresentation(roleModel)); - } - + roles = scopeContainer.getRealmScopeMappingsStream() + .peek(scopeContainer::deleteScopeMapping) + .map(ModelToRepresentation::toBriefRepresentation) + .collect(Collectors.toList()); } else { for (RoleRepresentation role : roles) { RoleModel roleModel = realm.getRoleById(role.getId()); diff --git a/services/src/main/java/org/keycloak/services/util/DefaultClientSessionContext.java b/services/src/main/java/org/keycloak/services/util/DefaultClientSessionContext.java index 339cb08be8..371fa7929e 100644 --- a/services/src/main/java/org/keycloak/services/util/DefaultClientSessionContext.java +++ b/services/src/main/java/org/keycloak/services/util/DefaultClientSessionContext.java @@ -21,6 +21,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.jboss.logging.Logger; import org.keycloak.OAuth2Constants; @@ -122,12 +124,12 @@ public class DefaultClientSessionContext implements ClientSessionContext { @Override - public Set getRoles() { + public Stream getRolesStream() { // Load roles if not yet present if (roles == null) { roles = loadRoles(); } - return roles; + return roles.stream(); } @@ -225,7 +227,7 @@ public class DefaultClientSessionContext implements ClientSessionContext { return true; } - Set clientScopeRoles = clientScope.getScopeMappings(); + Set clientScopeRoles = clientScope.getScopeMappingsStream().collect(Collectors.toSet()); // Client scope is automatically permitted if it doesn't have any role scope mappings if (clientScopeRoles.isEmpty()) { diff --git a/services/src/main/java/org/keycloak/storage/openshift/OpenshiftSAClientAdapter.java b/services/src/main/java/org/keycloak/storage/openshift/OpenshiftSAClientAdapter.java index 0e30672396..0f084afca2 100644 --- a/services/src/main/java/org/keycloak/storage/openshift/OpenshiftSAClientAdapter.java +++ b/services/src/main/java/org/keycloak/storage/openshift/OpenshiftSAClientAdapter.java @@ -350,8 +350,8 @@ public final class OpenshiftSAClientAdapter extends AbstractReadOnlyClientStorag } @Override - public Set getRealmScopeMappings() { - return Collections.emptySet(); + public Stream getRealmScopeMappingsStream() { + return Stream.empty(); } @Override @@ -469,8 +469,8 @@ public final class OpenshiftSAClientAdapter extends AbstractReadOnlyClientStorag } @Override - public Set getRealmScopeMappings() { - return Collections.emptySet(); + public Stream getRealmScopeMappingsStream() { + return Stream.empty(); } @Override diff --git a/services/src/main/java/org/keycloak/utils/RoleResolveUtil.java b/services/src/main/java/org/keycloak/utils/RoleResolveUtil.java index f6233c98aa..ddd1cc10bc 100644 --- a/services/src/main/java/org/keycloak/utils/RoleResolveUtil.java +++ b/services/src/main/java/org/keycloak/utils/RoleResolveUtil.java @@ -18,7 +18,6 @@ package org.keycloak.utils; import java.util.Map; -import java.util.Set; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionContext; @@ -102,10 +101,9 @@ public class RoleResolveUtil { AccessToken token = session.getAttribute(resolvedRolesAttrName, AccessToken.class); if (token == null) { - token = new AccessToken(); - for (RoleModel role : clientSessionCtx.getRoles()) { - addToToken(token, role); - } + AccessToken finalToken = new AccessToken(); + clientSessionCtx.getRolesStream().forEach(role -> addToToken(finalToken, role)); + token = finalToken; session.setAttribute(resolvedRolesAttrName, token); } diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java index f60afc6a27..c219e127ec 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java @@ -285,8 +285,8 @@ public class HardcodedClientStorageProvider implements ClientStorageProvider, Cl } @Override - public Set getRealmScopeMappings() { - return Collections.EMPTY_SET; + public Stream getRealmScopeMappingsStream() { + return Stream.empty(); } @Override diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedGroupStorageProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedGroupStorageProvider.java index 9717995023..3dc8f09e6d 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedGroupStorageProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedGroupStorageProvider.java @@ -26,11 +26,8 @@ import org.keycloak.storage.StorageId; import org.keycloak.storage.group.GroupStorageProvider; import org.keycloak.storage.group.GroupStorageProviderModel; -import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; public class HardcodedGroupStorageProvider implements GroupStorageProvider { @@ -93,13 +90,13 @@ public class HardcodedGroupStorageProvider implements GroupStorageProvider { } @Override - public Set getRealmRoleMappings() { - return null; + public Stream getRealmRoleMappingsStream() { + return Stream.empty(); } @Override - public Set getClientRoleMappings(ClientModel app) { - return null; + public Stream getClientRoleMappingsStream(ClientModel app) { + return Stream.empty(); } @Override @@ -108,8 +105,8 @@ public class HardcodedGroupStorageProvider implements GroupStorageProvider { } @Override - public Set getRoleMappings() { - return null; + public Stream getRoleMappingsStream() { + return Stream.empty(); } @Override diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedRoleStorageProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedRoleStorageProvider.java index 685e205c5d..3f8a87f548 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedRoleStorageProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedRoleStorageProvider.java @@ -17,9 +17,7 @@ package org.keycloak.testsuite.federation; import java.util.Collection; -import java.util.Collections; import java.util.Map; -import java.util.Set; import java.util.List; import java.util.stream.Stream; import org.jboss.logging.Logger; @@ -116,8 +114,8 @@ public class HardcodedRoleStorageProvider implements RoleStorageProvider { } @Override - public Set getComposites() { - return Collections.EMPTY_SET; + public Stream getCompositesStream() { + return Stream.empty(); } @Override @@ -146,7 +144,7 @@ public class HardcodedRoleStorageProvider implements RoleStorageProvider { } @Override - public List getAttribute(String name) { + public Stream getAttributeStream(String name) { throw new UnsupportedOperationException("Not supported yet."); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMapperTest.java index 3d92a04b66..b6e7daf5de 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMapperTest.java @@ -30,7 +30,6 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory; import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig; -import static org.keycloak.testsuite.federation.ldap.AbstractLDAPTest.TEST_REALM_NAME; import org.keycloak.testsuite.util.LDAPRule; import org.keycloak.testsuite.util.LDAPTestUtils; @@ -63,16 +62,16 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest { // check users UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm); Assert.assertNotNull(john); - Assert.assertThat(john.getRealmRoleMappings().stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); + Assert.assertThat(john.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm); Assert.assertNotNull(mary); - Assert.assertThat(mary.getRealmRoleMappings().stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); + Assert.assertThat(mary.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm); Assert.assertNotNull(rob); - Assert.assertThat(rob.getRealmRoleMappings().stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1")); + Assert.assertThat(rob.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1")); UserModel james = session.users().getUserByUsername("jameskeycloak", appRealm); Assert.assertNotNull(james); - Assert.assertThat(james.getRealmRoleMappings(), Matchers.empty()); + Assert.assertThat(james.getRealmRoleMappingsStream().collect(Collectors.toSet()), Matchers.empty()); // check groups RoleModel group1 = appRealm.getRole("group1"); @@ -111,16 +110,16 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest { // check users UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm); Assert.assertNotNull(john); - Assert.assertThat(john.getClientRoleMappings(rolesClient).stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); + Assert.assertThat(john.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm); Assert.assertNotNull(mary); - Assert.assertThat(mary.getClientRoleMappings(rolesClient).stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); + Assert.assertThat(mary.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2")); UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm); Assert.assertNotNull(rob); - Assert.assertThat(rob.getClientRoleMappings(rolesClient).stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1")); + Assert.assertThat(rob.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1")); UserModel james = session.users().getUserByUsername("jameskeycloak", appRealm); Assert.assertNotNull(james); - Assert.assertThat(james.getClientRoleMappings(rolesClient).stream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty()); + Assert.assertThat(james.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty()); // check groups RoleModel group1 = rolesClient.getRole("group1"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMappingsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMappingsTest.java index e4af977532..a57dd81f4d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMappingsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPRoleMappingsTest.java @@ -44,6 +44,7 @@ import org.keycloak.testsuite.util.LDAPRule; import org.keycloak.testsuite.util.LDAPTestUtils; import java.util.Set; +import java.util.stream.Collectors; /** * @author Marek Posolda @@ -157,7 +158,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { // 2 - Check that role mappings are not in local Keycloak DB (They are in LDAP). UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm); - Set johnDbRoles = johnDb.getRoleMappings(); + Set johnDbRoles = johnDb.getRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(johnDbRoles.contains(realmRole1)); Assert.assertFalse(johnDbRoles.contains(realmRole2)); Assert.assertFalse(johnDbRoles.contains(realmRole3)); @@ -166,23 +167,23 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { // 3 - Check that role mappings are in LDAP and hence available through federation - Set johnRoles = john.getRoleMappings(); + Set johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertTrue(johnRoles.contains(realmRole3)); Assert.assertTrue(johnRoles.contains(financeRole1)); Assert.assertTrue(johnRoles.contains(manageAccountRole)); - Set johnRealmRoles = john.getRealmRoleMappings(); + Set johnRealmRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertEquals(2, johnRealmRoles.size()); Assert.assertTrue(johnRealmRoles.contains(realmRole1)); Assert.assertTrue(johnRealmRoles.contains(realmRole3)); // account roles are not mapped in LDAP. Those are in Keycloak DB - Set johnAccountRoles = john.getClientRoleMappings(accountApp); + Set johnAccountRoles = john.getClientRoleMappingsStream(accountApp).collect(Collectors.toSet()); Assert.assertTrue(johnAccountRoles.contains(manageAccountRole)); - Set johnFinanceRoles = john.getClientRoleMappings(financeApp); + Set johnFinanceRoles = john.getClientRoleMappingsStream(financeApp).collect(Collectors.toSet()); Assert.assertEquals(1, johnFinanceRoles.size()); Assert.assertTrue(johnFinanceRoles.contains(financeRole1)); @@ -193,7 +194,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { john.deleteRoleMapping(financeRole1); john.deleteRoleMapping(manageAccountRole); - johnRoles = john.getRoleMappings(); + johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole3)); @@ -238,14 +239,14 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { mary.grantRole(realmRole3); // Assert that mary has both LDAP and DB mapped roles - Set maryRoles = mary.getRealmRoleMappings(); + Set maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(maryRoles.contains(realmRole1)); Assert.assertTrue(maryRoles.contains(realmRole2)); Assert.assertTrue(maryRoles.contains(realmRole3)); // Assert that access through DB will have just DB mapped role UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm); - Set maryDBRoles = maryDB.getRealmRoleMappings(); + Set maryDBRoles = maryDB.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(maryDBRoles.contains(realmRole1)); Assert.assertFalse(maryDBRoles.contains(realmRole2)); Assert.assertTrue(maryDBRoles.contains(realmRole3)); @@ -269,7 +270,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm); // Assert role mappings is not available - Set maryRoles = mary.getRealmRoleMappings(); + Set maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole1"))); Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole2"))); Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole3"))); @@ -302,20 +303,20 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { if (realmRole3 == null) { realmRole3 = appRealm.addRole("realmRole3"); } - Set robRoles = rob.getRealmRoleMappings(); + Set robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(robRoles.contains(realmRole1)); Assert.assertTrue(robRoles.contains(realmRole2)); Assert.assertFalse(robRoles.contains(realmRole3)); // Add some role mappings in model and check that user has it rob.grantRole(realmRole3); - robRoles = rob.getRealmRoleMappings(); + robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(robRoles.contains(realmRole3)); // Delete some role mappings in LDAP and check that it doesn't have any effect and user still has role deleteRoleMappingsInLDAP(roleMapper, robLdap, "realmRole1"); deleteRoleMappingsInLDAP(roleMapper, robLdap, "realmRole2"); - robRoles = rob.getRealmRoleMappings(); + robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(robRoles.contains(realmRole1)); Assert.assertTrue(robRoles.contains(realmRole2)); @@ -323,7 +324,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { rob.deleteRoleMapping(realmRole1); rob.deleteRoleMapping(realmRole2); rob.deleteRoleMapping(realmRole3); - robRoles = rob.getRealmRoleMappings(); + robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(robRoles.contains(realmRole1)); Assert.assertFalse(robRoles.contains(realmRole2)); Assert.assertFalse(robRoles.contains(realmRole3)); @@ -363,7 +364,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { // make sure user is cached. UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm); Assert.assertNotNull(johnRoleMapper); - Assert.assertEquals(0, johnRoleMapper.getRealmRoleMappings().size()); + Assert.assertEquals(0, johnRoleMapper.getRealmRoleMappingsStream().count()); }); @@ -385,7 +386,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { RoleModel realmRole1 = appRealm.getRole("realmRole1"); RoleModel realmRole2 = appRealm.getRole("realmRole2"); - Set johnRoles = johnRoleMapper.getRealmRoleMappings(); + Set johnRoles = johnRoleMapper.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole2)); }); @@ -420,7 +421,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { RoleModel realmRole1 = appRealm.getRole("realmRole1"); RoleModel realmRole2 = appRealm.getRole("realmRole2"); - Set johnRoles = johnRoleMapper.getRealmRoleMappings(); + Set johnRoles = johnRoleMapper.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(johnRoles.contains(realmRole1)); Assert.assertTrue(johnRoles.contains(realmRole2)); }); @@ -467,7 +468,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { // Get user in Keycloak. Ensure that he is member of requested group UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm); - Set carlosRoles = carlos.getRealmRoleMappings(); + Set carlosRoles = carlos.getRealmRoleMappingsStream().collect(Collectors.toSet()); RoleModel realmRole1 = appRealm.getRole("realmRole1"); RoleModel realmRole2 = appRealm.getRole("realmRole2"); @@ -500,7 +501,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest { Assert.assertNotNull(defaultRole); Assert.assertNotNull(realmRole2); - Set davidRoles = david.getRealmRoleMappings(); + Set davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(davidRoles.contains(defaultRole)); Assert.assertFalse(davidRoles.contains(realmRole2)); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/noimport/LDAPRoleMappingsNoImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/noimport/LDAPRoleMappingsNoImportTest.java index aefe55dffb..3566d61878 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/noimport/LDAPRoleMappingsNoImportTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/noimport/LDAPRoleMappingsNoImportTest.java @@ -41,6 +41,7 @@ import org.keycloak.testsuite.util.LDAPRule; import org.keycloak.testsuite.util.LDAPTestUtils; import java.util.Set; +import java.util.stream.Collectors; /** * @author Marek Posolda @@ -152,7 +153,7 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest { // This role should already exists as it was imported from LDAP RoleModel realmRole2 = appRealm.getRole("realmRole2"); - Set maryRoles = mary.getRealmRoleMappings(); + Set maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(maryRoles.contains(realmRole1)); Assert.assertTrue(maryRoles.contains(realmRole2)); @@ -178,7 +179,7 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest { // This role should already exists as it was imported from LDAP RoleModel realmRole2 = appRealm.getRole("realmRole2"); - Set maryRoles = mary.getRealmRoleMappings(); + Set maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(maryRoles.contains(realmRole1)); Assert.assertFalse(maryRoles.contains(realmRole2)); }); @@ -251,23 +252,23 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest { // 3 - Check that role mappings are in LDAP and hence available through federation - Set johnRoles = john.getRoleMappings(); + Set johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertTrue(johnRoles.contains(realmRole3)); Assert.assertTrue(johnRoles.contains(financeRole1)); Assert.assertTrue(johnRoles.contains(manageAccountRole)); - Set johnRealmRoles = john.getRealmRoleMappings(); + Set johnRealmRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertEquals(2, johnRealmRoles.size()); Assert.assertTrue(johnRealmRoles.contains(realmRole1)); Assert.assertTrue(johnRealmRoles.contains(realmRole3)); // account roles are not mapped in LDAP. Those are in Keycloak DB - Set johnAccountRoles = john.getClientRoleMappings(accountApp); + Set johnAccountRoles = john.getClientRoleMappingsStream(accountApp).collect(Collectors.toSet()); Assert.assertTrue(johnAccountRoles.contains(manageAccountRole)); - Set johnFinanceRoles = john.getClientRoleMappings(financeApp); + Set johnFinanceRoles = john.getClientRoleMappingsStream(financeApp).collect(Collectors.toSet()); Assert.assertEquals(1, johnFinanceRoles.size()); Assert.assertTrue(johnFinanceRoles.contains(financeRole1)); @@ -277,7 +278,7 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest { john.deleteRoleMapping(realmRole1); john.deleteRoleMapping(financeRole1); - johnRoles = john.getRoleMappings(); + johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole3)); @@ -316,14 +317,14 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest { Assert.assertNotNull(defaultRole); Assert.assertNotNull(realmRole2); - Set davidRoles = david.getRealmRoleMappings(); + Set davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertTrue(davidRoles.contains(defaultRole)); Assert.assertFalse(davidRoles.contains(realmRole2)); // Make sure john has not received the default role UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm); - Set johnRoles = john.getRealmRoleMappings(); + Set johnRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet()); Assert.assertFalse(johnRoles.contains(defaultRole)); }); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java index 50fb07756f..ca6be7428f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java @@ -149,7 +149,8 @@ public class FederatedStorageExportImportTest extends AbstractAuthTest { Assert.assertTrue(attributes.getList("list1").contains("1")); Assert.assertTrue(attributes.getList("list1").contains("2")); Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD")); - Assert.assertTrue(session.userFederatedStorage().getRoleMappings(realm, userId).contains(role)); + Assert.assertTrue(session.userFederatedStorage().getRoleMappingsStream(realm, userId) + .collect(Collectors.toSet()).contains(role)); Assert.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group)); List creds = session.userFederatedStorage().getStoredCredentials(realm, userId); Assert.assertEquals(1, creds.size()); @@ -216,7 +217,8 @@ public class FederatedStorageExportImportTest extends AbstractAuthTest { Assert.assertTrue(attributes.getList("list1").contains("1")); Assert.assertTrue(attributes.getList("list1").contains("2")); Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD")); - Assert.assertTrue(session.userFederatedStorage().getRoleMappings(realm, userId).contains(role)); + Assert.assertTrue(session.userFederatedStorage().getRoleMappingsStream(realm, userId) + .collect(Collectors.toSet()).contains(role)); Assert.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group)); Assert.assertEquals(50, session.userFederatedStorage().getNotBeforeOfUser(realm, userId)); List creds = session.userFederatedStorage().getStoredCredentials(realm, userId); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CacheTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CacheTest.java index c310ae128d..6ed3a3a7a8 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CacheTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CacheTest.java @@ -30,6 +30,7 @@ import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -128,8 +129,6 @@ public class CacheTest extends AbstractTestRealmKeycloakTest { // KEYCLOAK-1842 @Test public void testRoleMappingsInvalidatedWhenClientRemoved() { - - testingClient.server().run(session -> { RealmModel realm = session.realms().getRealmByName("test"); @@ -137,27 +136,20 @@ public class CacheTest extends AbstractTestRealmKeycloakTest { ClientModel client = realm.addClient("foo"); RoleModel fooRole = client.addRole("foo-role"); user.grantRole(fooRole); - }); - - - int gRolesCount=0; + }); testingClient.server().run(session -> { RealmModel realm = session.realms().getRealmByName("test"); UserModel user = session.users().getUserByUsername("joel", realm); - int grantedRolesCount = user.getRoleMappings().size(); + long grantedRolesCount = user.getRoleMappingsStream().count(); ClientModel client = realm.getClientByClientId("foo"); realm.removeClient(client.getId()); - - - - realm = session.realms().getRealmByName("test"); user = session.users().getUserByUsername("joel", realm); - Set roles = user.getRoleMappings(); + Set roles = user.getRoleMappingsStream().collect(Collectors.toSet()); for (RoleModel role : roles) { Assert.assertNotNull(role.getContainer()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java index 8c6462ba3a..8c134b96dc 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.notNullValue; @@ -78,7 +79,8 @@ public class ClientModelTest extends AbstractKeycloakTest { assertThat(expected.getDescription(), is(actual.getDescription())); assertThat(expected.getBaseUrl(), is(actual.getBaseUrl())); assertThat(expected.getManagementUrl(), is(actual.getManagementUrl())); - assertThat(expected.getDefaultRoles(), is(actual.getDefaultRoles())); + assertThat(expected.getDefaultRolesStream().collect(Collectors.toSet()), + is(actual.getDefaultRolesStream().collect(Collectors.toSet()))); assertThat(expected.getRedirectUris().containsAll(actual.getRedirectUris()), is(true)); assertThat(expected.getWebOrigins().containsAll(actual.getWebOrigins()), is(true)); @@ -151,10 +153,9 @@ public class ClientModelTest extends AbstractKeycloakTest { assertThat("Realm Model 'original' is NULL !!", realm, notNullValue()); ClientModel scoped = realm.getClientByClientId("scoped"); - Set scopeMappings = scoped.getScopeMappings(); // used to throw an NPE - assertThat("Scope Mappings must be 0", scopeMappings.size(), is(0)); + assertThat("Scope Mappings must be 0", scoped.getScopeMappingsStream().count(), is(0L)); currentSession.clients().removeClient(realm, scoped.getId()); }); @@ -187,10 +188,9 @@ public class ClientModelTest extends AbstractKeycloakTest { ClientModel from = realm.getClientByClientId("from"); RoleModel role = currentSession.roles().getRoleById(realm, roleId); from.removeRole(role); - Set scopeMappings = scoped.getScopeMappings(); // used to throw an NPE - assertThat("Scope Mappings is not 0", scopeMappings.size(), is(0)); + assertThat("Scope Mappings is not 0", scoped.getScopeMappingsStream().count(), is(0L)); currentSession.clients().removeClient(realm, scoped.getId()); currentSession.clients().removeClient(realm, from.getId()); @@ -224,9 +224,8 @@ public class ClientModelTest extends AbstractKeycloakTest { currentSession = sessionRealmRoleRemove3; RealmModel realm = currentSession.realms().getRealmByName(realmName); ClientModel scoped = realm.getClientByClientId("scoped"); - Set scopeMappings = scoped.getScopeMappings(); // used to throw an NPE - assertThat("Scope Mappings is not 0", scopeMappings.size(), is(0)); + assertThat("Scope Mappings is not 0", scoped.getScopeMappingsStream().count(), is(0L)); currentSession.clients().removeClient(realm, scoped.getId()); }); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java index 9428fbdec5..d963ea710b 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java @@ -34,6 +34,7 @@ import org.keycloak.testsuite.arquillian.annotation.ModelTest; import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; @@ -52,7 +53,7 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { Set requestedRoles = new HashSet<>(); - Set roleMappings = user.getRoleMappings(); + Set roleMappings = user.getRoleMappingsStream().collect(Collectors.toSet()); Stream scopeMappings = Stream.concat(application.getScopeMappingsStream(), application.getRolesStream()); scopeMappings.forEach(scope -> roleMappings.forEach(role -> { @@ -75,9 +76,7 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { } if (!scope.isComposite()) return; - for (RoleModel contained : scope.getComposites()) { - applyScope(role, contained, visited, requested); - } + scope.getCompositesStream().forEach(contained -> applyScope(role, contained, visited, requested)); } private static RoleModel getRole(RealmModel realm, String appName, String roleName) { diff --git a/testsuite/utils/src/main/java/org/keycloak/testsuite/util/cli/UserCommands.java b/testsuite/utils/src/main/java/org/keycloak/testsuite/util/cli/UserCommands.java index 7360d7bb11..1d7d06cfba 100644 --- a/testsuite/utils/src/main/java/org/keycloak/testsuite/util/cli/UserCommands.java +++ b/testsuite/utils/src/main/java/org/keycloak/testsuite/util/cli/UserCommands.java @@ -19,17 +19,15 @@ package org.keycloak.testsuite.util.cli; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionTask; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; -import org.keycloak.models.utils.KeycloakModelUtils; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** * @author Marek Posolda @@ -219,23 +217,22 @@ public class UserCommands { if (user == null) { log.infof("User '%s' doesn't exist in realm '%s'", username, realmName); } else { - List roleMappings = getRoleMappings(session, realm, user); + List roleMappings = getRoleMappings(user); log.infof("User: ID: '%s', username: '%s', mail: '%s', roles: '%s'", user.getId(), user.getUsername(), user.getEmail(), roleMappings.toString()); } } - private List getRoleMappings(KeycloakSession session, RealmModel realm, UserModel user) { - Set roles = user.getRoleMappings(); - List result = new LinkedList<>(); - for (RoleModel role : roles) { - if (role.getContainer() instanceof RealmModel) { - result.add(role.getName()); - } else { - ClientModel client = (ClientModel) role.getContainer(); - result.add(client.getClientId() + "/" + role.getName()); - } - } - return result; + private List getRoleMappings(UserModel user) { + return user.getRoleMappingsStream() + .map(role -> { + if (role.getContainer() instanceof RealmModel) + return role.getName(); + else { + ClientModel client = (ClientModel) role.getContainer(); + return client.getClientId() + "/" + role.getName(); + } + }) + .collect(Collectors.toList()); } @Override