KEYCLOAK-15199 Complement methods for accessing roles with Stream variants
This commit is contained in:
parent
f874e9a43c
commit
5d5e56dde3
67 changed files with 539 additions and 832 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue