KEYCLOAK-15199 Complement methods for accessing roles with Stream variants

This commit is contained in:
Martin Kanis 2020-09-02 09:30:06 +02:00 committed by Hynek Mlnařík
parent f874e9a43c
commit 5d5e56dde3
67 changed files with 539 additions and 832 deletions

View file

@ -30,7 +30,7 @@ import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.idm.model.LDAPObject; import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery; import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
import java.util.Set; import java.util.stream.Stream;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -54,27 +54,27 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
return new UserModelDelegate(delegate) { return new UserModelDelegate(delegate) {
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> roles = super.getRealmRoleMappings(); Stream<RoleModel> realmRoleMappings = super.getRealmRoleMappingsStream();
RoleModel role = getRole(realm); RoleModel role = getRole(realm);
if (role != null && role.getContainer().equals(realm)) { if (role != null && role.getContainer().equals(realm)) {
roles.add(role); realmRoleMappings = Stream.concat(realmRoleMappings, Stream.of(role));
} }
return roles; return realmRoleMappings;
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> roles = super.getClientRoleMappings(app); Stream<RoleModel> clientRoleMappings = super.getClientRoleMappingsStream(app);
RoleModel role = getRole(realm); RoleModel role = getRole(realm);
if (role != null && role.getContainer().equals(app)) { if (role != null && role.getContainer().equals(app)) {
roles.add(role); return Stream.concat(clientRoleMappings, Stream.of(role));
} }
return roles; return clientRoleMappings;
} }
@Override @Override
@ -83,15 +83,15 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
Set<RoleModel> roles = super.getRoleMappings(); Stream<RoleModel> roleMappings = super.getRoleMappingsStream();
RoleModel role = getRole(realm); RoleModel role = getRole(realm);
if (role != null) { if (role != null) {
roles.add(role); roleMappings = Stream.concat(roleMappings, Stream.of(role));
} }
return roles; return roleMappings;
} }
@Override @Override

View file

@ -46,9 +46,11 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.Collectors;
/** /**
* Map realm roles or roles of particular client to LDAP groups * Map realm roles or roles of particular client to LDAP groups
@ -330,47 +332,42 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
if (roleContainer.equals(realm)) { if (roleContainer.equals(realm)) {
Set<RoleModel> ldapRoleMappings = getLDAPRoleMappingsConverted(); Stream<RoleModel> ldapRoleMappings = getLDAPRoleMappingsConverted();
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) { if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
// Use just role mappings from LDAP // Use just role mappings from LDAP
return ldapRoleMappings; return ldapRoleMappings;
} else { } else {
// Merge mappings from both DB and LDAP // Merge mappings from both DB and LDAP
Set<RoleModel> modelRoleMappings = super.getRealmRoleMappings(); return Stream.concat(ldapRoleMappings, super.getRealmRoleMappingsStream());
ldapRoleMappings.addAll(modelRoleMappings);
return ldapRoleMappings;
} }
} else { } else {
return super.getRealmRoleMappings(); return super.getRealmRoleMappingsStream();
} }
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel client) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel client) {
if (roleContainer.equals(client)) { if (roleContainer.equals(client)) {
Set<RoleModel> ldapRoleMappings = getLDAPRoleMappingsConverted(); Stream<RoleModel> ldapRoleMappings = getLDAPRoleMappingsConverted();
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) { if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
// Use just role mappings from LDAP // Use just role mappings from LDAP
return ldapRoleMappings; return ldapRoleMappings;
} else { } else {
// Merge mappings from both DB and LDAP // Merge mappings from both DB and LDAP
Set<RoleModel> modelRoleMappings = super.getClientRoleMappings(client); return Stream.concat(ldapRoleMappings, super.getClientRoleMappingsStream(client));
ldapRoleMappings.addAll(modelRoleMappings);
return ldapRoleMappings;
} }
} else { } else {
return super.getClientRoleMappings(client); return super.getClientRoleMappingsStream(client);
} }
} }
@Override @Override
public boolean hasRole(RoleModel role) { public boolean hasRole(RoleModel role) {
Set<RoleModel> roles = getRoleMappings(); return RoleUtils.hasRole(getRoleMappingsStream(), role)
return RoleUtils.hasRole(roles, role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
} }
@ -392,47 +389,38 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
Set<RoleModel> modelRoleMappings = super.getRoleMappings(); Stream<RoleModel> modelRoleMappings = super.getRoleMappingsStream();
Set<RoleModel> ldapRoleMappings = getLDAPRoleMappingsConverted(); Stream<RoleModel> ldapRoleMappings = getLDAPRoleMappingsConverted();
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) { if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
// For LDAP-only we want to retrieve role mappings of target container just from LDAP // For LDAP-only we want to retrieve role mappings of target container just from LDAP
Set<RoleModel> modelRolesCopy = new HashSet<>(modelRoleMappings); modelRoleMappings = modelRoleMappings.filter(role -> !Objects.equals(role.getContainer(), roleContainer));
for (RoleModel role : modelRolesCopy) {
if (role.getContainer().equals(roleContainer)) {
modelRoleMappings.remove(role);
}
}
} }
modelRoleMappings.addAll(ldapRoleMappings); return Stream.concat(modelRoleMappings, ldapRoleMappings);
return modelRoleMappings;
} }
protected Set<RoleModel> getLDAPRoleMappingsConverted() { protected Stream<RoleModel> getLDAPRoleMappingsConverted() {
if (cachedLDAPRoleMappings != null) { if (cachedLDAPRoleMappings != null) {
return new HashSet<>(cachedLDAPRoleMappings); return cachedLDAPRoleMappings.stream();
} }
List<LDAPObject> ldapRoles = getLDAPRoleMappings(ldapUser); List<LDAPObject> ldapRoles = getLDAPRoleMappings(ldapUser);
Set<RoleModel> roles = new HashSet<>();
String roleNameLdapAttr = config.getRoleNameLdapAttribute(); String roleNameLdapAttr = config.getRoleNameLdapAttribute();
for (LDAPObject role : ldapRoles) { cachedLDAPRoleMappings = ldapRoles.stream()
.map(role -> {
String roleName = role.getAttributeAsString(roleNameLdapAttr); String roleName = role.getAttributeAsString(roleNameLdapAttr);
RoleModel modelRole = roleContainer.getRole(roleName); RoleModel modelRole = roleContainer.getRole(roleName);
if (modelRole == null) { if (modelRole == null) {
// Add role to local DB // Add role to local DB
modelRole = roleContainer.addRole(roleName); modelRole = roleContainer.addRole(roleName);
} }
roles.add(modelRole); return modelRole;
} }).collect(Collectors.toSet());
cachedLDAPRoleMappings = new HashSet<>(roles); return cachedLDAPRoleMappings.stream();
return roles;
} }
@Override @Override

View file

@ -21,14 +21,13 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientScopeModel; import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.CachedObject; import org.keycloak.models.cache.CachedObject;
import org.keycloak.models.cache.infinispan.entities.CachedClient; import org.keycloak.models.cache.infinispan.entities.CachedClient;
import org.keycloak.models.utils.RoleUtils;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -271,20 +270,8 @@ public class ClientAdapter implements ClientModel, CachedObject {
updated.deleteScopeMapping(role); updated.deleteScopeMapping(role);
} }
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
Set<RoleModel> roleMappings = getScopeMappings(); return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, cachedRealm));
Set<RoleModel> 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 RealmModel getRealm() { public RealmModel getRealm() {
@ -496,9 +483,9 @@ public class ClientAdapter implements ClientModel, CachedObject {
} }
@Override @Override
public List<String> getDefaultRoles() { public Stream<String> getDefaultRolesStream() {
if (isUpdated()) return updated.getDefaultRoles(); if (isUpdated()) return updated.getDefaultRolesStream();
return cached.getDefaultRoles(); return cached.getDefaultRoles().stream();
} }
@Override @Override
@ -662,7 +649,8 @@ public class ClientAdapter implements ClientModel, CachedObject {
if (isUpdated()) return updated.hasScope(role); if (isUpdated()) return updated.hasScope(role);
if (cached.isFullScopeAllowed() || cached.getScope().contains(role.getId())) return true; 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))); return getRolesStream().anyMatch(r -> (Objects.equals(r, role) || r.hasRole(role)));
} }

View file

@ -20,12 +20,11 @@ package org.keycloak.models.cache.infinispan;
import org.keycloak.models.ClientScopeModel; import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.infinispan.entities.CachedClientScope; import org.keycloak.models.cache.infinispan.entities.CachedClientScope;
import org.keycloak.models.utils.RoleUtils;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -173,20 +172,8 @@ public class ClientScopeAdapter implements ClientScopeModel {
updated.deleteScopeMapping(role); updated.deleteScopeMapping(role);
} }
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
Set<RoleModel> roleMappings = getScopeMappings(); return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, cachedRealm));
Set<RoleModel> 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;
} }
@Override @Override
@ -194,12 +181,7 @@ public class ClientScopeAdapter implements ClientScopeModel {
if (isUpdated()) return updated.hasScope(role); if (isUpdated()) return updated.hasScope(role);
if (cached.getScope().contains(role.getId())) return true; if (cached.getScope().contains(role.getId())) return true;
Set<RoleModel> roles = getScopeMappings(); return RoleUtils.hasRole(getScopeMappingsStream(), role);
for (RoleModel mapping : roles) {
if (mapping.hasRole(role)) return true;
}
return false;
} }

View file

@ -21,9 +21,9 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.infinispan.entities.CachedGroup; import org.keycloak.models.cache.infinispan.entities.CachedGroup;
import org.keycloak.models.utils.RoleUtils;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -149,35 +149,15 @@ public class GroupAdapter implements GroupModel {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
if (isUpdated()) return updated.getRealmRoleMappings(); if (isUpdated()) return updated.getRealmRoleMappingsStream();
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
Set<RoleModel> 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;
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
if (isUpdated()) return updated.getClientRoleMappings(app); if (isUpdated()) return updated.getClientRoleMappingsStream(app);
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> 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;
} }
@Override @Override
@ -185,11 +165,7 @@ public class GroupAdapter implements GroupModel {
if (isUpdated()) return updated.hasRole(role); if (isUpdated()) return updated.hasRole(role);
if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true; if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true;
Set<RoleModel> mappings = getRoleMappings(); return getRoleMappingsStream().anyMatch(r -> r.hasRole(role));
for (RoleModel mapping: mappings) {
if (mapping.hasRole(role)) return true;
}
return false;
} }
@Override @Override
@ -199,20 +175,20 @@ public class GroupAdapter implements GroupModel {
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
if (isUpdated()) return updated.getRoleMappings(); if (isUpdated()) return updated.getRoleMappingsStream();
Set<RoleModel> roles = new HashSet<>(); Set<RoleModel> roles = new HashSet<>();
for (String id : cached.getRoleMappings(modelSupplier)) { for (String id : cached.getRoleMappings(modelSupplier)) {
RoleModel roleById = keycloakSession.roles().getRoleById(realm, id); RoleModel roleById = keycloakSession.roles().getRoleById(realm, id);
if (roleById == null) { if (roleById == null) {
// chance that role was removed, so just delegate to persistence and get user invalidated // chance that role was removed, so just delegate to persistence and get user invalidated
getDelegateForUpdate(); getDelegateForUpdate();
return updated.getRoleMappings(); return updated.getRoleMappingsStream();
} }
roles.add(roleById); roles.add(roleById);
} }
return roles; return roles.stream();
} }
@Override @Override

View file

@ -725,9 +725,9 @@ public class RealmAdapter implements CachedRealmModel {
} }
@Override @Override
public List<String> getDefaultRoles() { public Stream<String> getDefaultRolesStream() {
if (isUpdated()) return updated.getDefaultRoles(); if (isUpdated()) return updated.getDefaultRolesStream();
return cached.getDefaultRoles(); return cached.getDefaultRoles().stream();
} }
@Override @Override

View file

@ -26,12 +26,13 @@ import org.keycloak.models.cache.infinispan.entities.CachedRole;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -125,21 +126,22 @@ public class RoleAdapter implements RoleModel {
} }
@Override @Override
public Set<RoleModel> getComposites() { public Stream<RoleModel> getCompositesStream() {
if (isUpdated()) return updated.getComposites(); if (isUpdated()) return updated.getCompositesStream();
if (composites == null) { if (composites == null) {
composites = new HashSet<>(); composites = new HashSet<>();
for (String id : cached.getComposites()) { composites = cached.getComposites().stream()
.map(id -> {
RoleModel role = realm.getRoleById(id); RoleModel role = realm.getRoleById(id);
if (role == null) { if (role == null) {
throw new IllegalStateException("Could not find composite in role " + getName() + ": " + id); throw new IllegalStateException("Could not find composite in role " + getName() + ": " + id);
} }
composites.add(role); return role;
} }).collect(Collectors.toSet());
} }
return composites; return composites.stream();
} }
@Override @Override
@ -201,16 +203,16 @@ public class RoleAdapter implements RoleModel {
} }
@Override @Override
public List<String> getAttribute(String name) { public Stream<String> getAttributeStream(String name) {
if (updated != null) { if (updated != null) {
return updated.getAttribute(name); return updated.getAttributeStream(name);
} }
List<String> result = cached.getAttributes(modelSupplier).get(name); List<String> result = cached.getAttributes(modelSupplier).get(name);
if (result == null) { if (result == null) {
result = Collections.emptyList(); return Stream.empty();
} }
return result; return result.stream();
} }
@Override @Override

View file

@ -21,7 +21,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.cache.CachedUserModel; import org.keycloak.models.cache.CachedUserModel;
@ -276,35 +275,15 @@ public class UserAdapter implements CachedUserModel {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
if (updated != null) return updated.getRealmRoleMappings(); if (updated != null) return updated.getRealmRoleMappingsStream();
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
Set<RoleModel> 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;
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
if (updated != null) return updated.getClientRoleMappings(app); if (updated != null) return updated.getClientRoleMappingsStream(app);
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> 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;
} }
@Override @Override
@ -312,11 +291,8 @@ public class UserAdapter implements CachedUserModel {
if (updated != null) return updated.hasRole(role); if (updated != null) return updated.hasRole(role);
if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true; if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true;
Set<RoleModel> mappings = getRoleMappings(); return getRoleMappingsStream().anyMatch(r -> r.hasRole(role)) ?
for (RoleModel mapping: mappings) { true : RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
if (mapping.hasRole(role)) return true;
}
return RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
} }
@Override @Override
@ -326,20 +302,20 @@ public class UserAdapter implements CachedUserModel {
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
if (updated != null) return updated.getRoleMappings(); if (updated != null) return updated.getRoleMappingsStream();
Set<RoleModel> roles = new HashSet<>(); Set<RoleModel> roles = new HashSet<>();
for (String id : cached.getRoleMappings(modelSupplier)) { for (String id : cached.getRoleMappings(modelSupplier)) {
RoleModel roleById = keycloakSession.roles().getRoleById(realm, id); RoleModel roleById = keycloakSession.roles().getRoleById(realm, id);
if (roleById == null) { if (roleById == null) {
// chance that role was removed, so just delete to persistence and get user invalidated // chance that role was removed, so just delete to persistence and get user invalidated
getDelegateForUpdate(); getDelegateForUpdate();
return updated.getRoleMappings(); return updated.getRoleMappingsStream();
} }
roles.add(roleById); roles.add(roleById);
} }
return roles; return roles.stream();
} }
@Override @Override

View file

@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -92,9 +93,7 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
fullScopeAllowed = model.isFullScopeAllowed(); fullScopeAllowed = model.isFullScopeAllowed();
redirectUris.addAll(model.getRedirectUris()); redirectUris.addAll(model.getRedirectUris());
webOrigins.addAll(model.getWebOrigins()); webOrigins.addAll(model.getWebOrigins());
for (RoleModel role : model.getScopeMappings()) { scope.addAll(model.getScopeMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()));
scope.add(role.getId());
}
for (ProtocolMapperModel mapper : model.getProtocolMappers()) { for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper); this.protocolMappers.add(mapper);
} }
@ -102,7 +101,7 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
managementUrl = model.getManagementUrl(); managementUrl = model.getManagementUrl();
rootUrl = model.getRootUrl(); rootUrl = model.getRootUrl();
baseUrl = model.getBaseUrl(); baseUrl = model.getBaseUrl();
defaultRoles.addAll(model.getDefaultRoles()); defaultRoles.addAll(model.getDefaultRolesStream().collect(Collectors.toList()));
bearerOnly = model.isBearerOnly(); bearerOnly = model.isBearerOnly();
consentRequired = model.isConsentRequired(); consentRequired = model.isConsentRequired();
standardFlowEnabled = model.isStandardFlowEnabled(); standardFlowEnabled = model.isStandardFlowEnabled();

View file

@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -50,9 +51,7 @@ public class CachedClientScope extends AbstractRevisioned implements InRealm {
for (ProtocolMapperModel mapper : model.getProtocolMappers()) { for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper); this.protocolMappers.add(mapper);
} }
for (RoleModel role : model.getScopeMappings()) { scope.addAll(model.getScopeMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()));
scope.add(role.getId());
}
attributes.putAll(model.getAttributes()); attributes.putAll(model.getAttributes());
} }

View file

@ -48,7 +48,7 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
this.name = group.getName(); this.name = group.getName();
this.parentId = group.getParentId(); this.parentId = group.getParentId();
this.attributes = new DefaultLazyLoader<>(source -> new MultivaluedHashMap<>(source.getAttributes()), MultivaluedHashMap::new); 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); this.subGroups = new DefaultLazyLoader<>(source -> source.getSubGroupsStream().map(GroupModel::getId).collect(Collectors.toSet()), Collections::emptySet);
} }

View file

@ -252,7 +252,7 @@ public class CachedRealm extends AbstractExtendableRevisioned {
adminEventsEnabled = model.isAdminEventsEnabled(); adminEventsEnabled = model.isAdminEventsEnabled();
adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled(); adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled();
defaultRoles = model.getDefaultRoles(); defaultRoles = model.getDefaultRolesStream().collect(Collectors.toList());
ClientModel masterAdminClient = model.getMasterAdminClient(); ClientModel masterAdminClient = model.getMasterAdminClient();
this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null; this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null;

View file

@ -26,6 +26,7 @@ import org.keycloak.models.cache.infinispan.LazyLoader;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -47,9 +48,7 @@ public class CachedRole extends AbstractRevisioned implements InRealm {
name = model.getName(); name = model.getName();
this.realm = realm.getId(); this.realm = realm.getId();
if (composite) { if (composite) {
for (RoleModel child : model.getComposites()) { composites.addAll(model.getCompositesStream().map(RoleModel::getId).collect(Collectors.toSet()));
composites.add(child.getId());
}
} }
attributes = new DefaultLazyLoader<>(roleModel -> new MultivaluedHashMap<>(roleModel.getAttributes()), MultivaluedHashMap::new); attributes = new DefaultLazyLoader<>(roleModel -> new MultivaluedHashMap<>(roleModel.getAttributes()), MultivaluedHashMap::new);
} }

View file

@ -64,7 +64,7 @@ public class CachedUser extends AbstractExtendableRevisioned implements InRealm
this.notBefore = notBefore; this.notBefore = notBefore;
this.requiredActions = new DefaultLazyLoader<>(UserModel::getRequiredActions, Collections::emptySet); this.requiredActions = new DefaultLazyLoader<>(UserModel::getRequiredActions, Collections::emptySet);
this.attributes = new DefaultLazyLoader<>(userModel -> new MultivaluedHashMap<>(userModel.getAttributes()), MultivaluedHashMap::new); 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); this.groups = new DefaultLazyLoader<>(userModel -> userModel.getGroupsStream().map(GroupModel::getId).collect(Collectors.toCollection(LinkedHashSet::new)), LinkedHashSet::new);
} }

View file

@ -23,7 +23,6 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientAttributeEntity; import org.keycloak.models.jpa.entities.ClientAttributeEntity;
import org.keycloak.models.jpa.entities.ClientEntity; 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.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RoleEntity; import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.RoleUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
@ -46,7 +46,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -239,20 +238,8 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
} }
@Override @Override
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
Set<RoleModel> roleMappings = getScopeMappings(); return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
Set<RoleModel> 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;
} }
@Override @Override
@ -690,24 +677,17 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
public boolean hasScope(RoleModel role) { public boolean hasScope(RoleModel role) {
if (isFullScopeAllowed()) return true; if (isFullScopeAllowed()) return true;
Predicate<RoleModel> hasRoleOrEquals = r -> (Objects.equals(r, role) || r.hasRole(role)); if (RoleUtils.hasRole(getScopeMappingsStream(), role))
if (getScopeMappingsStream().anyMatch(hasRoleOrEquals)) {
return true; return true;
}
return getRolesStream().anyMatch(hasRoleOrEquals); return RoleUtils.hasRole(getRolesStream(), role);
} }
@Override @Override
public List<String> getDefaultRoles() { public Stream<String> getDefaultRolesStream() {
Collection<RoleEntity> entities = entity.getDefaultRoles(); Collection<RoleEntity> entities = entity.getDefaultRoles();
List<String> roles = new ArrayList<String>(); if (entities == null) return Stream.empty();
if (entities == null) return roles; return entities.stream().map(RoleEntity::getName);
for (RoleEntity entity : entities) {
roles.add(entity.getName());
}
return roles;
} }
@Override @Override

View file

@ -22,13 +22,13 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientScopeAttributeEntity; import org.keycloak.models.jpa.entities.ClientScopeAttributeEntity;
import org.keycloak.models.jpa.entities.ClientScopeEntity; import org.keycloak.models.jpa.entities.ClientScopeEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity; import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RoleEntity; import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.RoleUtils;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import java.util.HashMap; import java.util.HashMap;
@ -210,20 +210,8 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
} }
@Override @Override
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
Set<RoleModel> roleMappings = getScopeMappings(); return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
Set<RoleModel> 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;
} }
@Override @Override
@ -247,13 +235,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
@Override @Override
public boolean hasScope(RoleModel role) { public boolean hasScope(RoleModel role) {
Set<RoleModel> roles = getScopeMappings(); return RoleUtils.hasRole(getScopeMappingsStream(), role);
if (roles.contains(role)) return true;
for (RoleModel mapping : roles) {
if (mapping.hasRole(role)) return true;
}
return false;
} }
@Override @Override

View file

@ -21,7 +21,6 @@ import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.GroupAttributeEntity; import org.keycloak.models.jpa.entities.GroupAttributeEntity;
import org.keycloak.models.jpa.entities.GroupEntity; import org.keycloak.models.jpa.entities.GroupEntity;
@ -217,8 +216,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
@Override @Override
public boolean hasRole(RoleModel role) { public boolean hasRole(RoleModel role) {
Set<RoleModel> roles = getRoleMappings(); return RoleUtils.hasRole(getRoleMappingsStream(), role);
return RoleUtils.hasRole(roles, role);
} }
protected TypedQuery<GroupRoleMappingEntity> getGroupRoleMappingEntityTypedQuery(RoleModel role) { protected TypedQuery<GroupRoleMappingEntity> getGroupRoleMappingEntityTypedQuery(RoleModel role) {
@ -240,34 +238,18 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
Set<RoleModel> realmRoles = new HashSet<RoleModel>();
for (RoleModel role : roleMappings) {
RoleContainerModel container = role.getContainer();
if (container instanceof RealmModel) {
realmRoles.add(role);
}
}
return realmRoles;
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
// we query ids only as the role might be cached and following the @ManyToOne will result in a load // 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. // even if we're getting just the id.
TypedQuery<String> query = em.createNamedQuery("groupRoleMappingIds", String.class); TypedQuery<String> query = em.createNamedQuery("groupRoleMappingIds", String.class);
query.setParameter("group", getEntity()); query.setParameter("group", getEntity());
List<String> ids = query.getResultList(); return closing(query.getResultStream().map(realm::getRoleById).filter(Objects::nonNull));
Set<RoleModel> roles = new HashSet<RoleModel>();
for (String roleId : ids) {
RoleModel roleById = realm.getRoleById(roleId);
if (roleById == null) continue;
roles.add(roleById);
}
return roles;
} }
@Override @Override
@ -285,20 +267,8 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> roles = new HashSet<RoleModel>();
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;
} }
@Override @Override

View file

@ -340,7 +340,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
} }
session.users().preRemove(realm, role); session.users().preRemove(realm, role);
RoleContainerModel container = role.getContainer(); RoleContainerModel container = role.getContainer();
if (container.getDefaultRoles().contains(role.getName())) { if (container.getDefaultRolesStream().anyMatch(r -> Objects.equals(r, role.getName()))) {
container.removeDefaultRoles(role.getName()); container.removeDefaultRoles(role.getName());
} }
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId()); RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());

View file

@ -718,14 +718,10 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
@Override @Override
public List<String> getDefaultRoles() { public Stream<String> getDefaultRolesStream() {
Collection<RoleEntity> entities = realm.getDefaultRoles(); Collection<RoleEntity> entities = realm.getDefaultRoles();
if (entities == null || entities.isEmpty()) return Collections.emptyList(); if (entities == null || entities.isEmpty()) return Stream.empty();
List<String> roles = new LinkedList<>(); return entities.stream().map(RoleEntity::getName);
for (RoleEntity entity : entities) {
roles.add(entity.getName());
}
return Collections.unmodifiableList(roles);
} }
@Override @Override

View file

@ -34,7 +34,8 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Objects;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -88,7 +89,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
@Override @Override
public boolean isComposite() { public boolean isComposite() {
return getComposites().size() > 0; return getCompositesStream().count() > 0;
} }
@Override @Override
@ -107,16 +108,8 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
} }
@Override @Override
public Set<RoleModel> getComposites() { public Stream<RoleModel> getCompositesStream() {
Set<RoleModel> set = new HashSet<RoleModel>(); return getEntity().getCompositeRoles().stream().map(c -> new RoleAdapter(session, realm, em, c));
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;
} }
@Override @Override
@ -175,14 +168,10 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
} }
@Override @Override
public List<String> getAttribute(String name) { public Stream<String> getAttributeStream(String name) {
List<String> attributes = new ArrayList<>(); return role.getAttributes().stream()
for (RoleAttributeEntity attribute : role.getAttributes()) { .filter(a -> Objects.equals(a.getName(), name))
if (attribute.getName().equals(name)) { .map(RoleAttributeEntity::getValue);
attributes.add(attribute.getValue());
}
}
return attributes;
} }
@Override @Override

View file

@ -22,7 +22,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.GroupEntity; import org.keycloak.models.jpa.entities.GroupEntity;
@ -472,8 +471,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
@Override @Override
public boolean hasRole(RoleModel role) { public boolean hasRole(RoleModel role) {
Set<RoleModel> roles = getRoleMappings(); return RoleUtils.hasRole(getRoleMappingsStream(), role)
return RoleUtils.hasRole(roles, role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
} }
@ -500,34 +498,18 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
Set<RoleModel> realmRoles = new HashSet<RoleModel>();
for (RoleModel role : roleMappings) {
RoleContainerModel container = role.getContainer();
if (container instanceof RealmModel) {
realmRoles.add(role);
}
}
return realmRoles;
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
// we query ids only as the role might be cached and following the @ManyToOne will result in a load // 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. // even if we're getting just the id.
TypedQuery<String> query = em.createNamedQuery("userRoleMappingIds", String.class); TypedQuery<String> query = em.createNamedQuery("userRoleMappingIds", String.class);
query.setParameter("user", getEntity()); query.setParameter("user", getEntity());
List<String> ids = query.getResultList(); return closing(query.getResultStream().map(realm::getRoleById).filter(Objects::nonNull));
Set<RoleModel> roles = new HashSet<RoleModel>();
for (String roleId : ids) {
RoleModel roleById = realm.getRoleById(roleId);
if (roleById == null) continue;
roles.add(roleById);
}
return roles;
} }
@Override @Override
@ -545,20 +527,8 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> roles = new HashSet<RoleModel>();
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;
} }
@Override @Override

View file

@ -544,17 +544,10 @@ public class JpaUserFederatedStorageProvider implements
} }
@Override @Override
public Set<RoleModel> getRoleMappings(RealmModel realm, String userId) { public Stream<RoleModel> getRoleMappingsStream(RealmModel realm, String userId) {
Set<RoleModel> set = new HashSet<>();
TypedQuery<FederatedUserRoleMappingEntity> query = em.createNamedQuery("feduserRoleMappings", FederatedUserRoleMappingEntity.class); TypedQuery<FederatedUserRoleMappingEntity> query = em.createNamedQuery("feduserRoleMappings", FederatedUserRoleMappingEntity.class);
query.setParameter("userId", userId); query.setParameter("userId", userId);
List<FederatedUserRoleMappingEntity> results = query.getResultList(); return closing(query.getResultStream().map(FederatedUserRoleMappingEntity::getRoleId).map(realm::getRoleById));
if (results.size() == 0) return set;
for (FederatedUserRoleMappingEntity entity : results) {
RoleModel role = realm.getRoleById(entity.getRoleId());
set.add(role);
}
return set;
} }
@Override @Override

View file

@ -22,9 +22,10 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.map.common.AbstractEntity; import org.keycloak.models.map.common.AbstractEntity;
import org.keycloak.models.utils.RoleUtils;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -54,11 +55,8 @@ public abstract class AbstractClientModel<E extends AbstractEntity> implements C
} }
@Override @Override
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
String realmId = realm.getId(); return getScopeMappingsStream().filter(r -> RoleUtils.isRealmRole(r, realm));
return getScopeMappingsStream()
.filter(rm -> Objects.equals(rm.getContainerId(), realmId))
.collect(Collectors.toSet());
} }
@Override @Override

View file

@ -457,8 +457,8 @@ public abstract class MapClientAdapter extends AbstractClientModel<MapClientEnti
/*************** Default roles ****************/ /*************** Default roles ****************/
@Override @Override
public List<String> getDefaultRoles() { public Stream<String> getDefaultRolesStream() {
return entity.getDefaultRoles(); return entity.getDefaultRoles().stream();
} }
@Override @Override

View file

@ -18,13 +18,10 @@
package org.keycloak.authorization.policy.evaluation; package org.keycloak.authorization.policy.evaluation;
import java.util.Collections; import java.util.*;
import java.util.HashMap; import java.util.function.Predicate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.Decision; import org.keycloak.authorization.Decision;
@ -52,7 +49,7 @@ public class DefaultEvaluation implements Evaluation {
private Policy policy; private Policy policy;
private final Policy parentPolicy; private final Policy parentPolicy;
private final AuthorizationProvider authorizationProvider; private final AuthorizationProvider authorizationProvider;
private Map<Policy, Map<Object, Effect>> decisionCache; private final Map<Policy, Map<Object, Effect>> decisionCache;
private final Realm realm; private final Realm realm;
private Effect effect; private Effect effect;
@ -192,9 +189,7 @@ public class DefaultEvaluation implements Evaluation {
return false; return false;
} }
Set<RoleModel> roleMappings = user.getRoleMappings().stream() Stream<RoleModel> roleMappings = user.getRoleMappingsStream().filter(isNotClientRole);
.filter(role -> !role.isClientRole())
.collect(Collectors.toSet());
return RoleUtils.hasRole(roleMappings, session.getContext().getRealm().getRole(roleName)); return RoleUtils.hasRole(roleMappings, session.getContext().getRealm().getRole(roleName));
} }
@ -209,15 +204,16 @@ public class DefaultEvaluation implements Evaluation {
return false; return false;
} }
Set<RoleModel> roleMappings = user.getRoleMappings().stream() Set<RoleModel> roleMappings = user.getRoleMappingsStream()
.filter(role -> role.isClientRole() && ClientModel.class.cast(role.getContainer()).getClientId().equals(clientId)) .filter(RoleModel::isClientRole)
.filter(role -> Objects.equals(((ClientModel) role.getContainer()).getClientId(), clientId))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
if (roleMappings.isEmpty()) { if (roleMappings.isEmpty()) {
return false; 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)) { if (Objects.isNull(role)) {
return false; return false;
@ -237,16 +233,16 @@ public class DefaultEvaluation implements Evaluation {
@Override @Override
public List<String> getUserRealmRoles(String id) { public List<String> getUserRealmRoles(String id) {
return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappings().stream() return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappingsStream()
.filter(role -> !role.isClientRole()) .filter(isNotClientRole)
.map(RoleModel::getName) .map(RoleModel::getName)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
public List<String> getUserClientRoles(String id, String clientId) { public List<String> getUserClientRoles(String id, String clientId) {
return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappings().stream() return getUser(id, authorizationProvider.getKeycloakSession()).getRoleMappingsStream()
.filter(role -> role.isClientRole()) .filter(RoleModel::isClientRole)
.map(RoleModel::getName) .map(RoleModel::getName)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -274,4 +270,6 @@ public class DefaultEvaluation implements Evaluation {
this.effect = effect; this.effect = effect;
this.decision.onDecision(this); this.decision.onDecision(this);
} }
private Predicate<RoleModel> isNotClientRole = ((Predicate<RoleModel>) RoleModel::isClientRole).negate();
} }

View file

@ -23,16 +23,8 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RealmRepresentation; 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 <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a> * @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>
*/ */
@ -65,10 +57,7 @@ public class MigrateTo3_4_2 implements Migration {
private void clearScope(ClientModel cli) { private void clearScope(ClientModel cli) {
if (cli.isFullScopeAllowed()) cli.setFullScopeAllowed(false); if (cli.isFullScopeAllowed()) cli.setFullScopeAllowed(false);
Set<RoleModel> scope = cli.getScopeMappings(); cli.getScopeMappingsStream().forEach(cli::deleteScopeMapping);
if (scope.size() > 0) {
for (RoleModel role : scope) cli.deleteScopeMapping(role);
}
} }
@Override @Override

View file

@ -191,12 +191,9 @@ public final class KeycloakModelUtils {
return false; return false;
} }
Set<RoleModel> compositeRoles = composite.getComposites(); Set<RoleModel> compositeRoles = composite.getCompositesStream().collect(Collectors.toSet());
return compositeRoles.contains(role) || return compositeRoles.contains(role) ||
compositeRoles.stream() compositeRoles.stream().anyMatch(x -> x.isComposite() && searchFor(role, x, visited));
.filter(x -> x.isComposite() && searchFor(role, x, visited))
.findFirst()
.isPresent();
} }
/** /**
@ -510,19 +507,21 @@ public final class KeycloakModelUtils {
}).filter(Objects::nonNull).findFirst().orElse(null); }).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<RoleModel> getClientScopeMappings(ClientModel client, ScopeContainerModel container) { public static Set<RoleModel> getClientScopeMappings(ClientModel client, ScopeContainerModel container) {
Set<RoleModel> mappings = container.getScopeMappings(); return getClientScopeMappingsStream(client, container).collect(Collectors.toSet());
Set<RoleModel> 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);
} }
} public static Stream<RoleModel> getClientScopeMappingsStream(ClientModel client, ScopeContainerModel container) {
} return container.getScopeMappingsStream()
return result; .filter(role -> role.getContainer() instanceof ClientModel &&
Objects.equals(client.getId(), role.getContainer().getId()));
} }
// Used in various role mappers // Used in various role mappers

View file

@ -119,7 +119,7 @@ public class ModelToRepresentation {
rep.setPath(buildGroupPath(group)); rep.setPath(buildGroupPath(group));
if (!full) return rep; if (!full) return rep;
// Role mappings // Role mappings
Set<RoleModel> roles = group.getRoleMappings(); Set<RoleModel> roles = group.getRoleMappingsStream().collect(Collectors.toSet());
List<String> realmRoleNames = new ArrayList<>(); List<String> realmRoleNames = new ArrayList<>();
Map<String, List<String>> clientRoleNames = new HashMap<>(); Map<String, List<String>> clientRoleNames = new HashMap<>();
for (RoleModel role : roles) { for (RoleModel role : roles) {
@ -409,10 +409,9 @@ public class ModelToRepresentation {
if (realm.getClientAuthenticationFlow() != null) rep.setClientAuthenticationFlow(realm.getClientAuthenticationFlow().getAlias()); if (realm.getClientAuthenticationFlow() != null) rep.setClientAuthenticationFlow(realm.getClientAuthenticationFlow().getAlias());
if (realm.getDockerAuthenticationFlow() != null) rep.setDockerAuthenticationFlow(realm.getDockerAuthenticationFlow().getAlias()); if (realm.getDockerAuthenticationFlow() != null) rep.setDockerAuthenticationFlow(realm.getDockerAuthenticationFlow().getAlias());
List<String> defaultRoles = realm.getDefaultRoles(); List<String> defaultRoles = realm.getDefaultRolesStream().collect(Collectors.toList());
if (!defaultRoles.isEmpty()) { if (!defaultRoles.isEmpty()) {
List<String> roleStrings = new ArrayList<>(defaultRoles); rep.setDefaultRoles(defaultRoles);
rep.setDefaultRoles(roleStrings);
} }
List<String> defaultGroups = realm.getDefaultGroupsStream() List<String> defaultGroups = realm.getDefaultGroupsStream()
.map(ModelToRepresentation::buildGroupPath).collect(Collectors.toList()); .map(ModelToRepresentation::buildGroupPath).collect(Collectors.toList());
@ -650,8 +649,9 @@ public class ModelToRepresentation {
rep.setWebOrigins(new LinkedList<>(webOrigins)); rep.setWebOrigins(new LinkedList<>(webOrigins));
} }
if (!clientModel.getDefaultRoles().isEmpty()) { String[] defaultRoles = clientModel.getDefaultRolesStream().toArray(String[]::new);
rep.setDefaultRoles(clientModel.getDefaultRoles().toArray(new String[0])); if (defaultRoles.length > 0) {
rep.setDefaultRoles(defaultRoles);
} }
if (!clientModel.getRegisteredNodes().isEmpty()) { if (!clientModel.getRegisteredNodes().isEmpty()) {

View file

@ -260,36 +260,18 @@ public class InMemoryUserAdapter extends UserModelDefaultMethods {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> allRoles = getRoleMappings(); return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
// Filter to retrieve just realm roles
Set<RoleModel> realmRoles = new HashSet<>();
for (RoleModel role : allRoles) {
if (role.getContainer() instanceof RealmModel) {
realmRoles.add(role);
}
}
return realmRoles;
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> result = new HashSet<>(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> roles = getRoleMappings();
for (RoleModel role : roles) {
if (app.equals(role.getContainer())) {
result.add(role);
}
}
return result;
} }
@Override @Override
public boolean hasRole(RoleModel role) { public boolean hasRole(RoleModel role) {
Set<RoleModel> roles = getRoleMappings(); return RoleUtils.hasRole(getRoleMappingsStream(), role)
return RoleUtils.hasRole(roles, role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
} }
@ -300,13 +282,8 @@ public class InMemoryUserAdapter extends UserModelDefaultMethods {
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
if (roleIds.isEmpty()) return new HashSet<>(); return roleIds.stream().map(realm::getRoleById);
Set<RoleModel> roles = new HashSet<>();
for (String id : roleIds) {
roles.add(realm.getRoleById(id));
}
return roles;
} }
@Override @Override

View file

@ -20,8 +20,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.ModelException; import org.keycloak.models.ModelException;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -67,8 +65,8 @@ public abstract class UnsupportedOperationsClientStorageAdapter implements Clien
} }
@Override @Override
public final List<String> getDefaultRoles() { public final Stream<String> getDefaultRolesStream() {
return Collections.EMPTY_LIST; return Stream.empty();
} }
@Override @Override

View file

@ -18,6 +18,8 @@
package org.keycloak.models; package org.keycloak.models;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* Request-scoped context object * Request-scoped context object
@ -35,7 +37,12 @@ public interface ClientSessionContext {
/** /**
* @return expanded roles (composite roles already applied) * @return expanded roles (composite roles already applied)
*/ */
Set<RoleModel> getRoles(); @Deprecated
default Set<RoleModel> getRoles() {
return getRolesStream().collect(Collectors.toSet());
}
Stream<RoleModel> getRolesStream();
Set<ProtocolMapperModel> getProtocolMappers(); Set<ProtocolMapperModel> getProtocolMappers();

View file

@ -70,13 +70,18 @@ public interface RoleContainerModel {
Stream<RoleModel> searchForRolesStream(String search, Integer first, Integer max); Stream<RoleModel> searchForRolesStream(String search, Integer first, Integer max);
List<String> getDefaultRoles(); @Deprecated
default List<String> getDefaultRoles() {
return getDefaultRolesStream().collect(Collectors.toList());
}
Stream<String> getDefaultRolesStream();
void addDefaultRole(String name); void addDefaultRole(String name);
default void updateDefaultRoles(String... defaultRoles) { default void updateDefaultRoles(String... defaultRoles) {
List<String> defaultRolesArray = Arrays.asList(defaultRoles); List<String> defaultRolesArray = Arrays.asList(defaultRoles);
Collection<String> entities = getDefaultRoles(); Collection<String> entities = getDefaultRolesStream().collect(Collectors.toList());
Set<String> already = new HashSet<>(); Set<String> already = new HashSet<>();
ArrayList<String> remove = new ArrayList<>(); ArrayList<String> remove = new ArrayList<>();
for (String rel : entities) { for (String rel : entities) {

View file

@ -18,6 +18,8 @@
package org.keycloak.models; package org.keycloak.models;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -27,15 +29,36 @@ public interface RoleMapperModel {
/** /**
* Returns set of realm roles that are directly set to this object. * Returns set of realm roles that are directly set to this object.
* @return see description * @return see description
* @deprecated Use {@link #getRealmRoleMappingsStream()} getRealmRoleMappingsStream} instead.
*/ */
Set<RoleModel> getRealmRoleMappings(); @Deprecated
default Set<RoleModel> getRealmRoleMappings() {
return getRealmRoleMappingsStream().collect(Collectors.toSet());
}
/**
* Returns stream of realm roles that are directly set to this object.
* @return stream of {@link RoleModel}
*/
Stream<RoleModel> getRealmRoleMappingsStream();
/** /**
* Returns set of client roles that are directly set to this object for the given client. * Returns set of client roles that are directly set to this object for the given client.
* @param app Client to get the roles for * @param app Client to get the roles for
* @return see description * @return see description
* @deprecated Use {@link #getClientRoleMappingsStream(ClientModel)} getClientRoleMappingsStream} instead.
*/ */
Set<RoleModel> getClientRoleMappings(ClientModel app); @Deprecated
default Set<RoleModel> 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<RoleModel> getClientRoleMappingsStream(ClientModel app);
/** /**
* Returns {@code true} if this object is directly or indirectly assigned the given role, {@code false} otherwise. * 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. * Returns set of all role (both realm all client) that are directly set to this object.
* @return * @return
* @deprecated Use {@link #getRoleMappingsStream()} getRoleMappingsStream} instead.
*/ */
Set<RoleModel> getRoleMappings(); @Deprecated
default Set<RoleModel> 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<RoleModel> getRoleMappingsStream();
/** /**
* Removes the given role mapping from this object. * Removes the given role mapping from this object.

View file

@ -21,6 +21,8 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -43,7 +45,12 @@ public interface RoleModel {
void removeCompositeRole(RoleModel role); void removeCompositeRole(RoleModel role);
Set<RoleModel> getComposites(); @Deprecated
default Set<RoleModel> getComposites() {
return getCompositesStream().collect(Collectors.toSet());
}
Stream<RoleModel> getCompositesStream();
boolean isClientRole(); boolean isClientRole();
@ -61,7 +68,12 @@ public interface RoleModel {
String getFirstAttribute(String name); String getFirstAttribute(String name);
List<String> getAttribute(String name); @Deprecated
default List<String> getAttribute(String name) {
return getAttributeStream(name).collect(Collectors.toList());
}
Stream<String> getAttributeStream(String name);
Map<String, List<String>> getAttributes(); Map<String, List<String>> getAttributes();
} }

View file

@ -37,9 +37,20 @@ public interface ScopeContainerModel {
/** /**
* From the scope mappings returned by {@link #getScopeMappings()} returns only those * From the scope mappings returned by {@link #getScopeMappings()} returns only those
* that belong to the realm that owns this scope container. * that belong to the realm that owns this scope container.
* @return * @return set of {@link RealmModel}
* @deprecated Use {@link #getRealmScopeMappingsStream()} getRealmScopeMappingsStream} instead.
*/ */
Set<RoleModel> getRealmScopeMappings(); @Deprecated
default Set<RoleModel> 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<RoleModel> getRealmScopeMappingsStream();
void addScopeMapping(RoleModel role); void addScopeMapping(RoleModel role);

View file

@ -21,11 +21,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; 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; import java.util.stream.Stream;
/** /**
@ -33,20 +28,16 @@ import java.util.stream.Stream;
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class DefaultRoles { public class DefaultRoles {
public static Set<RoleModel> getDefaultRoles(RealmModel realm) { public static Stream<RoleModel> getDefaultRoles(RealmModel realm) {
Set<RoleModel> set = new HashSet<>(); Stream<RoleModel> realmDefaultRoles = realm.getDefaultRolesStream().map(realm::getRole);
for (String r : realm.getDefaultRoles()) { Stream<RoleModel> clientDefaultRoles = realm.getClientsStream().flatMap(DefaultRoles::toClientDefaultRoles);
set.add(realm.getRole(r)); return Stream.concat(realmDefaultRoles, clientDefaultRoles);
}
Function<ClientModel, Set<RoleModel>> defaultRoles = i -> i.getDefaultRoles().stream().map(i::getRole).collect(Collectors.toSet());
realm.getClientsStream().map(defaultRoles).forEach(set::addAll);
return set;
} }
public static void addDefaultRoles(RealmModel realm, UserModel userModel) { public static void addDefaultRoles(RealmModel realm, UserModel userModel) {
for (RoleModel role : getDefaultRoles(realm)) { getDefaultRoles(realm).forEach(userModel::grantRole);
userModel.grantRole(role);
} }
private static Stream<RoleModel> toClientDefaultRoles(ClientModel c) {
return c.getDefaultRolesStream().map(c::getRole);
} }
} }

View file

@ -17,13 +17,17 @@
package org.keycloak.models.utils; package org.keycloak.models.utils;
import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -90,6 +94,15 @@ public class RoleUtils {
return false; return false;
} }
/**
* @param roles
* @param targetRole
* @return true if targetRole is in roles (directly or indirectly via composite role)
*/
public static boolean hasRole(Stream<RoleModel> 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 * Checks whether the {@code targetRole} is contained in the given group or its parents
* (if requested) * (if requested)
@ -163,7 +176,7 @@ public class RoleUtils {
sb.add(current); sb.add(current);
if (current.isComposite()) { if (current.isComposite()) {
current.getComposites().stream() current.getCompositesStream()
.filter(r -> !visited.contains(r)) .filter(r -> !visited.contains(r))
.forEach(r -> { .forEach(r -> {
visited.add(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 * @return all user role mappings including all groups of user. Composite roles will be expanded
*/ */
public static Set<RoleModel> getDeepUserRoleMappings(UserModel user) { public static Set<RoleModel> getDeepUserRoleMappings(UserModel user) {
Set<RoleModel> roleMappings = new HashSet<>(user.getRoleMappings()); Set<RoleModel> roleMappings = user.getRoleMappingsStream().collect(Collectors.toSet());
user.getGroupsStream().forEach(group -> addGroupRoles(group, roleMappings)); user.getGroupsStream().forEach(group -> addGroupRoles(group, roleMappings));
return expandCompositeRoles(roleMappings); return expandCompositeRoles(roleMappings);
} }
private static void addGroupRoles(GroupModel group, Set<RoleModel> roleMappings) { private static void addGroupRoles(GroupModel group, Set<RoleModel> roleMappings) {
roleMappings.addAll(group.getRoleMappings()); roleMappings.addAll(group.getRoleMappingsStream().collect(Collectors.toSet()));
if (group.getParentId() == null) return; if (group.getParentId() == null) return;
addGroupRoles(group.getParent(), roleMappings); 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;
}
} }

View file

@ -161,13 +161,13 @@ public class UserModelDelegate implements UserModel {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
return delegate.getRealmRoleMappings(); return delegate.getRealmRoleMappingsStream();
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
return delegate.getClientRoleMappings(app); return delegate.getClientRoleMappingsStream(app);
} }
@Override @Override
@ -181,8 +181,8 @@ public class UserModelDelegate implements UserModel {
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
return delegate.getRoleMappings(); return delegate.getRoleMappingsStream();
} }
@Override @Override

View file

@ -22,7 +22,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserModelDefaultMethods; import org.keycloak.models.UserModelDefaultMethods;
@ -135,40 +134,18 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
Set<RoleModel> realmRoles = new HashSet<>();
for (RoleModel role : roleMappings) {
RoleContainerModel container = role.getContainer();
if (container instanceof RealmModel) {
realmRoles.add(role);
}
}
return realmRoles;
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> 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;
} }
@Override @Override
public boolean hasRole(RoleModel role) { public boolean hasRole(RoleModel role) {
Set<RoleModel> roles = getRoleMappings(); return RoleUtils.hasRole(getRoleMappingsStream(), role)
return RoleUtils.hasRole(roles, role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
} }
@ -189,16 +166,15 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
return true; return true;
} }
protected Set<RoleModel> getRoleMappingsInternal() { protected Stream<RoleModel> getRoleMappingsInternal() {
return Collections.emptySet(); return Stream.empty();
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
Set<RoleModel> set = new HashSet<>(); Stream<RoleModel> roleMappings = getRoleMappingsInternal();
if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm)); if (appendDefaultRolesToRoleMappings()) return Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
set.addAll(getRoleMappingsInternal()); return roleMappings;
return set;
} }

View file

@ -22,7 +22,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserModelDefaultMethods; import org.keycloak.models.UserModelDefaultMethods;
@ -160,17 +159,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
* @return * @return
*/ */
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
Set<RoleModel> realmRoles = new HashSet<>();
for (RoleModel role : roleMappings) {
RoleContainerModel container = role.getContainer();
if (container instanceof RealmModel) {
realmRoles.add(role);
}
}
return realmRoles;
} }
/** /**
@ -182,26 +172,13 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
* @return * @return
*/ */
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> roleMappings = getRoleMappings(); return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
Set<RoleModel> 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;
} }
@Override @Override
public boolean hasRole(RoleModel role) { public boolean hasRole(RoleModel role) {
Set<RoleModel> roles = getRoleMappings(); return RoleUtils.hasRole(getRoleMappingsStream(), role)
return RoleUtils.hasRole(roles, role)
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true); || RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
} }
@ -222,8 +199,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
return true; return true;
} }
protected Set<RoleModel> getRoleMappingsInternal() { protected Stream<RoleModel> getRoleMappingsInternal() {
return Collections.emptySet(); return Stream.empty();
} }
/** /**
@ -234,15 +211,14 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
* @return * @return
*/ */
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
Set<RoleModel> set = new HashSet<>(getFederatedRoleMappings()); Stream<RoleModel> roleMappings = getFederatedRoleMappings();
if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm)); if (appendDefaultRolesToRoleMappings()) roleMappings = Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
set.addAll(getRoleMappingsInternal()); return Stream.concat(roleMappings, getRoleMappingsInternal());
return set;
} }
protected Set<RoleModel> getFederatedRoleMappings() { protected Stream<RoleModel> getFederatedRoleMappings() {
return getFederatedStorage().getRoleMappings(realm, this.getId()); return getFederatedStorage().getRoleMappingsStream(realm, this.getId());
} }
@Override @Override

View file

@ -20,6 +20,8 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -29,7 +31,12 @@ public interface UserRoleMappingsFederatedStorage {
void grantRole(RealmModel realm, String userId, RoleModel role); void grantRole(RealmModel realm, String userId, RoleModel role);
Set<RoleModel> getRoleMappings(RealmModel realm,String userId); @Deprecated
default Set<RoleModel> getRoleMappings(RealmModel realm,String userId) {
return getRoleMappingsStream(realm, userId).collect(Collectors.toSet());
}
Stream<RoleModel> getRoleMappingsStream(RealmModel realm, String userId);
void deleteRoleMapping(RealmModel realm, String userId, RoleModel role); void deleteRoleMapping(RealmModel realm, String userId, RoleModel role);
} }

View file

@ -48,7 +48,6 @@ import org.keycloak.credential.CredentialModel;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientScopeModel; import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleContainerModel;
@ -164,7 +163,7 @@ public class ExportUtils {
// Scopes of clients // Scopes of clients
for (ClientModel client : allClients) { for (ClientModel client : allClients) {
Set<RoleModel> clientScopes = client.getScopeMappings(); Set<RoleModel> clientScopes = client.getScopeMappingsStream().collect(Collectors.toSet());
ScopeMappingRepresentation scopeMappingRep = null; ScopeMappingRepresentation scopeMappingRep = null;
for (RoleModel scope : clientScopes) { for (RoleModel scope : clientScopes) {
if (scope.getContainer() instanceof RealmModel) { if (scope.getContainer() instanceof RealmModel) {
@ -201,7 +200,7 @@ public class ExportUtils {
// Scopes of client scopes // Scopes of client scopes
for (ClientScopeModel clientScope : realm.getClientScopes()) { for (ClientScopeModel clientScope : realm.getClientScopes()) {
Set<RoleModel> clientScopes = clientScope.getScopeMappings(); Set<RoleModel> clientScopes = clientScope.getScopeMappingsStream().collect(Collectors.toSet());
ScopeMappingRepresentation scopeMappingRep = null; ScopeMappingRepresentation scopeMappingRep = null;
for (RoleModel scope : clientScopes) { for (RoleModel scope : clientScopes) {
if (scope.getContainer() instanceof RealmModel) { if (scope.getContainer() instanceof RealmModel) {
@ -428,7 +427,7 @@ public class ExportUtils {
public static RoleRepresentation exportRole(RoleModel role) { public static RoleRepresentation exportRole(RoleModel role) {
RoleRepresentation roleRep = ModelToRepresentation.toRepresentation(role); RoleRepresentation roleRep = ModelToRepresentation.toRepresentation(role);
Set<RoleModel> composites = role.getComposites(); Set<RoleModel> composites = role.getCompositesStream().collect(Collectors.toSet());
if (composites != null && composites.size() > 0) { if (composites != null && composites.size() > 0) {
Set<String> compositeRealmRoles = null; Set<String> compositeRealmRoles = null;
Map<String, List<String>> compositeClientRoles = null; Map<String, List<String>> compositeClientRoles = null;
@ -493,7 +492,7 @@ public class ExportUtils {
// Role mappings // Role mappings
if (options.isGroupsAndRolesIncluded()) { if (options.isGroupsAndRolesIncluded()) {
Set<RoleModel> roles = user.getRoleMappings(); Set<RoleModel> roles = user.getRoleMappingsStream().collect(Collectors.toSet());
List<String> realmRoleNames = new ArrayList<>(); List<String> realmRoleNames = new ArrayList<>();
Map<String, List<String>> clientRoleNames = new HashMap<>(); Map<String, List<String>> clientRoleNames = new HashMap<>();
for (RoleModel role : roles) { for (RoleModel role : roles) {
@ -673,7 +672,7 @@ public class ExportUtils {
// Role mappings // Role mappings
if (options.isGroupsAndRolesIncluded()) { if (options.isGroupsAndRolesIncluded()) {
Set<RoleModel> roles = session.userFederatedStorage().getRoleMappings(realm, id); Set<RoleModel> roles = session.userFederatedStorage().getRoleMappingsStream(realm, id).collect(Collectors.toSet());
List<String> realmRoleNames = new ArrayList<>(); List<String> realmRoleNames = new ArrayList<>();
Map<String, List<String>> clientRoleNames = new HashMap<>(); Map<String, List<String>> clientRoleNames = new HashMap<>();
for (RoleModel role : roles) { for (RoleModel role : roles) {

View file

@ -21,11 +21,8 @@ import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
import org.keycloak.dom.saml.v2.assertion.AttributeType; import org.keycloak.dom.saml.v2.assertion.AttributeType;
import org.keycloak.models.ClientSessionContext; import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.RoleUtils;
import org.keycloak.protocol.ProtocolMapper; import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.ProtocolMapperUtils; import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.saml.SamlProtocol; import org.keycloak.protocol.saml.SamlProtocol;
@ -33,12 +30,10 @@ import org.keycloak.provider.ProviderConfigProperty;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -144,7 +139,7 @@ public class RoleListMapper extends AbstractSAMLProtocolMapper implements SAMLRo
} }
} }
List<String> allRoleNames = clientSessionCtx.getRoles().stream() List<String> allRoleNames = clientSessionCtx.getRolesStream()
// todo need a role mapping // todo need a role mapping
.map(roleModel -> roleNameMappers.stream() .map(roleModel -> roleNameMappers.stream()
.map(entry -> entry.mapper.mapName(entry.model, roleModel)) .map(entry -> entry.mapper.mapName(entry.model, roleModel))

View file

@ -18,9 +18,7 @@ package org.keycloak.protocol.saml.mappers;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType; import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType;
import org.keycloak.dom.saml.v2.protocol.ResponseType; import org.keycloak.dom.saml.v2.protocol.ResponseType;
@ -82,29 +80,23 @@ public class SAMLAudienceResolveProtocolMapper extends AbstractSAMLProtocolMappe
AudienceRestrictionType aud = SAMLAudienceProtocolMapper.locateAudienceRestriction(response); AudienceRestrictionType aud = SAMLAudienceProtocolMapper.locateAudienceRestriction(response);
if (aud != null) { if (aud != null) {
// get all the roles the user has and calculate the clientIds to add // get all the roles the user has and calculate the clientIds to add
Set<RoleModel> roles = clientSessionCtx.getRoles();
Set<String> audiences = new HashSet<>();
// add as audience any SAML clientId with role included (same as OIDC) // add as audience any SAML clientId with role included (same as OIDC)
for (RoleModel role : roles) { clientSessionCtx.getRolesStream()
logger.tracef("Managing role: %s", role.getName()); .peek(r -> logger.tracef("Managing role: %s", r.getName()))
if (role.isClientRole()) { .filter(RoleModel::isClientRole)
ClientModel app = (ClientModel) role.getContainer(); .map(r -> (ClientModel) r.getContainer())
// only adding SAML clients that are not this clientId (which is added by default) // only adding SAML clients that are not this clientId (which is added by default)
if (SamlProtocol.LOGIN_PROTOCOL.equals(app.getProtocol()) && .filter(app -> SamlProtocol.LOGIN_PROTOCOL.equals(app.getProtocol()) &&
!app.getClientId().equals(clientSessionCtx.getClientSession().getClient().getClientId())) { !app.getClientId().equals(clientSessionCtx.getClientSession().getClient().getClientId()))
audiences.add(app.getClientId()); .map(ClientModel::getClientId)
} .peek(audience -> logger.debugf("Audience to add: %s", audience))
} .forEach(audience -> {
}
logger.debugf("Calculated audiences to add: %s", audiences);
// add the audiences
for (String audience : audiences) {
try { try {
aud.addAudience(URI.create(audience)); aud.addAudience(URI.create(audience));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.warnf(e, "Invalid URI syntax for audience: %s", audience); logger.warnf(e, "Invalid URI syntax for audience: %s", audience);
} }
} });
} }
return response; return response;
} }

View file

@ -33,6 +33,7 @@ import org.keycloak.services.ServicesLogger;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; 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 // 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) { private UserSessionModel createOfflineUserSession(UserModel user, UserSessionModel userSession) {

View file

@ -25,8 +25,6 @@ import org.keycloak.authentication.AuthenticationProcessor;
import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator; import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator;
import org.keycloak.authentication.authenticators.broker.util.PostBrokerLoginConstants; import org.keycloak.authentication.authenticators.broker.util.PostBrokerLoginConstants;
import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext; 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.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext; import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException; import org.keycloak.broker.provider.IdentityBrokerException;
@ -123,6 +121,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
/** /**
* <p></p> * <p></p>
@ -279,7 +278,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
// Ensure user has role and client has "role scope" for this role // Ensure user has role and client has "role scope" for this role
ClientSessionContext ctx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, session); ClientSessionContext ctx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, session);
Set<RoleModel> userAccountRoles = ctx.getRoles(); Set<RoleModel> userAccountRoles = ctx.getRolesStream().collect(Collectors.toSet());
if (!userAccountRoles.contains(manageAccountRole)) { if (!userAccountRoles.contains(manageAccountRole)) {
RoleModel linkRole = accountService.getRole(AccountRoles.MANAGE_ACCOUNT_LINKS); RoleModel linkRole = accountService.getRole(AccountRoles.MANAGE_ACCOUNT_LINKS);

View file

@ -45,12 +45,10 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -94,15 +92,10 @@ public class ClientRoleMappingsResource {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @NoCache
public List<RoleRepresentation> getClientRoleMappings() { public Stream<RoleRepresentation> getClientRoleMappings() {
viewPermission.require(); viewPermission.require();
Set<RoleModel> mappings = user.getClientRoleMappings(client); return user.getClientRoleMappingsStream(client).map(ModelToRepresentation::toBriefRepresentation);
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : mappings) {
mapRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
return mapRep;
} }
/** /**
@ -184,19 +177,13 @@ public class ClientRoleMappingsResource {
managePermission.require(); managePermission.require();
if (roles == null) { if (roles == null) {
Set<RoleModel> roleModels = user.getClientRoleMappings(client); roles = user.getClientRoleMappingsStream(client)
roles = new LinkedList<>(); .peek(roleModel -> {
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); auth.roles().requireMapRole(roleModel);
user.deleteRoleMapping(roleModel); user.deleteRoleMapping(roleModel);
roles.add(ModelToRepresentation.toBriefRepresentation(roleModel)); })
} .map(ModelToRepresentation::toBriefRepresentation)
.collect(Collectors.toList());
} else { } else {
for (RoleRepresentation role : roles) { for (RoleRepresentation role : roles) {
RoleModel roleModel = client.getRole(role.getName()); RoleModel roleModel = client.getRole(role.getName());

View file

@ -25,6 +25,7 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.ManagementPermissionReference; import org.keycloak.representations.idm.ManagementPermissionReference;
import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator; 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 javax.ws.rs.core.MediaType;
import java.util.List; import java.util.List;
import java.util.Set; 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 * 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 @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) { public Stream<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'"); if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'");
RoleModel role = getRoleModel(id); RoleModel role = getRoleModel(id);
auth.roles().requireView(role); auth.roles().requireView(role);
return getRoleComposites(role); return role.getCompositesStream().map(ModelToRepresentation::toBriefRepresentation);
} }
/** /**
@ -183,10 +185,9 @@ public class RoleByIdResource extends RoleResource {
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-id") String id) { public Stream<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-id") String id) {
RoleModel role = getRoleModel(id); RoleModel role = getRoleModel(id);
auth.roles().requireView(role); auth.roles().requireView(role);
auth.roles().requireView(role);
return getRealmRoleComposites(role); return getRealmRoleComposites(role);
} }
@ -201,7 +202,7 @@ public class RoleByIdResource extends RoleResource {
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-id") String id, public Stream<RoleRepresentation> getClientRoleComposites(final @PathParam("role-id") String id,
final @PathParam("clientUuid") String clientUuid) { final @PathParam("clientUuid") String clientUuid) {
RoleModel role = getRoleModel(id); RoleModel role = getRoleModel(id);

View file

@ -259,13 +259,13 @@ public class RoleContainerResource extends RoleResource {
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-name") String roleName) { public Stream<RoleRepresentation> getRoleComposites(final @PathParam("role-name") String roleName) {
auth.roles().requireView(roleContainer); auth.roles().requireView(roleContainer);
RoleModel role = roleContainer.getRole(roleName); RoleModel role = roleContainer.getRole(roleName);
if (role == null) { if (role == null) {
throw new NotFoundException("Could not find role"); 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 @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-name") String roleName) { public Stream<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-name") String roleName) {
auth.roles().requireView(roleContainer); auth.roles().requireView(roleContainer);
RoleModel role = roleContainer.getRole(roleName); RoleModel role = roleContainer.getRole(roleName);
if (role == null) { if (role == null) {
@ -298,7 +298,7 @@ public class RoleContainerResource extends RoleResource {
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-name") String roleName, public Stream<RoleRepresentation> getClientRoleComposites(final @PathParam("role-name") String roleName,
final @PathParam("clientUuid") String clientUuid) { final @PathParam("clientUuid") String clientUuid) {
auth.roles().requireView(roleContainer); auth.roles().requireView(roleContainer);
RoleModel role = roleContainer.getRole(roleName); RoleModel role = roleContainer.getRole(roleName);

View file

@ -53,12 +53,11 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -124,7 +123,7 @@ public class RoleMapperResource {
ClientModel clientModel; ClientModel clientModel;
ClientMappingsRepresentation mappings; ClientMappingsRepresentation mappings;
for (RoleModel roleMapping : roleMapper.getRoleMappings()) { for (RoleModel roleMapping : roleMapper.getRoleMappingsStream().collect(Collectors.toSet())) {
RoleContainerModel container = roleMapping.getContainer(); RoleContainerModel container = roleMapping.getContainer();
if (container instanceof RealmModel) { if (container instanceof RealmModel) {
realmRolesRepresentation.add(ModelToRepresentation.toBriefRepresentation(roleMapping)); realmRolesRepresentation.add(ModelToRepresentation.toBriefRepresentation(roleMapping));
@ -157,15 +156,10 @@ public class RoleMapperResource {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @NoCache
public List<RoleRepresentation> getRealmRoleMappings() { public Stream<RoleRepresentation> getRealmRoleMappings() {
viewPermission.require(); viewPermission.require();
Set<RoleModel> realmMappings = roleMapper.getRealmRoleMappings(); return roleMapper.getRealmRoleMappingsStream().map(ModelToRepresentation::toBriefRepresentation);
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : realmMappings) {
realmMappingsRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
return realmMappingsRep;
} }
/** /**
@ -250,14 +244,13 @@ public class RoleMapperResource {
logger.debug("deleteRealmRoleMappings"); logger.debug("deleteRealmRoleMappings");
if (roles == null) { if (roles == null) {
Set<RoleModel> roleModels = roleMapper.getRealmRoleMappings(); roles = roleMapper.getRealmRoleMappingsStream()
roles = new LinkedList<>(); .peek(roleModel -> {
for (RoleModel roleModel : roleModels) {
auth.roles().requireMapRole(roleModel); auth.roles().requireMapRole(roleModel);
roleMapper.deleteRoleMapping(roleModel); roleMapper.deleteRoleMapping(roleModel);
roles.add(ModelToRepresentation.toBriefRepresentation(roleModel)); })
} .map(ModelToRepresentation::toBriefRepresentation)
.collect(Collectors.toList());
} else { } else {
for (RoleRepresentation role : roles) { for (RoleRepresentation role : roles) {

View file

@ -28,11 +28,8 @@ import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluato
import javax.ws.rs.NotFoundException; import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import java.util.Collections; import java.util.*;
import java.util.HashSet; import java.util.stream.Stream;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* @resource Roles * @resource Roles
@ -93,36 +90,16 @@ public abstract class RoleResource {
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success(); adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
} }
protected Set<RoleRepresentation> getRoleComposites(RoleModel role) { protected Stream<RoleRepresentation> getRealmRoleComposites(RoleModel role) {
if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet(); return role.getCompositesStream()
.filter(composite -> composite.getContainer() instanceof RealmModel)
Set<RoleRepresentation> composites = new HashSet<RoleRepresentation>(role.getComposites().size()); .map(ModelToRepresentation::toBriefRepresentation);
for (RoleModel composite : role.getComposites()) {
composites.add(ModelToRepresentation.toBriefRepresentation(composite));
}
return composites;
} }
protected Set<RoleRepresentation> getRealmRoleComposites(RoleModel role) { protected Stream<RoleRepresentation> getClientRoleComposites(ClientModel app, RoleModel role) {
if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet(); return role.getCompositesStream()
.filter(composite -> Objects.equals(composite.getContainer(), app))
Set<RoleRepresentation> composites = new HashSet<RoleRepresentation>(role.getComposites().size()); .map(ModelToRepresentation::toBriefRepresentation);
for (RoleModel composite : role.getComposites()) {
if (composite.getContainer() instanceof RealmModel)
composites.add(ModelToRepresentation.toBriefRepresentation(composite));
}
return composites;
}
protected Set<RoleRepresentation> getClientRoleComposites(ClientModel app, RoleModel role) {
if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet();
Set<RoleRepresentation> composites = new HashSet<RoleRepresentation>(role.getComposites().size());
for (RoleModel composite : role.getComposites()) {
if (composite.getContainer().equals(app))
composites.add(ModelToRepresentation.toBriefRepresentation(composite));
}
return composites;
} }
protected void deleteComposites(AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) { protected void deleteComposites(AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {

View file

@ -40,12 +40,10 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -86,15 +84,11 @@ public class ScopeMappedClientResource {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @NoCache
public List<RoleRepresentation> getClientScopeMappings() { public Stream<RoleRepresentation> getClientScopeMappings() {
viewPermission.require(); viewPermission.require();
Set<RoleModel> mappings = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer); //scopedClient.getClientScopeMappings(client); return KeycloakModelUtils.getClientScopeMappingsStream(scopedClient, scopeContainer)
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>(); .map(ModelToRepresentation::toBriefRepresentation);
for (RoleModel roleModel : mappings) {
mapRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
return mapRep;
} }
/** /**
@ -172,14 +166,10 @@ public class ScopeMappedClientResource {
managePermission.require(); managePermission.require();
if (roles == null) { if (roles == null) {
Set<RoleModel> roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client); roles = KeycloakModelUtils.getClientScopeMappingsStream(scopedClient, scopeContainer)
roles = new LinkedList<>(); .peek(scopeContainer::deleteScopeMapping)
.map(ModelToRepresentation::toBriefRepresentation)
for (RoleModel roleModel : roleModels) { .collect(Collectors.toList());
scopeContainer.deleteScopeMapping(roleModel);
roles.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
} else { } else {
for (RoleRepresentation role : roles) { for (RoleRepresentation role : roles) {
RoleModel roleModel = scopedClient.getRole(role.getName()); RoleModel roleModel = scopedClient.getRole(role.getName());

View file

@ -43,12 +43,9 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -100,12 +97,10 @@ public class ScopeMappedResource {
} }
MappingsRepresentation all = new MappingsRepresentation(); MappingsRepresentation all = new MappingsRepresentation();
Set<RoleModel> realmMappings = scopeContainer.getRealmScopeMappings(); List<RoleRepresentation> realmRep = scopeContainer.getRealmScopeMappingsStream()
if (!realmMappings.isEmpty()) { .map(ModelToRepresentation::toBriefRepresentation)
List<RoleRepresentation> realmRep = new LinkedList<>(); .collect(Collectors.toList());
for (RoleModel roleModel : realmMappings) { if (!realmRep.isEmpty()) {
realmRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
all.setRealmMappings(realmRep); all.setRealmMappings(realmRep);
} }
@ -130,19 +125,15 @@ public class ScopeMappedResource {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @NoCache
public List<RoleRepresentation> getRealmScopeMappings() { public Stream<RoleRepresentation> getRealmScopeMappings() {
viewPermission.require(); viewPermission.require();
if (scopeContainer == null) { if (scopeContainer == null) {
throw new NotFoundException("Could not find client"); throw new NotFoundException("Could not find client");
} }
Set<RoleModel> realmMappings = scopeContainer.getRealmScopeMappings(); return scopeContainer.getRealmScopeMappingsStream()
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>(); .map(ModelToRepresentation::toBriefRepresentation);
for (RoleModel roleModel : realmMappings) {
realmMappingsRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
return realmMappingsRep;
} }
/** /**
@ -238,14 +229,10 @@ public class ScopeMappedResource {
} }
if (roles == null) { if (roles == null) {
Set<RoleModel> roleModels = scopeContainer.getRealmScopeMappings(); roles = scopeContainer.getRealmScopeMappingsStream()
roles = new LinkedList<>(); .peek(scopeContainer::deleteScopeMapping)
.map(ModelToRepresentation::toBriefRepresentation)
for (RoleModel roleModel : roleModels) { .collect(Collectors.toList());
scopeContainer.deleteScopeMapping(roleModel);
roles.add(ModelToRepresentation.toBriefRepresentation(roleModel));
}
} else { } else {
for (RoleRepresentation role : roles) { for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRoleById(role.getId()); RoleModel roleModel = realm.getRoleById(role.getId());

View file

@ -21,6 +21,8 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
@ -122,12 +124,12 @@ public class DefaultClientSessionContext implements ClientSessionContext {
@Override @Override
public Set<RoleModel> getRoles() { public Stream<RoleModel> getRolesStream() {
// Load roles if not yet present // Load roles if not yet present
if (roles == null) { if (roles == null) {
roles = loadRoles(); roles = loadRoles();
} }
return roles; return roles.stream();
} }
@ -225,7 +227,7 @@ public class DefaultClientSessionContext implements ClientSessionContext {
return true; return true;
} }
Set<RoleModel> clientScopeRoles = clientScope.getScopeMappings(); Set<RoleModel> clientScopeRoles = clientScope.getScopeMappingsStream().collect(Collectors.toSet());
// Client scope is automatically permitted if it doesn't have any role scope mappings // Client scope is automatically permitted if it doesn't have any role scope mappings
if (clientScopeRoles.isEmpty()) { if (clientScopeRoles.isEmpty()) {

View file

@ -350,8 +350,8 @@ public final class OpenshiftSAClientAdapter extends AbstractReadOnlyClientStorag
} }
@Override @Override
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
return Collections.emptySet(); return Stream.empty();
} }
@Override @Override
@ -469,8 +469,8 @@ public final class OpenshiftSAClientAdapter extends AbstractReadOnlyClientStorag
} }
@Override @Override
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
return Collections.emptySet(); return Stream.empty();
} }
@Override @Override

View file

@ -18,7 +18,6 @@
package org.keycloak.utils; package org.keycloak.utils;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionContext; import org.keycloak.models.ClientSessionContext;
@ -102,10 +101,9 @@ public class RoleResolveUtil {
AccessToken token = session.getAttribute(resolvedRolesAttrName, AccessToken.class); AccessToken token = session.getAttribute(resolvedRolesAttrName, AccessToken.class);
if (token == null) { if (token == null) {
token = new AccessToken(); AccessToken finalToken = new AccessToken();
for (RoleModel role : clientSessionCtx.getRoles()) { clientSessionCtx.getRolesStream().forEach(role -> addToToken(finalToken, role));
addToToken(token, role); token = finalToken;
}
session.setAttribute(resolvedRolesAttrName, token); session.setAttribute(resolvedRolesAttrName, token);
} }

View file

@ -285,8 +285,8 @@ public class HardcodedClientStorageProvider implements ClientStorageProvider, Cl
} }
@Override @Override
public Set<RoleModel> getRealmScopeMappings() { public Stream<RoleModel> getRealmScopeMappingsStream() {
return Collections.EMPTY_SET; return Stream.empty();
} }
@Override @Override

View file

@ -26,11 +26,8 @@ import org.keycloak.storage.StorageId;
import org.keycloak.storage.group.GroupStorageProvider; import org.keycloak.storage.group.GroupStorageProvider;
import org.keycloak.storage.group.GroupStorageProviderModel; import org.keycloak.storage.group.GroupStorageProviderModel;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
public class HardcodedGroupStorageProvider implements GroupStorageProvider { public class HardcodedGroupStorageProvider implements GroupStorageProvider {
@ -93,13 +90,13 @@ public class HardcodedGroupStorageProvider implements GroupStorageProvider {
} }
@Override @Override
public Set<RoleModel> getRealmRoleMappings() { public Stream<RoleModel> getRealmRoleMappingsStream() {
return null; return Stream.empty();
} }
@Override @Override
public Set<RoleModel> getClientRoleMappings(ClientModel app) { public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
return null; return Stream.empty();
} }
@Override @Override
@ -108,8 +105,8 @@ public class HardcodedGroupStorageProvider implements GroupStorageProvider {
} }
@Override @Override
public Set<RoleModel> getRoleMappings() { public Stream<RoleModel> getRoleMappingsStream() {
return null; return Stream.empty();
} }
@Override @Override

View file

@ -17,9 +17,7 @@
package org.keycloak.testsuite.federation; package org.keycloak.testsuite.federation;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -116,8 +114,8 @@ public class HardcodedRoleStorageProvider implements RoleStorageProvider {
} }
@Override @Override
public Set<RoleModel> getComposites() { public Stream<RoleModel> getCompositesStream() {
return Collections.EMPTY_SET; return Stream.empty();
} }
@Override @Override
@ -146,7 +144,7 @@ public class HardcodedRoleStorageProvider implements RoleStorageProvider {
} }
@Override @Override
public List<String> getAttribute(String name) { public Stream<String> getAttributeStream(String name) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }

View file

@ -30,7 +30,6 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory; import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory;
import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig; 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.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils; import org.keycloak.testsuite.util.LDAPTestUtils;
@ -63,16 +62,16 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
// check users // check users
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm); UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
Assert.assertNotNull(john); 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); UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
Assert.assertNotNull(mary); 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); UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
Assert.assertNotNull(rob); 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); UserModel james = session.users().getUserByUsername("jameskeycloak", appRealm);
Assert.assertNotNull(james); Assert.assertNotNull(james);
Assert.assertThat(james.getRealmRoleMappings(), Matchers.empty()); Assert.assertThat(james.getRealmRoleMappingsStream().collect(Collectors.toSet()), Matchers.empty());
// check groups // check groups
RoleModel group1 = appRealm.getRole("group1"); RoleModel group1 = appRealm.getRole("group1");
@ -111,16 +110,16 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
// check users // check users
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm); UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
Assert.assertNotNull(john); 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); UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
Assert.assertNotNull(mary); 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); UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
Assert.assertNotNull(rob); 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); UserModel james = session.users().getUserByUsername("jameskeycloak", appRealm);
Assert.assertNotNull(james); 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 // check groups
RoleModel group1 = rolesClient.getRole("group1"); RoleModel group1 = rolesClient.getRole("group1");

View file

@ -44,6 +44,7 @@ import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils; import org.keycloak.testsuite.util.LDAPTestUtils;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -157,7 +158,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
// 2 - Check that role mappings are not in local Keycloak DB (They are in LDAP). // 2 - Check that role mappings are not in local Keycloak DB (They are in LDAP).
UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm); UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm);
Set<RoleModel> johnDbRoles = johnDb.getRoleMappings(); Set<RoleModel> johnDbRoles = johnDb.getRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(johnDbRoles.contains(realmRole1)); Assert.assertFalse(johnDbRoles.contains(realmRole1));
Assert.assertFalse(johnDbRoles.contains(realmRole2)); Assert.assertFalse(johnDbRoles.contains(realmRole2));
Assert.assertFalse(johnDbRoles.contains(realmRole3)); 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 // 3 - Check that role mappings are in LDAP and hence available through federation
Set<RoleModel> johnRoles = john.getRoleMappings(); Set<RoleModel> johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(johnRoles.contains(realmRole1)); Assert.assertTrue(johnRoles.contains(realmRole1));
Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole2));
Assert.assertTrue(johnRoles.contains(realmRole3)); Assert.assertTrue(johnRoles.contains(realmRole3));
Assert.assertTrue(johnRoles.contains(financeRole1)); Assert.assertTrue(johnRoles.contains(financeRole1));
Assert.assertTrue(johnRoles.contains(manageAccountRole)); Assert.assertTrue(johnRoles.contains(manageAccountRole));
Set<RoleModel> johnRealmRoles = john.getRealmRoleMappings(); Set<RoleModel> johnRealmRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertEquals(2, johnRealmRoles.size()); Assert.assertEquals(2, johnRealmRoles.size());
Assert.assertTrue(johnRealmRoles.contains(realmRole1)); Assert.assertTrue(johnRealmRoles.contains(realmRole1));
Assert.assertTrue(johnRealmRoles.contains(realmRole3)); Assert.assertTrue(johnRealmRoles.contains(realmRole3));
// account roles are not mapped in LDAP. Those are in Keycloak DB // account roles are not mapped in LDAP. Those are in Keycloak DB
Set<RoleModel> johnAccountRoles = john.getClientRoleMappings(accountApp); Set<RoleModel> johnAccountRoles = john.getClientRoleMappingsStream(accountApp).collect(Collectors.toSet());
Assert.assertTrue(johnAccountRoles.contains(manageAccountRole)); Assert.assertTrue(johnAccountRoles.contains(manageAccountRole));
Set<RoleModel> johnFinanceRoles = john.getClientRoleMappings(financeApp); Set<RoleModel> johnFinanceRoles = john.getClientRoleMappingsStream(financeApp).collect(Collectors.toSet());
Assert.assertEquals(1, johnFinanceRoles.size()); Assert.assertEquals(1, johnFinanceRoles.size());
Assert.assertTrue(johnFinanceRoles.contains(financeRole1)); Assert.assertTrue(johnFinanceRoles.contains(financeRole1));
@ -193,7 +194,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
john.deleteRoleMapping(financeRole1); john.deleteRoleMapping(financeRole1);
john.deleteRoleMapping(manageAccountRole); john.deleteRoleMapping(manageAccountRole);
johnRoles = john.getRoleMappings(); johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole1));
Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole2));
Assert.assertFalse(johnRoles.contains(realmRole3)); Assert.assertFalse(johnRoles.contains(realmRole3));
@ -238,14 +239,14 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
mary.grantRole(realmRole3); mary.grantRole(realmRole3);
// Assert that mary has both LDAP and DB mapped roles // Assert that mary has both LDAP and DB mapped roles
Set<RoleModel> maryRoles = mary.getRealmRoleMappings(); Set<RoleModel> maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(maryRoles.contains(realmRole1)); Assert.assertTrue(maryRoles.contains(realmRole1));
Assert.assertTrue(maryRoles.contains(realmRole2)); Assert.assertTrue(maryRoles.contains(realmRole2));
Assert.assertTrue(maryRoles.contains(realmRole3)); Assert.assertTrue(maryRoles.contains(realmRole3));
// Assert that access through DB will have just DB mapped role // Assert that access through DB will have just DB mapped role
UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm); UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm);
Set<RoleModel> maryDBRoles = maryDB.getRealmRoleMappings(); Set<RoleModel> maryDBRoles = maryDB.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(maryDBRoles.contains(realmRole1)); Assert.assertFalse(maryDBRoles.contains(realmRole1));
Assert.assertFalse(maryDBRoles.contains(realmRole2)); Assert.assertFalse(maryDBRoles.contains(realmRole2));
Assert.assertTrue(maryDBRoles.contains(realmRole3)); Assert.assertTrue(maryDBRoles.contains(realmRole3));
@ -269,7 +270,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm); UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
// Assert role mappings is not available // Assert role mappings is not available
Set<RoleModel> maryRoles = mary.getRealmRoleMappings(); Set<RoleModel> maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole1"))); Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole1")));
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole2"))); Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole2")));
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole3"))); Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole3")));
@ -302,20 +303,20 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
if (realmRole3 == null) { if (realmRole3 == null) {
realmRole3 = appRealm.addRole("realmRole3"); realmRole3 = appRealm.addRole("realmRole3");
} }
Set<RoleModel> robRoles = rob.getRealmRoleMappings(); Set<RoleModel> robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(robRoles.contains(realmRole1)); Assert.assertTrue(robRoles.contains(realmRole1));
Assert.assertTrue(robRoles.contains(realmRole2)); Assert.assertTrue(robRoles.contains(realmRole2));
Assert.assertFalse(robRoles.contains(realmRole3)); Assert.assertFalse(robRoles.contains(realmRole3));
// Add some role mappings in model and check that user has it // Add some role mappings in model and check that user has it
rob.grantRole(realmRole3); rob.grantRole(realmRole3);
robRoles = rob.getRealmRoleMappings(); robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(robRoles.contains(realmRole3)); 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 // 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, "realmRole1");
deleteRoleMappingsInLDAP(roleMapper, robLdap, "realmRole2"); deleteRoleMappingsInLDAP(roleMapper, robLdap, "realmRole2");
robRoles = rob.getRealmRoleMappings(); robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(robRoles.contains(realmRole1)); Assert.assertTrue(robRoles.contains(realmRole1));
Assert.assertTrue(robRoles.contains(realmRole2)); Assert.assertTrue(robRoles.contains(realmRole2));
@ -323,7 +324,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
rob.deleteRoleMapping(realmRole1); rob.deleteRoleMapping(realmRole1);
rob.deleteRoleMapping(realmRole2); rob.deleteRoleMapping(realmRole2);
rob.deleteRoleMapping(realmRole3); rob.deleteRoleMapping(realmRole3);
robRoles = rob.getRealmRoleMappings(); robRoles = rob.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(robRoles.contains(realmRole1)); Assert.assertFalse(robRoles.contains(realmRole1));
Assert.assertFalse(robRoles.contains(realmRole2)); Assert.assertFalse(robRoles.contains(realmRole2));
Assert.assertFalse(robRoles.contains(realmRole3)); Assert.assertFalse(robRoles.contains(realmRole3));
@ -363,7 +364,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
// make sure user is cached. // make sure user is cached.
UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm); UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm);
Assert.assertNotNull(johnRoleMapper); 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 realmRole1 = appRealm.getRole("realmRole1");
RoleModel realmRole2 = appRealm.getRole("realmRole2"); RoleModel realmRole2 = appRealm.getRole("realmRole2");
Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappings(); Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole1));
Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole2));
}); });
@ -420,7 +421,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
RoleModel realmRole1 = appRealm.getRole("realmRole1"); RoleModel realmRole1 = appRealm.getRole("realmRole1");
RoleModel realmRole2 = appRealm.getRole("realmRole2"); RoleModel realmRole2 = appRealm.getRole("realmRole2");
Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappings(); Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(johnRoles.contains(realmRole1)); Assert.assertTrue(johnRoles.contains(realmRole1));
Assert.assertTrue(johnRoles.contains(realmRole2)); 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 // Get user in Keycloak. Ensure that he is member of requested group
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm); UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
Set<RoleModel> carlosRoles = carlos.getRealmRoleMappings(); Set<RoleModel> carlosRoles = carlos.getRealmRoleMappingsStream().collect(Collectors.toSet());
RoleModel realmRole1 = appRealm.getRole("realmRole1"); RoleModel realmRole1 = appRealm.getRole("realmRole1");
RoleModel realmRole2 = appRealm.getRole("realmRole2"); RoleModel realmRole2 = appRealm.getRole("realmRole2");
@ -500,7 +501,7 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
Assert.assertNotNull(defaultRole); Assert.assertNotNull(defaultRole);
Assert.assertNotNull(realmRole2); Assert.assertNotNull(realmRole2);
Set<RoleModel> davidRoles = david.getRealmRoleMappings(); Set<RoleModel> davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(davidRoles.contains(defaultRole)); Assert.assertTrue(davidRoles.contains(defaultRole));
Assert.assertFalse(davidRoles.contains(realmRole2)); Assert.assertFalse(davidRoles.contains(realmRole2));

View file

@ -41,6 +41,7 @@ import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils; import org.keycloak.testsuite.util.LDAPTestUtils;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -152,7 +153,7 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
// This role should already exists as it was imported from LDAP // This role should already exists as it was imported from LDAP
RoleModel realmRole2 = appRealm.getRole("realmRole2"); RoleModel realmRole2 = appRealm.getRole("realmRole2");
Set<RoleModel> maryRoles = mary.getRealmRoleMappings(); Set<RoleModel> maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(maryRoles.contains(realmRole1)); Assert.assertTrue(maryRoles.contains(realmRole1));
Assert.assertTrue(maryRoles.contains(realmRole2)); 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 // This role should already exists as it was imported from LDAP
RoleModel realmRole2 = appRealm.getRole("realmRole2"); RoleModel realmRole2 = appRealm.getRole("realmRole2");
Set<RoleModel> maryRoles = mary.getRealmRoleMappings(); Set<RoleModel> maryRoles = mary.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(maryRoles.contains(realmRole1)); Assert.assertFalse(maryRoles.contains(realmRole1));
Assert.assertFalse(maryRoles.contains(realmRole2)); 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 // 3 - Check that role mappings are in LDAP and hence available through federation
Set<RoleModel> johnRoles = john.getRoleMappings(); Set<RoleModel> johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(johnRoles.contains(realmRole1)); Assert.assertTrue(johnRoles.contains(realmRole1));
Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole2));
Assert.assertTrue(johnRoles.contains(realmRole3)); Assert.assertTrue(johnRoles.contains(realmRole3));
Assert.assertTrue(johnRoles.contains(financeRole1)); Assert.assertTrue(johnRoles.contains(financeRole1));
Assert.assertTrue(johnRoles.contains(manageAccountRole)); Assert.assertTrue(johnRoles.contains(manageAccountRole));
Set<RoleModel> johnRealmRoles = john.getRealmRoleMappings(); Set<RoleModel> johnRealmRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertEquals(2, johnRealmRoles.size()); Assert.assertEquals(2, johnRealmRoles.size());
Assert.assertTrue(johnRealmRoles.contains(realmRole1)); Assert.assertTrue(johnRealmRoles.contains(realmRole1));
Assert.assertTrue(johnRealmRoles.contains(realmRole3)); Assert.assertTrue(johnRealmRoles.contains(realmRole3));
// account roles are not mapped in LDAP. Those are in Keycloak DB // account roles are not mapped in LDAP. Those are in Keycloak DB
Set<RoleModel> johnAccountRoles = john.getClientRoleMappings(accountApp); Set<RoleModel> johnAccountRoles = john.getClientRoleMappingsStream(accountApp).collect(Collectors.toSet());
Assert.assertTrue(johnAccountRoles.contains(manageAccountRole)); Assert.assertTrue(johnAccountRoles.contains(manageAccountRole));
Set<RoleModel> johnFinanceRoles = john.getClientRoleMappings(financeApp); Set<RoleModel> johnFinanceRoles = john.getClientRoleMappingsStream(financeApp).collect(Collectors.toSet());
Assert.assertEquals(1, johnFinanceRoles.size()); Assert.assertEquals(1, johnFinanceRoles.size());
Assert.assertTrue(johnFinanceRoles.contains(financeRole1)); Assert.assertTrue(johnFinanceRoles.contains(financeRole1));
@ -277,7 +278,7 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
john.deleteRoleMapping(realmRole1); john.deleteRoleMapping(realmRole1);
john.deleteRoleMapping(financeRole1); john.deleteRoleMapping(financeRole1);
johnRoles = john.getRoleMappings(); johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(johnRoles.contains(realmRole1)); Assert.assertFalse(johnRoles.contains(realmRole1));
Assert.assertFalse(johnRoles.contains(realmRole2)); Assert.assertFalse(johnRoles.contains(realmRole2));
Assert.assertFalse(johnRoles.contains(realmRole3)); Assert.assertFalse(johnRoles.contains(realmRole3));
@ -316,14 +317,14 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
Assert.assertNotNull(defaultRole); Assert.assertNotNull(defaultRole);
Assert.assertNotNull(realmRole2); Assert.assertNotNull(realmRole2);
Set<RoleModel> davidRoles = david.getRealmRoleMappings(); Set<RoleModel> davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertTrue(davidRoles.contains(defaultRole)); Assert.assertTrue(davidRoles.contains(defaultRole));
Assert.assertFalse(davidRoles.contains(realmRole2)); Assert.assertFalse(davidRoles.contains(realmRole2));
// Make sure john has not received the default role // Make sure john has not received the default role
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm); UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
Set<RoleModel> johnRoles = john.getRealmRoleMappings(); Set<RoleModel> johnRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet());
Assert.assertFalse(johnRoles.contains(defaultRole)); Assert.assertFalse(johnRoles.contains(defaultRole));
}); });

View file

@ -149,7 +149,8 @@ public class FederatedStorageExportImportTest extends AbstractAuthTest {
Assert.assertTrue(attributes.getList("list1").contains("1")); Assert.assertTrue(attributes.getList("list1").contains("1"));
Assert.assertTrue(attributes.getList("list1").contains("2")); Assert.assertTrue(attributes.getList("list1").contains("2"));
Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD")); 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.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group));
List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId); List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId);
Assert.assertEquals(1, creds.size()); 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("1"));
Assert.assertTrue(attributes.getList("list1").contains("2")); Assert.assertTrue(attributes.getList("list1").contains("2"));
Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD")); 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.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group));
Assert.assertEquals(50, session.userFederatedStorage().getNotBeforeOfUser(realm, userId)); Assert.assertEquals(50, session.userFederatedStorage().getNotBeforeOfUser(realm, userId));
List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId); List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId);

View file

@ -30,6 +30,7 @@ import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -128,8 +129,6 @@ public class CacheTest extends AbstractTestRealmKeycloakTest {
// KEYCLOAK-1842 // KEYCLOAK-1842
@Test @Test
public void testRoleMappingsInvalidatedWhenClientRemoved() { public void testRoleMappingsInvalidatedWhenClientRemoved() {
testingClient.server().run(session -> { testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test"); RealmModel realm = session.realms().getRealmByName("test");
@ -139,25 +138,18 @@ public class CacheTest extends AbstractTestRealmKeycloakTest {
user.grantRole(fooRole); user.grantRole(fooRole);
}); });
int gRolesCount=0;
testingClient.server().run(session -> { testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test"); RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("joel", realm); UserModel user = session.users().getUserByUsername("joel", realm);
int grantedRolesCount = user.getRoleMappings().size(); long grantedRolesCount = user.getRoleMappingsStream().count();
ClientModel client = realm.getClientByClientId("foo"); ClientModel client = realm.getClientByClientId("foo");
realm.removeClient(client.getId()); realm.removeClient(client.getId());
realm = session.realms().getRealmByName("test"); realm = session.realms().getRealmByName("test");
user = session.users().getUserByUsername("joel", realm); user = session.users().getUserByUsername("joel", realm);
Set<RoleModel> roles = user.getRoleMappings(); Set<RoleModel> roles = user.getRoleMappingsStream().collect(Collectors.toSet());
for (RoleModel role : roles) { for (RoleModel role : roles) {
Assert.assertNotNull(role.getContainer()); Assert.assertNotNull(role.getContainer());
} }

View file

@ -41,6 +41,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.hamcrest.core.Is.is; import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue; import static org.hamcrest.core.IsNull.notNullValue;
@ -78,7 +79,8 @@ public class ClientModelTest extends AbstractKeycloakTest {
assertThat(expected.getDescription(), is(actual.getDescription())); assertThat(expected.getDescription(), is(actual.getDescription()));
assertThat(expected.getBaseUrl(), is(actual.getBaseUrl())); assertThat(expected.getBaseUrl(), is(actual.getBaseUrl()));
assertThat(expected.getManagementUrl(), is(actual.getManagementUrl())); 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.getRedirectUris().containsAll(actual.getRedirectUris()), is(true));
assertThat(expected.getWebOrigins().containsAll(actual.getWebOrigins()), 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()); assertThat("Realm Model 'original' is NULL !!", realm, notNullValue());
ClientModel scoped = realm.getClientByClientId("scoped"); ClientModel scoped = realm.getClientByClientId("scoped");
Set<RoleModel> scopeMappings = scoped.getScopeMappings();
// used to throw an NPE // 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()); currentSession.clients().removeClient(realm, scoped.getId());
}); });
@ -187,10 +188,9 @@ public class ClientModelTest extends AbstractKeycloakTest {
ClientModel from = realm.getClientByClientId("from"); ClientModel from = realm.getClientByClientId("from");
RoleModel role = currentSession.roles().getRoleById(realm, roleId); RoleModel role = currentSession.roles().getRoleById(realm, roleId);
from.removeRole(role); from.removeRole(role);
Set<RoleModel> scopeMappings = scoped.getScopeMappings();
// used to throw an NPE // 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, scoped.getId());
currentSession.clients().removeClient(realm, from.getId()); currentSession.clients().removeClient(realm, from.getId());
@ -224,9 +224,8 @@ public class ClientModelTest extends AbstractKeycloakTest {
currentSession = sessionRealmRoleRemove3; currentSession = sessionRealmRoleRemove3;
RealmModel realm = currentSession.realms().getRealmByName(realmName); RealmModel realm = currentSession.realms().getRealmByName(realmName);
ClientModel scoped = realm.getClientByClientId("scoped"); ClientModel scoped = realm.getClientByClientId("scoped");
Set<RoleModel> scopeMappings = scoped.getScopeMappings();
// used to throw an NPE // 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, scoped.getId());
}); });
} }

View file

@ -34,6 +34,7 @@ import org.keycloak.testsuite.arquillian.annotation.ModelTest;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
@ -52,7 +53,7 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest {
Set<RoleModel> requestedRoles = new HashSet<>(); Set<RoleModel> requestedRoles = new HashSet<>();
Set<RoleModel> roleMappings = user.getRoleMappings(); Set<RoleModel> roleMappings = user.getRoleMappingsStream().collect(Collectors.toSet());
Stream<RoleModel> scopeMappings = Stream.concat(application.getScopeMappingsStream(), application.getRolesStream()); Stream<RoleModel> scopeMappings = Stream.concat(application.getScopeMappingsStream(), application.getRolesStream());
scopeMappings.forEach(scope -> roleMappings.forEach(role -> { scopeMappings.forEach(scope -> roleMappings.forEach(role -> {
@ -75,9 +76,7 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest {
} }
if (!scope.isComposite()) return; if (!scope.isComposite()) return;
for (RoleModel contained : scope.getComposites()) { scope.getCompositesStream().forEach(contained -> applyScope(role, contained, visited, requested));
applyScope(role, contained, visited, requested);
}
} }
private static RoleModel getRole(RealmModel realm, String appName, String roleName) { private static RoleModel getRole(RealmModel realm, String appName, String roleName) {

View file

@ -19,17 +19,15 @@ package org.keycloak.testsuite.util.cli;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionTask;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -219,23 +217,22 @@ public class UserCommands {
if (user == null) { if (user == null) {
log.infof("User '%s' doesn't exist in realm '%s'", username, realmName); log.infof("User '%s' doesn't exist in realm '%s'", username, realmName);
} else { } else {
List<String> roleMappings = getRoleMappings(session, realm, user); List<String> roleMappings = getRoleMappings(user);
log.infof("User: ID: '%s', username: '%s', mail: '%s', roles: '%s'", user.getId(), user.getUsername(), user.getEmail(), roleMappings.toString()); log.infof("User: ID: '%s', username: '%s', mail: '%s', roles: '%s'", user.getId(), user.getUsername(), user.getEmail(), roleMappings.toString());
} }
} }
private List<String> getRoleMappings(KeycloakSession session, RealmModel realm, UserModel user) { private List<String> getRoleMappings(UserModel user) {
Set<RoleModel> roles = user.getRoleMappings(); return user.getRoleMappingsStream()
List<String> result = new LinkedList<>(); .map(role -> {
for (RoleModel role : roles) { if (role.getContainer() instanceof RealmModel)
if (role.getContainer() instanceof RealmModel) { return role.getName();
result.add(role.getName()); else {
} else {
ClientModel client = (ClientModel) role.getContainer(); ClientModel client = (ClientModel) role.getContainer();
result.add(client.getClientId() + "/" + role.getName()); return client.getClientId() + "/" + role.getName();
} }
} })
return result; .collect(Collectors.toList());
} }
@Override @Override