KEYCLOAK-14846 Default roles processing
This commit is contained in:
parent
2aaceeab7e
commit
1402d021de
81 changed files with 894 additions and 563 deletions
|
@ -40,6 +40,7 @@ public class ClientRepresentation {
|
||||||
protected String clientAuthenticatorType;
|
protected String clientAuthenticatorType;
|
||||||
protected String secret;
|
protected String secret;
|
||||||
protected String registrationAccessToken;
|
protected String registrationAccessToken;
|
||||||
|
@Deprecated
|
||||||
protected String[] defaultRoles;
|
protected String[] defaultRoles;
|
||||||
protected List<String> redirectUris;
|
protected List<String> redirectUris;
|
||||||
protected List<String> webOrigins;
|
protected List<String> webOrigins;
|
||||||
|
@ -200,10 +201,12 @@ public class ClientRepresentation {
|
||||||
this.webOrigins = webOrigins;
|
this.webOrigins = webOrigins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public String[] getDefaultRoles() {
|
public String[] getDefaultRoles() {
|
||||||
return defaultRoles;
|
return defaultRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setDefaultRoles(String[] defaultRoles) {
|
public void setDefaultRoles(String[] defaultRoles) {
|
||||||
this.defaultRoles = defaultRoles;
|
this.defaultRoles = defaultRoles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,9 @@ public class RealmRepresentation {
|
||||||
protected String codeSecret;
|
protected String codeSecret;
|
||||||
protected RolesRepresentation roles;
|
protected RolesRepresentation roles;
|
||||||
protected List<GroupRepresentation> groups;
|
protected List<GroupRepresentation> groups;
|
||||||
|
@Deprecated
|
||||||
protected List<String> defaultRoles;
|
protected List<String> defaultRoles;
|
||||||
|
protected RoleRepresentation defaultRole;
|
||||||
protected List<String> defaultGroups;
|
protected List<String> defaultGroups;
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected Set<String> requiredCredentials;
|
protected Set<String> requiredCredentials;
|
||||||
|
@ -482,14 +484,24 @@ public class RealmRepresentation {
|
||||||
this.actionTokenGeneratedByUserLifespan = actionTokenGeneratedByUserLifespan;
|
this.actionTokenGeneratedByUserLifespan = actionTokenGeneratedByUserLifespan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public List<String> getDefaultRoles() {
|
public List<String> getDefaultRoles() {
|
||||||
return defaultRoles;
|
return defaultRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setDefaultRoles(List<String> defaultRoles) {
|
public void setDefaultRoles(List<String> defaultRoles) {
|
||||||
this.defaultRoles = defaultRoles;
|
this.defaultRoles = defaultRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RoleRepresentation getDefaultRole() {
|
||||||
|
return defaultRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultRole(RoleRepresentation defaultRole) {
|
||||||
|
this.defaultRole = defaultRole;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getDefaultGroups() {
|
public List<String> getDefaultGroups() {
|
||||||
return defaultGroups;
|
return defaultGroups;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,4 +159,22 @@ public class RoleRepresentation {
|
||||||
attributes.put(name, Arrays.asList(value));
|
attributes.put(name, Arrays.asList(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 7;
|
||||||
|
hash = 29 * hash + Objects.hashCode(this.id);
|
||||||
|
hash = 29 * hash + Objects.hashCode(this.name);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || (!(obj instanceof RoleRepresentation))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final RoleRepresentation other = (RoleRepresentation) obj;
|
||||||
|
return Objects.equals(this.id, other.id) && Objects.equals(this.name, other.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ import org.keycloak.models.UserManager;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.cache.CachedUserModel;
|
import org.keycloak.models.cache.CachedUserModel;
|
||||||
import org.keycloak.models.credential.PasswordCredentialModel;
|
import org.keycloak.models.credential.PasswordCredentialModel;
|
||||||
import org.keycloak.models.utils.DefaultRoles;
|
|
||||||
import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
|
import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
|
||||||
import org.keycloak.policy.PasswordPolicyManagerProvider;
|
import org.keycloak.policy.PasswordPolicyManagerProvider;
|
||||||
import org.keycloak.policy.PolicyError;
|
import org.keycloak.policy.PolicyError;
|
||||||
|
@ -291,7 +290,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
|
|
||||||
// Add the user to the default groups and add default required actions
|
// Add the user to the default groups and add default required actions
|
||||||
UserModel proxy = proxy(realm, user, ldapUser, true);
|
UserModel proxy = proxy(realm, user, ldapUser, true);
|
||||||
DefaultRoles.addDefaultRoles(realm, proxy);
|
proxy.grantRole(realm.getDefaultRole());
|
||||||
|
|
||||||
realm.getDefaultGroupsStream().forEach(proxy::joinGroup);
|
realm.getDefaultGroupsStream().forEach(proxy::joinGroup);
|
||||||
|
|
||||||
|
|
|
@ -483,28 +483,28 @@ public class ClientAdapter implements ClientModel, CachedObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public Stream<String> getDefaultRolesStream() {
|
public Stream<String> getDefaultRolesStream() {
|
||||||
if (isUpdated()) return updated.getDefaultRolesStream();
|
if (isUpdated()) return updated.getDefaultRolesStream();
|
||||||
return cached.getDefaultRoles().stream();
|
return getRealm().getDefaultRole().getCompositesStream().filter(this::isClientRole).map(RoleModel::getName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isClientRole(RoleModel role) {
|
||||||
|
return role.isClientRole() && Objects.equals(role.getContainerId(), this.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void addDefaultRole(String name) {
|
public void addDefaultRole(String name) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.addDefaultRole(name);
|
updated.addDefaultRole(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateDefaultRoles(String... defaultRoles) {
|
@Deprecated
|
||||||
getDelegateForUpdate();
|
|
||||||
updated.updateDefaultRoles(defaultRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeDefaultRoles(String... defaultRoles) {
|
public void removeDefaultRoles(String... defaultRoles) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.removeDefaultRoles(defaultRoles);
|
updated.removeDefaultRoles(defaultRoles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -725,30 +725,37 @@ public class RealmAdapter implements CachedRealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public Stream<String> getDefaultRolesStream() {
|
public Stream<String> getDefaultRolesStream() {
|
||||||
if (isUpdated()) return updated.getDefaultRolesStream();
|
if (isUpdated()) return updated.getDefaultRolesStream();
|
||||||
return cached.getDefaultRoles().stream();
|
return getDefaultRole().getCompositesStream().filter(this::isRealmRole).map(RoleModel::getName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRealmRole(RoleModel role) {
|
||||||
|
return ! role.isClientRole();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void addDefaultRole(String name) {
|
public void addDefaultRole(String name) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.addDefaultRole(name);
|
updated.addDefaultRole(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateDefaultRoles(String... defaultRoles) {
|
@Deprecated
|
||||||
getDelegateForUpdate();
|
|
||||||
updated.updateDefaultRoles(defaultRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeDefaultRoles(String... defaultRoles) {
|
public void removeDefaultRoles(String... defaultRoles) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.removeDefaultRoles(defaultRoles);
|
updated.removeDefaultRoles(defaultRoles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addToDefaultRoles(RoleModel role) {
|
||||||
|
getDelegateForUpdate();
|
||||||
|
updated.addToDefaultRoles(role);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<ClientModel> getClientsStream() {
|
public Stream<ClientModel> getClientsStream() {
|
||||||
return cacheSession.getClientsStream(this);
|
return cacheSession.getClientsStream(this);
|
||||||
|
@ -1008,6 +1015,17 @@ public class RealmAdapter implements CachedRealmModel {
|
||||||
updated.setMasterAdminClient(client);
|
updated.setMasterAdminClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultRole(RoleModel role) {
|
||||||
|
getDelegateForUpdate();
|
||||||
|
updated.setDefaultRole(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RoleModel getDefaultRole() {
|
||||||
|
return cached.getDefaultRoleId() == null ? null : cacheSession.getRoleById(this, cached.getDefaultRoleId());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoleModel getRole(String name) {
|
public RoleModel getRole(String name) {
|
||||||
return cacheSession.getRealmRole(this, name);
|
return cacheSession.getRealmRole(this, name);
|
||||||
|
|
|
@ -61,7 +61,6 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
||||||
protected String managementUrl;
|
protected String managementUrl;
|
||||||
protected String rootUrl;
|
protected String rootUrl;
|
||||||
protected String baseUrl;
|
protected String baseUrl;
|
||||||
protected List<String> defaultRoles = new LinkedList<>();
|
|
||||||
protected boolean bearerOnly;
|
protected boolean bearerOnly;
|
||||||
protected boolean consentRequired;
|
protected boolean consentRequired;
|
||||||
protected boolean standardFlowEnabled;
|
protected boolean standardFlowEnabled;
|
||||||
|
@ -99,7 +98,6 @@ 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.getDefaultRolesStream().collect(Collectors.toList()));
|
|
||||||
bearerOnly = model.isBearerOnly();
|
bearerOnly = model.isBearerOnly();
|
||||||
consentRequired = model.isConsentRequired();
|
consentRequired = model.isConsentRequired();
|
||||||
standardFlowEnabled = model.isStandardFlowEnabled();
|
standardFlowEnabled = model.isStandardFlowEnabled();
|
||||||
|
@ -212,10 +210,6 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
||||||
return baseUrl;
|
return baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getDefaultRoles() {
|
|
||||||
return defaultRoles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBearerOnly() {
|
public boolean isBearerOnly() {
|
||||||
return bearerOnly;
|
return bearerOnly;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
||||||
protected boolean adminEventsEnabled;
|
protected boolean adminEventsEnabled;
|
||||||
protected Set<String> adminEnabledEventOperations = new HashSet<>();
|
protected Set<String> adminEnabledEventOperations = new HashSet<>();
|
||||||
protected boolean adminEventsDetailsEnabled;
|
protected boolean adminEventsDetailsEnabled;
|
||||||
protected List<String> defaultRoles;
|
protected String defaultRoleId;
|
||||||
private boolean allowUserManagedAccess;
|
private boolean allowUserManagedAccess;
|
||||||
|
|
||||||
public Set<IdentityProviderMapperModel> getIdentityProviderMapperSet() {
|
public Set<IdentityProviderMapperModel> getIdentityProviderMapperSet() {
|
||||||
|
@ -251,7 +251,7 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
||||||
adminEventsEnabled = model.isAdminEventsEnabled();
|
adminEventsEnabled = model.isAdminEventsEnabled();
|
||||||
adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled();
|
adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled();
|
||||||
|
|
||||||
defaultRoles = model.getDefaultRolesStream().collect(Collectors.toList());
|
defaultRoleId = model.getDefaultRole().getId();
|
||||||
ClientModel masterAdminClient = model.getMasterAdminClient();
|
ClientModel masterAdminClient = model.getMasterAdminClient();
|
||||||
this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null;
|
this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null;
|
||||||
|
|
||||||
|
@ -318,6 +318,10 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
||||||
return masterAdminClient;
|
return masterAdminClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDefaultRoleId() {
|
||||||
|
return defaultRoleId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -330,10 +334,6 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
||||||
return displayNameHtml;
|
return displayNameHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getDefaultRoles() {
|
|
||||||
return defaultRoles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.connections.jpa.updater.liquibase.custom;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import liquibase.exception.CustomChangeException;
|
||||||
|
import liquibase.statement.core.InsertStatement;
|
||||||
|
import liquibase.statement.core.RawSqlStatement;
|
||||||
|
import liquibase.statement.core.UpdateStatement;
|
||||||
|
import liquibase.structure.core.Table;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
|
||||||
|
public class JpaUpdate13_0_0_MigrateDefaultRoles extends CustomKeycloakTask {
|
||||||
|
|
||||||
|
private final Set<String> realmIds = new HashSet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateStatementsImpl() throws CustomChangeException {
|
||||||
|
|
||||||
|
extractRealmIds("SELECT ID FROM " + getTableName("REALM"));
|
||||||
|
|
||||||
|
String clientTable = getTableName("CLIENT");
|
||||||
|
String clientDefaultRolesTable = getTableName("CLIENT_DEFAULT_ROLES");
|
||||||
|
String compositeRoleTable = getTableName("COMPOSITE_ROLE");
|
||||||
|
|
||||||
|
for (String realmId : realmIds) {
|
||||||
|
String id = UUID.randomUUID().toString();
|
||||||
|
String roleName = determineDefaultRoleName(realmId);
|
||||||
|
statements.add(
|
||||||
|
// create new default role
|
||||||
|
new InsertStatement(null, null, database.correctObjectName("KEYCLOAK_ROLE", Table.class))
|
||||||
|
.addColumnValue("ID", id)
|
||||||
|
.addColumnValue("CLIENT_REALM_CONSTRAINT", realmId)
|
||||||
|
.addColumnValue("CLIENT_ROLE", Boolean.FALSE)
|
||||||
|
.addColumnValue("DESCRIPTION", "${role_" + roleName + "}")
|
||||||
|
.addColumnValue("NAME", roleName)
|
||||||
|
.addColumnValue("REALM_ID", realmId)
|
||||||
|
.addColumnValue("REALM", realmId)
|
||||||
|
);
|
||||||
|
statements.add(
|
||||||
|
// assign the role to the realm
|
||||||
|
new UpdateStatement(null, null, database.correctObjectName("REALM", Table.class))
|
||||||
|
.addNewColumnValue("DEFAULT_ROLE", id)
|
||||||
|
.setWhereClause("REALM.ID = '" + realmId + "'")
|
||||||
|
);
|
||||||
|
|
||||||
|
statements.add(
|
||||||
|
// copy data from REALM_DEFAULT_ROLES to COMPOSITE_ROLE
|
||||||
|
new RawSqlStatement("INSERT INTO " + compositeRoleTable + " (COMPOSITE, CHILD_ROLE) " +
|
||||||
|
"SELECT '" + id + "', ROLE_ID FROM " + getTableName("REALM_DEFAULT_ROLES") +
|
||||||
|
" WHERE REALM_ID = '" + realmId + "'")
|
||||||
|
);
|
||||||
|
statements.add(
|
||||||
|
// copy data from CLIENT_DEFAULT_ROLES to COMPOSITE_ROLE
|
||||||
|
new RawSqlStatement("INSERT INTO " + compositeRoleTable + " (COMPOSITE, CHILD_ROLE) " +
|
||||||
|
"SELECT '" + id + "', " + clientDefaultRolesTable + ".ROLE_ID FROM " +
|
||||||
|
clientDefaultRolesTable + " INNER JOIN " + clientTable + " ON " +
|
||||||
|
clientTable + ".ID = " + clientDefaultRolesTable + ".CLIENT_ID AND " +
|
||||||
|
clientTable + ".REALM_ID = '" + realmId + "'")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void extractRealmIds(String sql) throws CustomChangeException {
|
||||||
|
try (PreparedStatement statement = jdbcConnection.prepareStatement(sql);
|
||||||
|
ResultSet rs = statement.executeQuery()) {
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
String realmId = rs.getString(1);
|
||||||
|
|
||||||
|
if (realmId == null || realmId.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
realmIds.add(realmId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CustomChangeException(getTaskId() + ": Exception when extracting data from previous version", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String determineDefaultRoleName(String realmId) throws CustomChangeException {
|
||||||
|
String roleName = Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realmId.toLowerCase();
|
||||||
|
if (isRoleNameAvailable(realmId, roleName)) {
|
||||||
|
return roleName;
|
||||||
|
} else {
|
||||||
|
for (int i = 1; i < Integer.MAX_VALUE; i++) {
|
||||||
|
roleName = Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realmId.toLowerCase() + "-" + i;
|
||||||
|
if (isRoleNameAvailable(realmId, roleName)) return roleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new CustomChangeException(getTaskId() + ": Exception when extracting data from previous version. Unable to determine default role name.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRoleNameAvailable(String realmId, String roleName) throws CustomChangeException {
|
||||||
|
try (PreparedStatement statement = jdbcConnection.prepareStatement("SELECT ID FROM " + getTableName("KEYCLOAK_ROLE") +
|
||||||
|
" WHERE REALM_ID=? AND NAME=?")) {
|
||||||
|
statement.setString(1, realmId);
|
||||||
|
statement.setString(2, roleName);
|
||||||
|
try (ResultSet rs = statement.executeQuery()) {
|
||||||
|
return ! rs.next(); //name is available
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CustomChangeException(getTaskId() + ": Exception when extracting data from previous version", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTaskId() {
|
||||||
|
return "Migrate Default roles (13.0.0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,7 +36,6 @@ import javax.persistence.EntityManager;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -44,7 +43,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.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -681,50 +679,35 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public Stream<String> getDefaultRolesStream() {
|
public Stream<String> getDefaultRolesStream() {
|
||||||
return entity.getDefaultRolesIds().stream().map(this::getRoleNameById);
|
return realm.getDefaultRole().getCompositesStream().filter(this::isClientRole).map(RoleModel::getName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRoleNameById(String id) {
|
private boolean isClientRole(RoleModel role) {
|
||||||
RoleModel roleById = session.roles().getRoleById(realm, id);
|
return role.isClientRole() && Objects.equals(role.getContainerId(), this.getId());
|
||||||
if (roleById == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return roleById.getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void addDefaultRole(String name) {
|
public void addDefaultRole(String name) {
|
||||||
if (entity.getDefaultRolesIds().add(getOrAddRoleId(name))) {
|
realm.getDefaultRole().addCompositeRole(getOrAddRoleId(name));
|
||||||
em.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getOrAddRoleId(String name) {
|
private RoleModel getOrAddRoleId(String name) {
|
||||||
RoleModel role = getRole(name);
|
RoleModel role = getRole(name);
|
||||||
if (role == null) {
|
if (role == null) {
|
||||||
role = addRole(name);
|
role = addRole(name);
|
||||||
}
|
}
|
||||||
return role.getId();
|
return role;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateDefaultRoles(String... defaultRoles) {
|
|
||||||
Set<String> newDefaultRolesIds = Arrays.stream(defaultRoles)
|
|
||||||
.map(this::getOrAddRoleId)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
entity.getDefaultRolesIds().retainAll(newDefaultRolesIds);
|
|
||||||
entity.getDefaultRolesIds().addAll(newDefaultRolesIds);
|
|
||||||
em.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void removeDefaultRoles(String... defaultRoles) {
|
public void removeDefaultRoles(String... defaultRoles) {
|
||||||
Arrays.stream(defaultRoles)
|
for (String defaultRole : defaultRoles) {
|
||||||
.map(this::getRole)
|
realm.getDefaultRole().removeCompositeRole(getRole(defaultRole));
|
||||||
.filter(Objects::nonNull)
|
}
|
||||||
.forEach(role -> entity.getDefaultRolesIds().remove(role.getId()));
|
|
||||||
em.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -337,10 +337,6 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
throw new IllegalStateException("RoleModel's container isn not instance of either RealmModel or ClientModel");
|
throw new IllegalStateException("RoleModel's container isn not instance of either RealmModel or ClientModel");
|
||||||
}
|
}
|
||||||
session.users().preRemove(realm, role);
|
session.users().preRemove(realm, role);
|
||||||
RoleContainerModel container = role.getContainer();
|
|
||||||
if (container.getDefaultRolesStream().anyMatch(r -> Objects.equals(r, role.getName()))) {
|
|
||||||
container.removeDefaultRoles(role.getName());
|
|
||||||
}
|
|
||||||
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
|
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
|
||||||
if (roleEntity == null || !roleEntity.getRealmId().equals(realm.getId())) {
|
if (roleEntity == null || !roleEntity.getRealmId().equals(realm.getId())) {
|
||||||
// Throw model exception to ensure transaction rollback and revert previous operations (removing default roles) as well
|
// Throw model exception to ensure transaction rollback and revert previous operations (removing default roles) as well
|
||||||
|
|
|
@ -43,7 +43,6 @@ import org.keycloak.models.jpa.entities.UserConsentClientScopeEntity;
|
||||||
import org.keycloak.models.jpa.entities.UserConsentEntity;
|
import org.keycloak.models.jpa.entities.UserConsentEntity;
|
||||||
import org.keycloak.models.jpa.entities.UserEntity;
|
import org.keycloak.models.jpa.entities.UserEntity;
|
||||||
import org.keycloak.models.jpa.entities.UserGroupMembershipEntity;
|
import org.keycloak.models.jpa.entities.UserGroupMembershipEntity;
|
||||||
import org.keycloak.models.utils.DefaultRoles;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.storage.StorageId;
|
import org.keycloak.storage.StorageId;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
|
@ -126,7 +125,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
UserAdapter userModel = new UserAdapter(session, realm, em, entity);
|
UserAdapter userModel = new UserAdapter(session, realm, em, entity);
|
||||||
|
|
||||||
if (addDefaultRoles) {
|
if (addDefaultRoles) {
|
||||||
DefaultRoles.addDefaultRoles(realm, userModel);
|
userModel.grantRole(realm.getDefaultRole());
|
||||||
|
|
||||||
// No need to check if user has group as it's new user
|
// No need to check if user has group as it's new user
|
||||||
realm.getDefaultGroupsStream().forEach(userModel::joinGroupImpl);
|
realm.getDefaultGroupsStream().forEach(userModel::joinGroupImpl);
|
||||||
|
|
|
@ -33,7 +33,6 @@ import javax.persistence.LockModeType;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
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;
|
||||||
|
|
||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
|
@ -707,47 +706,35 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public Stream<String> getDefaultRolesStream() {
|
public Stream<String> getDefaultRolesStream() {
|
||||||
return realm.getDefaultRolesIds().stream().map(this::getRoleNameById);
|
return getDefaultRole().getCompositesStream().filter(this::isRealmRole).map(RoleModel::getName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRoleNameById(String id) {
|
private boolean isRealmRole(RoleModel role) {
|
||||||
return getRoleById(id).getName();
|
return ! role.isClientRole();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void addDefaultRole(String name) {
|
public void addDefaultRole(String name) {
|
||||||
if (realm.getDefaultRolesIds().add(getOrAddRoleId(name))) {
|
getDefaultRole().addCompositeRole(getOrAddRoleId(name));
|
||||||
em.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getOrAddRoleId(String name) {
|
private RoleModel getOrAddRoleId(String name) {
|
||||||
RoleModel role = getRole(name);
|
RoleModel role = getRole(name);
|
||||||
if (role == null) {
|
if (role == null) {
|
||||||
role = addRole(name);
|
role = addRole(name);
|
||||||
}
|
}
|
||||||
return role.getId();
|
return role;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateDefaultRoles(String[] defaultRoles) {
|
|
||||||
Set<String> newDefaultRolesIds = Arrays.stream(defaultRoles)
|
|
||||||
.map(this::getOrAddRoleId)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
realm.getDefaultRolesIds().retainAll(newDefaultRolesIds);
|
|
||||||
realm.getDefaultRolesIds().addAll(newDefaultRolesIds);
|
|
||||||
em.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void removeDefaultRoles(String... defaultRoles) {
|
public void removeDefaultRoles(String... defaultRoles) {
|
||||||
Arrays.stream(defaultRoles)
|
for (String defaultRole : defaultRoles) {
|
||||||
.map(this::getRole)
|
getDefaultRole().removeCompositeRole(getRole(defaultRole));
|
||||||
.filter(Objects::nonNull)
|
}
|
||||||
.map(RoleModel::getId)
|
|
||||||
.forEach(realm.getDefaultRolesIds()::remove);
|
|
||||||
em.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1204,6 +1191,19 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
em.flush();
|
em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultRole(RoleModel role) {
|
||||||
|
realm.setDefaultRoleId(role.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RoleModel getDefaultRole() {
|
||||||
|
if (realm.getDefaultRoleId() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return session.roles().getRoleById(this, realm.getDefaultRoleId());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<IdentityProviderModel> getIdentityProvidersStream() {
|
public Stream<IdentityProviderModel> getIdentityProvidersStream() {
|
||||||
return realm.getIdentityProviders().stream().map(this::entityToModel);
|
return realm.getIdentityProviders().stream().map(this::entityToModel);
|
||||||
|
|
|
@ -153,11 +153,6 @@ public class ClientEntity {
|
||||||
@Column(name="NODE_REREG_TIMEOUT")
|
@Column(name="NODE_REREG_TIMEOUT")
|
||||||
private int nodeReRegistrationTimeout;
|
private int nodeReRegistrationTimeout;
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
@Column(name="ROLE_ID")
|
|
||||||
@CollectionTable(name="CLIENT_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="CLIENT_ID")})
|
|
||||||
private Set<String> defaultRolesIds;
|
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@Column(name="ROLE_ID")
|
@Column(name="ROLE_ID")
|
||||||
@CollectionTable(name="SCOPE_MAPPING", joinColumns = { @JoinColumn(name="CLIENT_ID")})
|
@CollectionTable(name="SCOPE_MAPPING", joinColumns = { @JoinColumn(name="CLIENT_ID")})
|
||||||
|
@ -376,17 +371,6 @@ public class ClientEntity {
|
||||||
this.managementUrl = managementUrl;
|
this.managementUrl = managementUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDefaultRolesIds() {
|
|
||||||
if (defaultRolesIds == null) {
|
|
||||||
defaultRolesIds = new HashSet<>();
|
|
||||||
}
|
|
||||||
return defaultRolesIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultRolesIds(Set<String> defaultRolesIds) {
|
|
||||||
this.defaultRolesIds = defaultRolesIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBearerOnly() {
|
public boolean isBearerOnly() {
|
||||||
return bearerOnly;
|
return bearerOnly;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinTable;
|
|
||||||
import javax.persistence.MapKey;
|
import javax.persistence.MapKey;
|
||||||
import javax.persistence.MapKeyColumn;
|
import javax.persistence.MapKeyColumn;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
|
@ -158,11 +157,6 @@ public class RealmEntity {
|
||||||
@CollectionTable(name="REALM_SMTP_CONFIG", joinColumns={ @JoinColumn(name="REALM_ID") })
|
@CollectionTable(name="REALM_SMTP_CONFIG", joinColumns={ @JoinColumn(name="REALM_ID") })
|
||||||
protected Map<String, String> smtpConfig;
|
protected Map<String, String> smtpConfig;
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
@Column(name="ROLE_ID")
|
|
||||||
@CollectionTable(name="REALM_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="REALM_ID")})
|
|
||||||
protected Set<String> defaultRolesIds;
|
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@Column(name="GROUP_ID")
|
@Column(name="GROUP_ID")
|
||||||
@CollectionTable(name="REALM_DEFAULT_GROUPS", joinColumns={ @JoinColumn(name="REALM_ID") })
|
@CollectionTable(name="REALM_DEFAULT_GROUPS", joinColumns={ @JoinColumn(name="REALM_ID") })
|
||||||
|
@ -192,6 +186,9 @@ public class RealmEntity {
|
||||||
@Column(name="MASTER_ADMIN_CLIENT")
|
@Column(name="MASTER_ADMIN_CLIENT")
|
||||||
protected String masterAdminClient;
|
protected String masterAdminClient;
|
||||||
|
|
||||||
|
@Column(name="DEFAULT_ROLE")
|
||||||
|
protected String defaultRoleId;
|
||||||
|
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
protected List<IdentityProviderEntity> identityProviders;
|
protected List<IdentityProviderEntity> identityProviders;
|
||||||
|
|
||||||
|
@ -459,17 +456,6 @@ public class RealmEntity {
|
||||||
this.smtpConfig = smtpConfig;
|
this.smtpConfig = smtpConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDefaultRolesIds() {
|
|
||||||
if (defaultRolesIds == null) {
|
|
||||||
defaultRolesIds = new HashSet<>();
|
|
||||||
}
|
|
||||||
return defaultRolesIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultRolesIds(Set<String> defaultRolesIds) {
|
|
||||||
this.defaultRolesIds = defaultRolesIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getDefaultGroupIds() {
|
public Set<String> getDefaultGroupIds() {
|
||||||
if (defaultGroupIds == null) {
|
if (defaultGroupIds == null) {
|
||||||
defaultGroupIds = new HashSet<>();
|
defaultGroupIds = new HashSet<>();
|
||||||
|
@ -591,6 +577,14 @@ public class RealmEntity {
|
||||||
this.masterAdminClient = masterAdminClient;
|
this.masterAdminClient = masterAdminClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDefaultRoleId() {
|
||||||
|
return defaultRoleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultRoleId(String defaultRoleId) {
|
||||||
|
this.defaultRoleId = defaultRoleId;
|
||||||
|
}
|
||||||
|
|
||||||
public List<UserFederationProviderEntity> getUserFederationProviders() {
|
public List<UserFederationProviderEntity> getUserFederationProviders() {
|
||||||
if (userFederationProviders == null) {
|
if (userFederationProviders == null) {
|
||||||
userFederationProviders = new LinkedList<>();
|
userFederationProviders = new LinkedList<>();
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!--
|
||||||
|
~ * Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||||
|
~ * and other contributors as indicated by the @author tags.
|
||||||
|
~ *
|
||||||
|
~ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ * you may not use this file except in compliance with the License.
|
||||||
|
~ * You may obtain a copy of the License at
|
||||||
|
~ *
|
||||||
|
~ * http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~ *
|
||||||
|
~ * Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ * See the License for the specific language governing permissions and
|
||||||
|
~ * limitations under the License.
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
|
||||||
|
<changeSet author="keycloak" id="default-roles">
|
||||||
|
<addColumn tableName="REALM">
|
||||||
|
<column name="DEFAULT_ROLE" type="VARCHAR(255)"/>
|
||||||
|
</addColumn>
|
||||||
|
|
||||||
|
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate13_0_0_MigrateDefaultRoles" />
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet author="keycloak" id="default-roles-cleanup">
|
||||||
|
<dropTable tableName="REALM_DEFAULT_ROLES" />
|
||||||
|
<dropTable tableName="CLIENT_DEFAULT_ROLES" />
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
|
@ -68,5 +68,6 @@
|
||||||
<include file="META-INF/jpa-changelog-9.0.1.xml"/>
|
<include file="META-INF/jpa-changelog-9.0.1.xml"/>
|
||||||
<include file="META-INF/jpa-changelog-11.0.0.xml"/>
|
<include file="META-INF/jpa-changelog-11.0.0.xml"/>
|
||||||
<include file="META-INF/jpa-changelog-12.0.0.xml"/>
|
<include file="META-INF/jpa-changelog-12.0.0.xml"/>
|
||||||
|
<include file="META-INF/jpa-changelog-13.0.0.xml"/>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -62,7 +60,6 @@ public abstract class AbstractClientEntity<K> implements AbstractEntity<K> {
|
||||||
private Map<String, ProtocolMapperModel> protocolMappers = new HashMap<>();
|
private Map<String, ProtocolMapperModel> protocolMappers = new HashMap<>();
|
||||||
private Map<String, Boolean> clientScopes = new HashMap<>();
|
private Map<String, Boolean> clientScopes = new HashMap<>();
|
||||||
private Set<String> scopeMappings = new LinkedHashSet<>();
|
private Set<String> scopeMappings = new LinkedHashSet<>();
|
||||||
private List<String> defaultRoles = new LinkedList<>();
|
|
||||||
private boolean surrogateAuthRequired;
|
private boolean surrogateAuthRequired;
|
||||||
private String managementUrl;
|
private String managementUrl;
|
||||||
private String rootUrl;
|
private String rootUrl;
|
||||||
|
@ -333,29 +330,6 @@ public abstract class AbstractClientEntity<K> implements AbstractEntity<K> {
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getDefaultRoles() {
|
|
||||||
return defaultRoles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultRoles(Collection<String> defaultRoles) {
|
|
||||||
this.updated |= ! Objects.equals(this.defaultRoles, defaultRoles);
|
|
||||||
this.defaultRoles.clear();
|
|
||||||
this.defaultRoles.addAll(defaultRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addDefaultRole(String name) {
|
|
||||||
updated = true;
|
|
||||||
if (name != null) {
|
|
||||||
defaultRoles.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeDefaultRoles(String... defaultRoles) {
|
|
||||||
for (String defaultRole : defaultRoles) {
|
|
||||||
updated |= this.defaultRoles.remove(defaultRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBearerOnly() {
|
public boolean isBearerOnly() {
|
||||||
return bearerOnly;
|
return bearerOnly;
|
||||||
}
|
}
|
||||||
|
|
|
@ -454,22 +454,35 @@ public abstract class MapClientAdapter extends AbstractClientModel<MapClientEnti
|
||||||
/*************** Default roles ****************/
|
/*************** Default roles ****************/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public Stream<String> getDefaultRolesStream() {
|
public Stream<String> getDefaultRolesStream() {
|
||||||
return entity.getDefaultRoles().stream();
|
return realm.getDefaultRole().getCompositesStream().filter(this::isClientRole).map(RoleModel::getName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isClientRole(RoleModel role) {
|
||||||
|
return role.isClientRole() && Objects.equals(role.getContainerId(), this.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void addDefaultRole(String name) {
|
public void addDefaultRole(String name) {
|
||||||
|
realm.getDefaultRole().addCompositeRole(getOrAddRoleId(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private RoleModel getOrAddRoleId(String name) {
|
||||||
RoleModel role = getRole(name);
|
RoleModel role = getRole(name);
|
||||||
if (role == null) {
|
if (role == null) {
|
||||||
addRole(name);
|
role = addRole(name);
|
||||||
}
|
}
|
||||||
this.entity.addDefaultRole(name);
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void removeDefaultRoles(String... defaultRoles) {
|
public void removeDefaultRoles(String... defaultRoles) {
|
||||||
this.entity.removeDefaultRoles(defaultRoles);
|
for (String defaultRole : defaultRoles) {
|
||||||
|
realm.getDefaultRole().removeCompositeRole(getRole(defaultRole));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************** Protocol mappers ****************/
|
/*************** Protocol mappers ****************/
|
||||||
|
|
|
@ -196,11 +196,6 @@ public class MapRoleProvider implements RoleProvider {
|
||||||
|
|
||||||
session.users().preRemove(realm, role);
|
session.users().preRemove(realm, role);
|
||||||
|
|
||||||
RoleContainerModel container = role.getContainer();
|
|
||||||
if (container.getDefaultRolesStream().anyMatch(r -> Objects.equals(r, role.getName()))) {
|
|
||||||
container.removeDefaultRoles(role.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove role from realm-roles composites
|
//remove role from realm-roles composites
|
||||||
try (Stream<MapRoleEntity> baseStream = getNotRemovedUpdatedRolesStream(realm)
|
try (Stream<MapRoleEntity> baseStream = getNotRemovedUpdatedRolesStream(realm)
|
||||||
.filter(this::isRealmRole)
|
.filter(this::isRealmRole)
|
||||||
|
|
|
@ -43,7 +43,6 @@ import org.keycloak.models.UserProvider;
|
||||||
import org.keycloak.models.map.common.Serialization;
|
import org.keycloak.models.map.common.Serialization;
|
||||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||||
import org.keycloak.models.map.storage.MapStorage;
|
import org.keycloak.models.map.storage.MapStorage;
|
||||||
import org.keycloak.models.utils.DefaultRoles;
|
|
||||||
import org.keycloak.storage.StorageId;
|
import org.keycloak.storage.StorageId;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.storage.client.ClientStorageProvider;
|
import org.keycloak.storage.client.ClientStorageProvider;
|
||||||
|
@ -352,7 +351,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
final UserModel userModel = entityToAdapterFunc(realm).apply(entity);
|
final UserModel userModel = entityToAdapterFunc(realm).apply(entity);
|
||||||
|
|
||||||
if (addDefaultRoles) {
|
if (addDefaultRoles) {
|
||||||
DefaultRoles.addDefaultRoles(realm, userModel);
|
userModel.grantRole(realm.getDefaultRole());
|
||||||
|
|
||||||
// No need to check if user has group as it's new user
|
// No need to check if user has group as it's new user
|
||||||
realm.getDefaultGroupsStream().forEach(userModel::joinGroup);
|
realm.getDefaultGroupsStream().forEach(userModel::joinGroup);
|
||||||
|
|
|
@ -30,6 +30,6 @@ public interface AccountRoles {
|
||||||
String MANAGE_CONSENT = "manage-consent";
|
String MANAGE_CONSENT = "manage-consent";
|
||||||
String DELETE_ACCOUNT = "delete-account";
|
String DELETE_ACCOUNT = "delete-account";
|
||||||
|
|
||||||
String[] ALL = {VIEW_PROFILE, MANAGE_ACCOUNT};
|
String[] DEFAULT = {VIEW_PROFILE, MANAGE_ACCOUNT};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ public final class Constants {
|
||||||
public static final String READ_TOKEN_ROLE = "read-token";
|
public static final String READ_TOKEN_ROLE = "read-token";
|
||||||
public static final String[] BROKER_SERVICE_ROLES = {READ_TOKEN_ROLE};
|
public static final String[] BROKER_SERVICE_ROLES = {READ_TOKEN_ROLE};
|
||||||
public static final String OFFLINE_ACCESS_ROLE = OAuth2Constants.OFFLINE_ACCESS;
|
public static final String OFFLINE_ACCESS_ROLE = OAuth2Constants.OFFLINE_ACCESS;
|
||||||
|
public static final String DEFAULT_ROLES_ROLE_PREFIX = "default-roles";
|
||||||
|
|
||||||
public static final String AUTHZ_UMA_PROTECTION = "uma_protection";
|
public static final String AUTHZ_UMA_PROTECTION = "uma_protection";
|
||||||
public static final String AUTHZ_UMA_AUTHORIZATION = "uma_authorization";
|
public static final String AUTHZ_UMA_AUTHORIZATION = "uma_authorization";
|
||||||
|
|
|
@ -339,13 +339,24 @@ public final class KeycloakModelUtils {
|
||||||
return str==null ? null : str.toLowerCase();
|
return str==null ? null : str.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates default role for particular realm with the given name.
|
||||||
|
* @param realm Realm
|
||||||
|
* @param defaultRoleName Name of the newly created defaultRole
|
||||||
|
*/
|
||||||
|
public static void setupDefaultRole(RealmModel realm, String defaultRoleName) {
|
||||||
|
RoleModel defaultRole = realm.addRole(defaultRoleName);
|
||||||
|
defaultRole.setDescription("${role_default-roles}");
|
||||||
|
realm.setDefaultRole(defaultRole);
|
||||||
|
}
|
||||||
|
|
||||||
public static RoleModel setupOfflineRole(RealmModel realm) {
|
public static RoleModel setupOfflineRole(RealmModel realm) {
|
||||||
RoleModel offlineRole = realm.getRole(Constants.OFFLINE_ACCESS_ROLE);
|
RoleModel offlineRole = realm.getRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||||
|
|
||||||
if (offlineRole == null) {
|
if (offlineRole == null) {
|
||||||
offlineRole = realm.addRole(Constants.OFFLINE_ACCESS_ROLE);
|
offlineRole = realm.addRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||||
offlineRole.setDescription("${role_offline-access}");
|
offlineRole.setDescription("${role_offline-access}");
|
||||||
realm.addDefaultRole(Constants.OFFLINE_ACCESS_ROLE);
|
realm.addToDefaultRoles(offlineRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
return offlineRole;
|
return offlineRole;
|
||||||
|
@ -633,7 +644,7 @@ public final class KeycloakModelUtils {
|
||||||
if (realm.getRole(roleName) == null) {
|
if (realm.getRole(roleName) == null) {
|
||||||
RoleModel role = realm.addRole(roleName);
|
RoleModel role = realm.addRole(roleName);
|
||||||
role.setDescription("${role_" + roleName + "}");
|
role.setDescription("${role_" + roleName + "}");
|
||||||
realm.addDefaultRole(roleName);
|
realm.addToDefaultRoles(role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,10 +401,8 @@ 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.getDefaultRolesStream().collect(Collectors.toList());
|
rep.setDefaultRole(toBriefRepresentation(realm.getDefaultRole()));
|
||||||
if (!defaultRoles.isEmpty()) {
|
|
||||||
rep.setDefaultRoles(defaultRoles);
|
|
||||||
}
|
|
||||||
List<String> defaultGroups = realm.getDefaultGroupsStream()
|
List<String> defaultGroups = realm.getDefaultGroupsStream()
|
||||||
.map(ModelToRepresentation::buildGroupPath).collect(Collectors.toList());
|
.map(ModelToRepresentation::buildGroupPath).collect(Collectors.toList());
|
||||||
if (!defaultGroups.isEmpty()) {
|
if (!defaultGroups.isEmpty()) {
|
||||||
|
@ -605,11 +603,6 @@ public class ModelToRepresentation {
|
||||||
rep.setWebOrigins(new LinkedList<>(webOrigins));
|
rep.setWebOrigins(new LinkedList<>(webOrigins));
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] defaultRoles = clientModel.getDefaultRolesStream().toArray(String[]::new);
|
|
||||||
if (defaultRoles.length > 0) {
|
|
||||||
rep.setDefaultRoles(defaultRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clientModel.getRegisteredNodes().isEmpty()) {
|
if (!clientModel.getRegisteredNodes().isEmpty()) {
|
||||||
rep.setRegisteredNodes(new HashMap<>(clientModel.getRegisteredNodes()));
|
rep.setRegisteredNodes(new HashMap<>(clientModel.getRegisteredNodes()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,23 +333,7 @@ public class RepresentationToModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
importRoles(rep.getRoles(), newRealm);
|
importRoles(rep.getRoles(), newRealm);
|
||||||
|
convertDeprecatedDefaultRoles(rep, newRealm);
|
||||||
// Setup realm default roles
|
|
||||||
if (rep.getDefaultRoles() != null) {
|
|
||||||
for (String roleString : rep.getDefaultRoles()) {
|
|
||||||
newRealm.addDefaultRole(roleString.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Setup client default roles
|
|
||||||
if (rep.getClients() != null) {
|
|
||||||
for (ClientRepresentation resourceRep : rep.getClients()) {
|
|
||||||
if (resourceRep.getDefaultRoles() != null) {
|
|
||||||
ClientModel clientModel = createdClients.computeIfAbsent(resourceRep.getClientId(), k -> newRealm.getClientByClientId(resourceRep.getClientId()));
|
|
||||||
clientModel.updateDefaultRoles(resourceRep.getDefaultRoles());
|
|
||||||
createdClients.put(clientModel.getClientId(), clientModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that all possible roles and clients are created, create scope mappings
|
// Now that all possible roles and clients are created, create scope mappings
|
||||||
|
|
||||||
|
@ -628,7 +612,9 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
if (realmRoles.getRealm() != null) { // realm roles
|
if (realmRoles.getRealm() != null) { // realm roles
|
||||||
for (RoleRepresentation roleRep : realmRoles.getRealm()) {
|
for (RoleRepresentation roleRep : realmRoles.getRealm()) {
|
||||||
createRole(realm, roleRep);
|
if (! realm.getDefaultRole().getName().equals(roleRep.getName())) { // default role was already imported
|
||||||
|
createRole(realm, roleRep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (realmRoles.getClient() != null) {
|
if (realmRoles.getClient() != null) {
|
||||||
|
@ -993,6 +979,47 @@ public class RepresentationToModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void convertDeprecatedDefaultRoles(RealmRepresentation rep, RealmModel newRealm) {
|
||||||
|
if (rep.getDefaultRole() == null) {
|
||||||
|
|
||||||
|
// Setup realm default roles
|
||||||
|
if (rep.getDefaultRoles() != null) {
|
||||||
|
rep.getDefaultRoles().stream()
|
||||||
|
.map(String::trim)
|
||||||
|
.map(name -> getOrAddRealmRole(newRealm, name))
|
||||||
|
.forEach(role -> newRealm.getDefaultRole().addCompositeRole(role));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup client default roles
|
||||||
|
if (rep.getClients() != null) {
|
||||||
|
for (ClientRepresentation clientRep : rep.getClients()) {
|
||||||
|
if (clientRep.getDefaultRoles() != null) {
|
||||||
|
Arrays.stream(clientRep.getDefaultRoles())
|
||||||
|
.map(String::trim)
|
||||||
|
.map(name -> getOrAddClientRole(newRealm.getClientById(clientRep.getId()), name))
|
||||||
|
.forEach(role -> newRealm.getDefaultRole().addCompositeRole(role));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RoleModel getOrAddRealmRole(RealmModel realm, String name) {
|
||||||
|
RoleModel role = realm.getRole(name);
|
||||||
|
if (role == null) {
|
||||||
|
role = realm.addRole(name);
|
||||||
|
}
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RoleModel getOrAddClientRole(ClientModel client, String name) {
|
||||||
|
RoleModel role = client.getRole(name);
|
||||||
|
if (role == null) {
|
||||||
|
role = client.addRole(name);
|
||||||
|
}
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
public static void renameRealm(RealmModel realm, String name) {
|
public static void renameRealm(RealmModel realm, String name) {
|
||||||
if (name.equals(realm.getName())) return;
|
if (name.equals(realm.getName())) return;
|
||||||
|
|
||||||
|
@ -1130,10 +1157,6 @@ public class RepresentationToModel {
|
||||||
realm.setPasswordPolicy(PasswordPolicy.parse(session, rep.getPasswordPolicy()));
|
realm.setPasswordPolicy(PasswordPolicy.parse(session, rep.getPasswordPolicy()));
|
||||||
if (rep.getOtpPolicyType() != null) realm.setOTPPolicy(toPolicy(rep));
|
if (rep.getOtpPolicyType() != null) realm.setOTPPolicy(toPolicy(rep));
|
||||||
|
|
||||||
if (rep.getDefaultRoles() != null) {
|
|
||||||
realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()]));
|
|
||||||
}
|
|
||||||
|
|
||||||
WebAuthnPolicy webAuthnPolicy = getWebAuthnPolicyTwoFactor(rep);
|
WebAuthnPolicy webAuthnPolicy = getWebAuthnPolicyTwoFactor(rep);
|
||||||
realm.setWebAuthnPolicy(webAuthnPolicy);
|
realm.setWebAuthnPolicy(webAuthnPolicy);
|
||||||
|
|
||||||
|
@ -1222,7 +1245,7 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
// Roles
|
// Roles
|
||||||
|
|
||||||
public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
|
public static RoleModel createRole(RealmModel newRealm, RoleRepresentation roleRep) {
|
||||||
RoleModel role = roleRep.getId() != null ? newRealm.addRole(roleRep.getId(), roleRep.getName()) : newRealm.addRole(roleRep.getName());
|
RoleModel role = roleRep.getId() != null ? newRealm.addRole(roleRep.getId(), roleRep.getName()) : newRealm.addRole(roleRep.getName());
|
||||||
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
|
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
|
||||||
if (roleRep.getAttributes() != null) {
|
if (roleRep.getAttributes() != null) {
|
||||||
|
@ -1230,6 +1253,7 @@ public class RepresentationToModel {
|
||||||
role.setAttribute(attribute.getKey(), attribute.getValue());
|
role.setAttribute(attribute.getKey(), attribute.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
|
private static void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
|
||||||
|
@ -1264,7 +1288,7 @@ public class RepresentationToModel {
|
||||||
private static Map<String, ClientModel> createClients(KeycloakSession session, RealmRepresentation rep, RealmModel realm, Map<String, String> mappedFlows) {
|
private static Map<String, ClientModel> createClients(KeycloakSession session, RealmRepresentation rep, RealmModel realm, Map<String, String> mappedFlows) {
|
||||||
Map<String, ClientModel> appMap = new HashMap<String, ClientModel>();
|
Map<String, ClientModel> appMap = new HashMap<String, ClientModel>();
|
||||||
for (ClientRepresentation resourceRep : rep.getClients()) {
|
for (ClientRepresentation resourceRep : rep.getClients()) {
|
||||||
ClientModel app = createClient(session, realm, resourceRep, false, mappedFlows);
|
ClientModel app = createClient(session, realm, resourceRep, mappedFlows);
|
||||||
appMap.put(app.getClientId(), app);
|
appMap.put(app.getClientId(), app);
|
||||||
|
|
||||||
ValidationUtil.validateClient(session, app, false, r -> {
|
ValidationUtil.validateClient(session, app, false, r -> {
|
||||||
|
@ -1281,11 +1305,11 @@ public class RepresentationToModel {
|
||||||
* @param resourceRep
|
* @param resourceRep
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation resourceRep, boolean addDefaultRoles) {
|
public static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation resourceRep) {
|
||||||
return createClient(session, realm, resourceRep, addDefaultRoles, null);
|
return createClient(session, realm, resourceRep, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation resourceRep, boolean addDefaultRoles, Map<String, String> mappedFlows) {
|
private static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation resourceRep, Map<String, String> mappedFlows) {
|
||||||
logger.debugv("Create client: {0}", resourceRep.getClientId());
|
logger.debugv("Create client: {0}", resourceRep.getClientId());
|
||||||
|
|
||||||
ClientModel client = resourceRep.getId() != null ? realm.addClient(resourceRep.getId(), resourceRep.getClientId()) : realm.addClient(resourceRep.getClientId());
|
ClientModel client = resourceRep.getId() != null ? realm.addClient(resourceRep.getId(), resourceRep.getClientId()) : realm.addClient(resourceRep.getClientId());
|
||||||
|
@ -1408,11 +1432,6 @@ public class RepresentationToModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addDefaultRoles && resourceRep.getDefaultRoles() != null) {
|
|
||||||
client.updateDefaultRoles(resourceRep.getDefaultRoles());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (resourceRep.getProtocolMappers() != null) {
|
if (resourceRep.getProtocolMappers() != null) {
|
||||||
// first, remove all default/built in mappers
|
// first, remove all default/built in mappers
|
||||||
client.getProtocolMappersStream().collect(Collectors.toList()).forEach(client::removeProtocolMapper);
|
client.getProtocolMappersStream().collect(Collectors.toList()).forEach(client::removeProtocolMapper);
|
||||||
|
@ -1528,9 +1547,6 @@ public class RepresentationToModel {
|
||||||
if (rep.getNotBefore() != null) {
|
if (rep.getNotBefore() != null) {
|
||||||
resource.setNotBefore(rep.getNotBefore());
|
resource.setNotBefore(rep.getNotBefore());
|
||||||
}
|
}
|
||||||
if (rep.getDefaultRoles() != null) {
|
|
||||||
resource.updateDefaultRoles(rep.getDefaultRoles());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> redirectUris = rep.getRedirectUris();
|
List<String> redirectUris = rep.getRedirectUris();
|
||||||
if (redirectUris != null) {
|
if (redirectUris != null) {
|
||||||
|
|
|
@ -25,7 +25,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 org.keycloak.models.UserModelDefaultMethods;
|
import org.keycloak.models.UserModelDefaultMethods;
|
||||||
import org.keycloak.models.utils.DefaultRoles;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.RoleUtils;
|
import org.keycloak.models.utils.RoleUtils;
|
||||||
import org.keycloak.storage.ReadOnlyException;
|
import org.keycloak.storage.ReadOnlyException;
|
||||||
|
@ -76,7 +75,7 @@ public class InMemoryUserAdapter extends UserModelDefaultMethods.Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDefaults() {
|
public void addDefaults() {
|
||||||
DefaultRoles.addDefaultRoles(realm, this);
|
this.grantRole(realm.getDefaultRole());
|
||||||
|
|
||||||
realm.getDefaultGroupsStream().forEach(this::joinGroup);
|
realm.getDefaultGroupsStream().forEach(this::joinGroup);
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,6 +668,18 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
void setMasterAdminClient(ClientModel client);
|
void setMasterAdminClient(ClientModel client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns default realm role. All both realm and client default roles are assigned as composite of this role.
|
||||||
|
* @return Default role of this realm
|
||||||
|
*/
|
||||||
|
RoleModel getDefaultRole();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets default role for this realm
|
||||||
|
* @param role to be set
|
||||||
|
*/
|
||||||
|
void setDefaultRole(RoleModel role);
|
||||||
|
|
||||||
boolean isIdentityFederationEnabled();
|
boolean isIdentityFederationEnabled();
|
||||||
|
|
||||||
boolean isInternationalizationEnabled();
|
boolean isInternationalizationEnabled();
|
||||||
|
@ -788,4 +800,12 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<ClientScopeModel> getDefaultClientScopesStream(boolean defaultScope);
|
Stream<ClientScopeModel> getDefaultClientScopesStream(boolean defaultScope);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a role as a composite to default role of this realm.
|
||||||
|
* @param role to be added
|
||||||
|
*/
|
||||||
|
default void addToDefaultRoles(RoleModel role) {
|
||||||
|
getDefaultRole().addCompositeRole(role);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import org.keycloak.provider.ProviderEvent;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import org.keycloak.provider.ProviderEvent;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -71,9 +71,7 @@ public interface RoleContainerModel {
|
||||||
Stream<RoleModel> searchForRolesStream(String search, Integer first, Integer max);
|
Stream<RoleModel> searchForRolesStream(String search, Integer first, Integer max);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the default role names of this object.
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
* @return List of the default role names of this object. Never returns {@code null}.
|
|
||||||
* @deprecated use the stream variant instead
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default List<String> getDefaultRoles() {
|
default List<String> getDefaultRoles() {
|
||||||
|
@ -81,25 +79,21 @@ public interface RoleContainerModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all default role names of this object as a stream.
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
* @return stream of default role names of this object. Never returns {@code null}.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
Stream<String> getDefaultRolesStream();
|
Stream<String> getDefaultRolesStream();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a role with given name to default roles of this object. If the role
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
* doesn't exist a new role is created.
|
|
||||||
* @param name of the role to be (created and ) added
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
void addDefaultRole(String name);
|
void addDefaultRole(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates default roles of this object. It removes all default roles which
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
* are not specified by {@code defaultRoles} and adds all which weren't
|
|
||||||
* present in original default roles. In other words it's the same as calling
|
|
||||||
* {@code Set.retainAll} and {@code Set.addAll}.
|
|
||||||
* @param defaultRoles Array of realm roles to be updated
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
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 = getDefaultRolesStream().collect(Collectors.toList());
|
Collection<String> entities = getDefaultRolesStream().collect(Collectors.toList());
|
||||||
|
@ -122,9 +116,9 @@ public interface RoleContainerModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes default roles from this object according to {@code defaultRoles}.
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
* @param defaultRoles Role names to be removed from default roles of this object.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
void removeDefaultRoles(String... defaultRoles);
|
void removeDefaultRoles(String... defaultRoles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.keycloak.models.utils;
|
|
||||||
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class DefaultRoles {
|
|
||||||
public static Stream<RoleModel> getDefaultRoles(RealmModel realm) {
|
|
||||||
Stream<RoleModel> realmDefaultRoles = realm.getDefaultRolesStream().map(realm::getRole);
|
|
||||||
Stream<RoleModel> clientDefaultRoles = realm.getClientsStream().flatMap(DefaultRoles::toClientDefaultRoles);
|
|
||||||
return Stream.concat(realmDefaultRoles, clientDefaultRoles);
|
|
||||||
}
|
|
||||||
public static void addDefaultRoles(RealmModel realm, UserModel userModel) {
|
|
||||||
getDefaultRoles(realm).forEach(userModel::grantRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream<RoleModel> toClientDefaultRoles(ClientModel c) {
|
|
||||||
return c.getDefaultRolesStream().map(c::getRole);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,7 +25,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 org.keycloak.models.UserModelDefaultMethods;
|
import org.keycloak.models.UserModelDefaultMethods;
|
||||||
import org.keycloak.models.utils.DefaultRoles;
|
|
||||||
import org.keycloak.models.utils.RoleUtils;
|
import org.keycloak.models.utils.RoleUtils;
|
||||||
import org.keycloak.storage.ReadOnlyException;
|
import org.keycloak.storage.ReadOnlyException;
|
||||||
import org.keycloak.storage.StorageId;
|
import org.keycloak.storage.StorageId;
|
||||||
|
@ -175,7 +174,7 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
||||||
@Override
|
@Override
|
||||||
public Set<RoleModel> getRoleMappings() {
|
public Set<RoleModel> getRoleMappings() {
|
||||||
Set<RoleModel> set = new HashSet<>();
|
Set<RoleModel> set = new HashSet<>();
|
||||||
if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm).collect(Collectors.toSet()));
|
if (appendDefaultRolesToRoleMappings()) set.addAll(realm.getDefaultRole().getCompositesStream().collect(Collectors.toSet()));
|
||||||
set.addAll(getRoleMappingsInternal());
|
set.addAll(getRoleMappingsInternal());
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +456,7 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
||||||
@Override
|
@Override
|
||||||
public Stream<RoleModel> getRoleMappingsStream() {
|
public Stream<RoleModel> getRoleMappingsStream() {
|
||||||
Stream<RoleModel> roleMappings = getRoleMappingsInternal().stream();
|
Stream<RoleModel> roleMappings = getRoleMappingsInternal().stream();
|
||||||
if (appendDefaultRolesToRoleMappings()) return Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
|
if (appendDefaultRolesToRoleMappings()) return Stream.concat(roleMappings, realm.getDefaultRole().getCompositesStream());
|
||||||
return roleMappings;
|
return roleMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,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 org.keycloak.models.UserModelDefaultMethods;
|
import org.keycloak.models.UserModelDefaultMethods;
|
||||||
import org.keycloak.models.utils.DefaultRoles;
|
|
||||||
import org.keycloak.models.utils.RoleUtils;
|
import org.keycloak.models.utils.RoleUtils;
|
||||||
import org.keycloak.storage.StorageId;
|
import org.keycloak.storage.StorageId;
|
||||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||||
|
@ -216,7 +215,7 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
||||||
@Override
|
@Override
|
||||||
public Set<RoleModel> getRoleMappings() {
|
public Set<RoleModel> getRoleMappings() {
|
||||||
Set<RoleModel> set = new HashSet<>(getFederatedRoleMappings());
|
Set<RoleModel> set = new HashSet<>(getFederatedRoleMappings());
|
||||||
if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm).collect(Collectors.toSet()));
|
if (appendDefaultRolesToRoleMappings()) set.addAll(realm.getDefaultRole().getCompositesStream().collect(Collectors.toSet()));
|
||||||
set.addAll(getRoleMappingsInternal());
|
set.addAll(getRoleMappingsInternal());
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
@ -503,7 +502,7 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
||||||
@Override
|
@Override
|
||||||
public Stream<RoleModel> getRoleMappingsStream() {
|
public Stream<RoleModel> getRoleMappingsStream() {
|
||||||
Stream<RoleModel> roleMappings = getFederatedRoleMappings().stream();
|
Stream<RoleModel> roleMappings = getFederatedRoleMappings().stream();
|
||||||
if (appendDefaultRolesToRoleMappings()) roleMappings = Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
|
if (appendDefaultRolesToRoleMappings()) roleMappings = Stream.concat(roleMappings, realm.getDefaultRole().getCompositesStream());
|
||||||
return Stream.concat(roleMappings, getRoleMappingsInternal().stream());
|
return Stream.concat(roleMappings, getRoleMappingsInternal().stream());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ public class ClientsPartialImport extends AbstractPartialImport<ClientRepresenta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientModel client = RepresentationToModel.createClient(session, realm, clientRep, true);
|
ClientModel client = RepresentationToModel.createClient(session, realm, clientRep);
|
||||||
RepresentationToModel.importAuthorizationSettings(clientRep, client, session);
|
RepresentationToModel.importAuthorizationSettings(clientRep, client, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
ClientModel clientModel = ClientManager.createClient(session, realm, client, true);
|
ClientModel clientModel = ClientManager.createClient(session, realm, client);
|
||||||
|
|
||||||
if (clientModel.isServiceAccountsEnabled()) {
|
if (clientModel.isServiceAccountsEnabled()) {
|
||||||
new ClientManager(new RealmManager(session)).enableServiceAccount(clientModel);
|
new ClientManager(new RealmManager(session)).enableServiceAccount(clientModel);
|
||||||
|
|
|
@ -75,8 +75,8 @@ public class ClientManager {
|
||||||
* @param addDefaultRoles
|
* @param addDefaultRoles
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation rep, boolean addDefaultRoles) {
|
public static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation rep) {
|
||||||
ClientModel client = RepresentationToModel.createClient(session, realm, rep, addDefaultRoles);
|
ClientModel client = RepresentationToModel.createClient(session, realm, rep);
|
||||||
|
|
||||||
if (rep.getProtocol() != null) {
|
if (rep.getProtocol() != null) {
|
||||||
LoginProtocolFactory providerFactory = (LoginProtocolFactory) session.getKeycloakSessionFactory().getProviderFactory(LoginProtocol.class, rep.getProtocol());
|
LoginProtocolFactory providerFactory = (LoginProtocolFactory) session.getKeycloakSessionFactory().getProviderFactory(LoginProtocol.class, rep.getProtocol());
|
||||||
|
|
|
@ -110,6 +110,7 @@ public class RealmManager {
|
||||||
// setup defaults
|
// setup defaults
|
||||||
setupRealmDefaults(realm);
|
setupRealmDefaults(realm);
|
||||||
|
|
||||||
|
KeycloakModelUtils.setupDefaultRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + name.toLowerCase());
|
||||||
setupMasterAdminManagement(realm);
|
setupMasterAdminManagement(realm);
|
||||||
setupRealmAdminManagement(realm);
|
setupRealmAdminManagement(realm);
|
||||||
setupAccountManagement(realm);
|
setupAccountManagement(realm);
|
||||||
|
@ -427,10 +428,10 @@ public class RealmManager {
|
||||||
|
|
||||||
accountClient.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
accountClient.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||||
|
|
||||||
for (String role : AccountRoles.ALL) {
|
for (String role : AccountRoles.DEFAULT) {
|
||||||
accountClient.addDefaultRole(role);
|
RoleModel roleModel = accountClient.addRole(role);
|
||||||
RoleModel roleModel = accountClient.getRole(role);
|
|
||||||
roleModel.setDescription("${role_" + role + "}");
|
roleModel.setDescription("${role_" + role + "}");
|
||||||
|
realm.addToDefaultRoles(roleModel);
|
||||||
}
|
}
|
||||||
RoleModel manageAccountLinks = accountClient.addRole(AccountRoles.MANAGE_ACCOUNT_LINKS);
|
RoleModel manageAccountLinks = accountClient.addRole(AccountRoles.MANAGE_ACCOUNT_LINKS);
|
||||||
manageAccountLinks.setDescription("${role_" + AccountRoles.MANAGE_ACCOUNT_LINKS + "}");
|
manageAccountLinks.setDescription("${role_" + AccountRoles.MANAGE_ACCOUNT_LINKS + "}");
|
||||||
|
@ -521,6 +522,12 @@ public class RealmManager {
|
||||||
|
|
||||||
setupRealmDefaults(realm);
|
setupRealmDefaults(realm);
|
||||||
|
|
||||||
|
if (rep.getDefaultRole() == null) {
|
||||||
|
KeycloakModelUtils.setupDefaultRole(realm, determineDefaultRoleName(rep));
|
||||||
|
} else {
|
||||||
|
realm.setDefaultRole(RepresentationToModel.createRole(realm, rep.getDefaultRole()));
|
||||||
|
}
|
||||||
|
|
||||||
boolean postponeMasterClientSetup = postponeMasterClientSetup(rep);
|
boolean postponeMasterClientSetup = postponeMasterClientSetup(rep);
|
||||||
if (!postponeMasterClientSetup) {
|
if (!postponeMasterClientSetup) {
|
||||||
setupMasterAdminManagement(realm);
|
setupMasterAdminManagement(realm);
|
||||||
|
@ -605,6 +612,21 @@ public class RealmManager {
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String determineDefaultRoleName(RealmRepresentation rep) {
|
||||||
|
String defaultRoleName = Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + rep.getRealm().toLowerCase();
|
||||||
|
if (! hasRealmRole(rep, defaultRoleName)) {
|
||||||
|
return defaultRoleName;
|
||||||
|
} else {
|
||||||
|
for (int i = 1; i < Integer.MAX_VALUE; i++) {
|
||||||
|
defaultRoleName = Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + rep.getRealm().toLowerCase() + "-" + i;
|
||||||
|
if (! hasRealmRole(rep, defaultRoleName)) {
|
||||||
|
return defaultRoleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean postponeMasterClientSetup(RealmRepresentation rep) {
|
private boolean postponeMasterClientSetup(RealmRepresentation rep) {
|
||||||
if (!Config.getAdminRealm().equals(rep.getRealm())) {
|
if (!Config.getAdminRealm().equals(rep.getRealm())) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class ClientsResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ClientModel clientModel = ClientManager.createClient(session, realm, rep, true);
|
ClientModel clientModel = ClientManager.createClient(session, realm, rep);
|
||||||
|
|
||||||
if (TRUE.equals(rep.isServiceAccountsEnabled())) {
|
if (TRUE.equals(rep.isServiceAccountsEnabled())) {
|
||||||
UserModel serviceAccount = session.users().getServiceAccount(clientModel);
|
UserModel serviceAccount = session.users().getServiceAccount(clientModel);
|
||||||
|
|
|
@ -28,6 +28,8 @@ import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
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.ErrorResponse;
|
||||||
|
import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
||||||
|
@ -42,8 +44,8 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,6 +106,13 @@ public class RoleByIdResource extends RoleResource {
|
||||||
@DELETE
|
@DELETE
|
||||||
@NoCache
|
@NoCache
|
||||||
public void deleteRole(final @PathParam("role-id") String id) {
|
public void deleteRole(final @PathParam("role-id") String id) {
|
||||||
|
if (realm.getDefaultRole() == null) {
|
||||||
|
logger.warnf("Default role for realm with id '%s' doesn't exist.", realm.getId());
|
||||||
|
} else if (realm.getDefaultRole().getId().equals(id)) {
|
||||||
|
throw new ErrorResponseException(ErrorResponse.error(realm.getDefaultRole().getName() + " is default role of the realm and cannot be removed.",
|
||||||
|
Response.Status.BAD_REQUEST));
|
||||||
|
}
|
||||||
|
|
||||||
RoleModel role = getRoleModel(id);
|
RoleModel role = getRoleModel(id);
|
||||||
auth.roles().requireManage(role);
|
auth.roles().requireManage(role);
|
||||||
deleteRole(role);
|
deleteRole(role);
|
||||||
|
|
|
@ -180,7 +180,9 @@ public class RoleMapperResource {
|
||||||
|
|
||||||
Function<RoleModel, RoleRepresentation> toBriefRepresentation = briefRepresentation ?
|
Function<RoleModel, RoleRepresentation> toBriefRepresentation = briefRepresentation ?
|
||||||
ModelToRepresentation::toBriefRepresentation : ModelToRepresentation::toRepresentation;
|
ModelToRepresentation::toBriefRepresentation : ModelToRepresentation::toRepresentation;
|
||||||
return realm.getRolesStream().filter(roleMapper::hasRole).map(toBriefRepresentation);
|
return realm.getRolesStream()
|
||||||
|
.filter(roleMapper::hasRole)
|
||||||
|
.map(toBriefRepresentation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -73,6 +73,7 @@ public abstract class RoleResource {
|
||||||
|
|
||||||
protected void addComposites(AdminPermissionEvaluator auth, AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {
|
protected void addComposites(AdminPermissionEvaluator auth, AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {
|
||||||
for (RoleRepresentation rep : roles) {
|
for (RoleRepresentation rep : roles) {
|
||||||
|
if (rep.getId() == null) throw new NotFoundException("Could not find composite role");
|
||||||
RoleModel composite = realm.getRoleById(rep.getId());
|
RoleModel composite = realm.getRoleById(rep.getId());
|
||||||
if (composite == null) {
|
if (composite == null) {
|
||||||
throw new NotFoundException("Could not find composite role");
|
throw new NotFoundException("Could not find composite role");
|
||||||
|
|
|
@ -237,7 +237,7 @@ public class ScopeMappedResource {
|
||||||
for (RoleRepresentation role : roles) {
|
for (RoleRepresentation role : roles) {
|
||||||
RoleModel roleModel = realm.getRoleById(role.getId());
|
RoleModel roleModel = realm.getRoleById(role.getId());
|
||||||
if (roleModel == null) {
|
if (roleModel == null) {
|
||||||
throw new NotFoundException("Client not found");
|
throw new NotFoundException("Role not found");
|
||||||
}
|
}
|
||||||
scopeContainer.deleteScopeMapping(roleModel);
|
scopeContainer.deleteScopeMapping(roleModel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,6 @@ public class DropAllServlet extends HttpServlet {
|
||||||
"alter table CLIENT nocheck constraint FK_P56CTINXXB9GSK57FO49F9TAC;\n" +
|
"alter table CLIENT nocheck constraint FK_P56CTINXXB9GSK57FO49F9TAC;\n" +
|
||||||
"_drop_table_ CLIENT_ATTRIBUTES _cascade_;\n" +
|
"_drop_table_ CLIENT_ATTRIBUTES _cascade_;\n" +
|
||||||
"_drop_table_ CLIENT_AUTH_FLOW_BINDINGS _cascade_;\n" +
|
"_drop_table_ CLIENT_AUTH_FLOW_BINDINGS _cascade_;\n" +
|
||||||
"_drop_table_ CLIENT_DEFAULT_ROLES _cascade_;\n" +
|
|
||||||
"_drop_table_ CLIENT_INITIAL_ACCESS _cascade_;\n" +
|
"_drop_table_ CLIENT_INITIAL_ACCESS _cascade_;\n" +
|
||||||
"_drop_table_ CLIENT_NODE_REGISTRATIONS _cascade_;\n" +
|
"_drop_table_ CLIENT_NODE_REGISTRATIONS _cascade_;\n" +
|
||||||
"_drop_table_ CLIENT_SCOPE_ATTRIBUTES _cascade_;\n" +
|
"_drop_table_ CLIENT_SCOPE_ATTRIBUTES _cascade_;\n" +
|
||||||
|
@ -141,7 +140,6 @@ public class DropAllServlet extends HttpServlet {
|
||||||
"_drop_table_ REALM_ATTRIBUTE _cascade_;\n" +
|
"_drop_table_ REALM_ATTRIBUTE _cascade_;\n" +
|
||||||
"_drop_table_ REALM_DEFAULT_GROUPS _cascade_;\n" +
|
"_drop_table_ REALM_DEFAULT_GROUPS _cascade_;\n" +
|
||||||
"_drop_table_ KEYCLOAK_GROUP _cascade_;\n" +
|
"_drop_table_ KEYCLOAK_GROUP _cascade_;\n" +
|
||||||
"_drop_table_ REALM_DEFAULT_ROLES _cascade_;\n" +
|
|
||||||
"_drop_table_ REALM_ENABLED_EVENT_TYPES _cascade_;\n" +
|
"_drop_table_ REALM_ENABLED_EVENT_TYPES _cascade_;\n" +
|
||||||
"_drop_table_ REALM_EVENTS_LISTENERS _cascade_;\n" +
|
"_drop_table_ REALM_EVENTS_LISTENERS _cascade_;\n" +
|
||||||
"_drop_table_ REALM_REQUIRED_CREDENTIAL _cascade_;\n" +
|
"_drop_table_ REALM_REQUIRED_CREDENTIAL _cascade_;\n" +
|
||||||
|
|
|
@ -122,9 +122,9 @@ public class AddUserTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
//--------------Roles-----------------------//
|
//--------------Roles-----------------------//
|
||||||
try {
|
try {
|
||||||
List<RoleRepresentation> realmRoles = userResource.roles().realmLevel().listAll();
|
assertRoles(userResource.roles().realmLevel().listAll(), "admin", Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realmName);
|
||||||
|
assertRoles(userResource.roles().realmLevel().listEffective(), "create-realm", Constants.AUTHZ_UMA_AUTHORIZATION,
|
||||||
assertRoles(realmRoles, "admin", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realmName, Constants.OFFLINE_ACCESS_ROLE, "admin");
|
||||||
|
|
||||||
List<ClientRepresentation> clients = realmResource.clients().findAll();
|
List<ClientRepresentation> clients = realmResource.clients().findAll();
|
||||||
String accountId = null;
|
String accountId = null;
|
||||||
|
@ -134,8 +134,9 @@ public class AddUserTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RoleRepresentation> accountRoles = userResource.roles().clientLevel(accountId).listAll();
|
assertTrue(userResource.roles().clientLevel(accountId).listAll().isEmpty());
|
||||||
assertRoles(accountRoles, "view-profile", "manage-account");
|
List<RoleRepresentation> accountRoles = userResource.roles().clientLevel(accountId).listEffective();
|
||||||
|
assertRoles(accountRoles, "view-profile", "manage-account", "manage-account-links");
|
||||||
} finally {
|
} finally {
|
||||||
userResource.remove();
|
userResource.remove();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
|
@ -331,19 +333,21 @@ public class ClientTest extends AbstractAdminTest {
|
||||||
|
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(id, "test"), role, ResourceType.CLIENT_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(id, "test"), role, ResourceType.CLIENT_ROLE);
|
||||||
|
|
||||||
ClientRepresentation foundClientRep = realm.clients().get(id).toRepresentation();
|
role = realm.clients().get(id).roles().get("test").toRepresentation();
|
||||||
foundClientRep.setDefaultRoles(new String[]{"test"});
|
|
||||||
realm.clients().get(id).update(foundClientRep);
|
|
||||||
|
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(id), rep, ResourceType.CLIENT);
|
realm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME).addComposites(Collections.singletonList(role));
|
||||||
|
|
||||||
assertArrayEquals(new String[]{"test"}, realm.clients().get(id).toRepresentation().getDefaultRoles());
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME), Collections.singletonList(role), ResourceType.REALM_ROLE);
|
||||||
|
|
||||||
|
assertThat(realm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME).getRoleComposites().stream().map(RoleRepresentation::getName).collect(Collectors.toSet()),
|
||||||
|
hasItem(role.getName()));
|
||||||
|
|
||||||
realm.clients().get(id).roles().deleteRole("test");
|
realm.clients().get(id).roles().deleteRole("test");
|
||||||
|
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(id, "test"), ResourceType.CLIENT_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(id, "test"), ResourceType.CLIENT_ROLE);
|
||||||
|
|
||||||
assertNull(realm.clients().get(id).toRepresentation().getDefaultRoles());
|
assertThat(realm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME).getRoleComposites().stream().map(RoleRepresentation::getName).collect(Collectors.toSet()),
|
||||||
|
not(hasItem(role)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -555,7 +559,7 @@ public class ClientTest extends AbstractAdminTest {
|
||||||
|
|
||||||
Assert.assertNames(scopesResource.realmLevel().listAll(), "role1");
|
Assert.assertNames(scopesResource.realmLevel().listAll(), "role1");
|
||||||
Assert.assertNames(scopesResource.realmLevel().listEffective(), "role1", "role2");
|
Assert.assertNames(scopesResource.realmLevel().listEffective(), "role1", "role2");
|
||||||
Assert.assertNames(scopesResource.realmLevel().listAvailable(), "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
Assert.assertNames(scopesResource.realmLevel().listAvailable(), "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME);
|
||||||
|
|
||||||
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAll(), AccountRoles.VIEW_PROFILE);
|
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAll(), AccountRoles.VIEW_PROFILE);
|
||||||
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listEffective(), AccountRoles.VIEW_PROFILE);
|
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listEffective(), AccountRoles.VIEW_PROFILE);
|
||||||
|
@ -573,7 +577,7 @@ public class ClientTest extends AbstractAdminTest {
|
||||||
|
|
||||||
Assert.assertNames(scopesResource.realmLevel().listAll());
|
Assert.assertNames(scopesResource.realmLevel().listAll());
|
||||||
Assert.assertNames(scopesResource.realmLevel().listEffective());
|
Assert.assertNames(scopesResource.realmLevel().listEffective());
|
||||||
Assert.assertNames(scopesResource.realmLevel().listAvailable(), "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "role1", "role2");
|
Assert.assertNames(scopesResource.realmLevel().listAvailable(), "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "role1", "role2", Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME);
|
||||||
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAll());
|
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAll());
|
||||||
|
|
||||||
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAvailable(), AccountRoles.VIEW_PROFILE, AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS, AccountRoles.VIEW_APPLICATIONS, AccountRoles.VIEW_CONSENT, AccountRoles.MANAGE_CONSENT, AccountRoles.DELETE_ACCOUNT);
|
Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAvailable(), AccountRoles.VIEW_PROFILE, AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS, AccountRoles.VIEW_APPLICATIONS, AccountRoles.VIEW_CONSENT, AccountRoles.MANAGE_CONSENT, AccountRoles.DELETE_ACCOUNT);
|
||||||
|
|
|
@ -22,12 +22,14 @@ import org.junit.Test;
|
||||||
import org.keycloak.admin.client.resource.RoleByIdResource;
|
import org.keycloak.admin.client.resource.RoleByIdResource;
|
||||||
import org.keycloak.events.admin.OperationType;
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.events.admin.ResourceType;
|
import org.keycloak.events.admin.ResourceType;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
import org.keycloak.testsuite.util.ClientBuilder;
|
import org.keycloak.testsuite.util.ClientBuilder;
|
||||||
import org.keycloak.testsuite.util.RoleBuilder;
|
import org.keycloak.testsuite.util.RoleBuilder;
|
||||||
|
|
||||||
|
import javax.ws.rs.BadRequestException;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -191,4 +193,9 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
|
||||||
Assert.assertRoleAttributes(attributes, roleAttributes);
|
Assert.assertRoleAttributes(attributes, roleAttributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test (expected = BadRequestException.class)
|
||||||
|
public void deleteDefaultRole() {
|
||||||
|
resource.deleteRole(adminClient.realm(REALM_NAME).roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME).toRepresentation().getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2009,7 +2009,8 @@ public class UserTest extends AbstractAdminTest {
|
||||||
assertAdminEvents.clear();
|
assertAdminEvents.clear();
|
||||||
|
|
||||||
RoleMappingResource roles = realm.users().get(userId).roles();
|
RoleMappingResource roles = realm.users().get(userId).roles();
|
||||||
assertNames(roles.realmLevel().listAll(), "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
assertNames(roles.realmLevel().listAll(), Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
assertNames(roles.realmLevel().listEffective(), "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
|
||||||
// Add realm roles
|
// Add realm roles
|
||||||
List<RoleRepresentation> l = new LinkedList<>();
|
List<RoleRepresentation> l = new LinkedList<>();
|
||||||
|
@ -2028,9 +2029,9 @@ public class UserTest extends AbstractAdminTest {
|
||||||
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), ResourceType.CLIENT_ROLE_MAPPING);
|
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), ResourceType.CLIENT_ROLE_MAPPING);
|
||||||
|
|
||||||
// List realm roles
|
// List realm roles
|
||||||
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite", Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
assertNames(roles.realmLevel().listAvailable(), "admin", "customer-user-premium", "realm-composite-role", "sample-realm-role", "attribute-role");
|
assertNames(roles.realmLevel().listAvailable(), "admin", "customer-user-premium", "realm-composite-role", "sample-realm-role", "attribute-role");
|
||||||
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
|
||||||
// List realm effective role with full representation
|
// List realm effective role with full representation
|
||||||
List<RoleRepresentation> realmRolesFullRepresentations = roles.realmLevel().listEffective(false);
|
List<RoleRepresentation> realmRolesFullRepresentations = roles.realmLevel().listEffective(false);
|
||||||
|
@ -2051,17 +2052,16 @@ public class UserTest extends AbstractAdminTest {
|
||||||
|
|
||||||
// Get mapping representation
|
// Get mapping representation
|
||||||
MappingsRepresentation all = roles.getAll();
|
MappingsRepresentation all = roles.getAll();
|
||||||
assertNames(all.getRealmMappings(), "realm-role", "realm-composite", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
assertNames(all.getRealmMappings(), "realm-role", "realm-composite", Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
assertEquals(2, all.getClientMappings().size());
|
assertEquals(1, all.getClientMappings().size());
|
||||||
assertNames(all.getClientMappings().get("myclient").getMappings(), "client-role", "client-composite");
|
assertNames(all.getClientMappings().get("myclient").getMappings(), "client-role", "client-composite");
|
||||||
assertNames(all.getClientMappings().get("account").getMappings(), "manage-account", "view-profile");
|
|
||||||
|
|
||||||
// Remove realm role
|
// Remove realm role
|
||||||
RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation();
|
RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation();
|
||||||
roles.realmLevel().remove(Collections.singletonList(realmRoleRep));
|
roles.realmLevel().remove(Collections.singletonList(realmRoleRep));
|
||||||
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId), Collections.singletonList(realmRoleRep), ResourceType.REALM_ROLE_MAPPING);
|
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId), Collections.singletonList(realmRoleRep), ResourceType.REALM_ROLE_MAPPING);
|
||||||
|
|
||||||
assertNames(roles.realmLevel().listAll(), "realm-composite", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
|
assertNames(roles.realmLevel().listAll(), "realm-composite", Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
|
||||||
// Remove client role
|
// Remove client role
|
||||||
RoleRepresentation clientRoleRep = realm.clients().get(clientUuid).roles().get("client-role").toRepresentation();
|
RoleRepresentation clientRoleRep = realm.clients().get(clientUuid).roles().get("client-role").toRepresentation();
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class AuthorizationTest extends AbstractAuthorizationTest {
|
||||||
|
|
||||||
UserRepresentation serviceAccount = realm.users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + resourceServer.getClientId()).get(0);
|
UserRepresentation serviceAccount = realm.users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + resourceServer.getClientId()).get(0);
|
||||||
Assert.assertNotNull(serviceAccount);
|
Assert.assertNotNull(serviceAccount);
|
||||||
List<RoleRepresentation> serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listAll();
|
List<RoleRepresentation> serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listEffective();
|
||||||
Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName())));
|
Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName())));
|
||||||
|
|
||||||
enableAuthorizationServices(false);
|
enableAuthorizationServices(false);
|
||||||
|
@ -61,7 +61,7 @@ public class AuthorizationTest extends AbstractAuthorizationTest {
|
||||||
serviceAccount = clientResource.getServiceAccountUser();
|
serviceAccount = clientResource.getServiceAccountUser();
|
||||||
Assert.assertNotNull(serviceAccount);
|
Assert.assertNotNull(serviceAccount);
|
||||||
realm = realmsResouce().realm(getRealmId());
|
realm = realmsResouce().realm(getRealmId());
|
||||||
serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listAll();
|
serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listEffective();
|
||||||
Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName())));
|
Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName())));
|
||||||
|
|
||||||
JSPolicyRepresentation policy = new JSPolicyRepresentation();
|
JSPolicyRepresentation policy = new JSPolicyRepresentation();
|
||||||
|
@ -97,7 +97,7 @@ public class AuthorizationTest extends AbstractAuthorizationTest {
|
||||||
|
|
||||||
serviceAccount = clientResource.getServiceAccountUser();
|
serviceAccount = clientResource.getServiceAccountUser();
|
||||||
Assert.assertNotNull(serviceAccount);
|
Assert.assertNotNull(serviceAccount);
|
||||||
serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listAll();
|
serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listEffective();
|
||||||
Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName())));
|
Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
|
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.util.ClientBuilder;
|
import org.keycloak.testsuite.util.ClientBuilder;
|
||||||
|
import org.keycloak.testsuite.util.RoleBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -119,12 +120,15 @@ public class ExportAuthorizationSettingsTest extends AbstractAuthorizationTest {
|
||||||
ClientResource clientResource = getClientResource();
|
ClientResource clientResource = getClientResource();
|
||||||
AuthorizationResource authorizationResource = clientResource.authorization();
|
AuthorizationResource authorizationResource = clientResource.authorization();
|
||||||
|
|
||||||
testRealmResource().clients().create(ClientBuilder.create().clientId("test-client-1").defaultRoles("client-role").build()).close();
|
testRealmResource().clients().create(ClientBuilder.create().clientId("test-client-1").build()).close();
|
||||||
testRealmResource().clients().create(ClientBuilder.create().clientId("test-client-2").defaultRoles("client-role").build()).close();
|
testRealmResource().clients().create(ClientBuilder.create().clientId("test-client-2").build()).close();
|
||||||
|
|
||||||
ClientRepresentation client1 = getClientByClientId("test-client-1");
|
ClientRepresentation client1 = getClientByClientId("test-client-1");
|
||||||
ClientRepresentation client2 = getClientByClientId("test-client-2");
|
ClientRepresentation client2 = getClientByClientId("test-client-2");
|
||||||
|
|
||||||
|
testRealmResource().clients().get(client1.getId()).roles().create(RoleBuilder.create().name("client-role").build());
|
||||||
|
testRealmResource().clients().get(client2.getId()).roles().create(RoleBuilder.create().name("client-role").build());
|
||||||
|
|
||||||
RoleRepresentation role1 = testRealmResource().clients().get(client1.getId()).roles().get("client-role").toRepresentation();
|
RoleRepresentation role1 = testRealmResource().clients().get(client1.getId()).roles().get("client-role").toRepresentation();
|
||||||
RoleRepresentation role2 = testRealmResource().clients().get(client2.getId()).roles().get("client-role").toRepresentation();
|
RoleRepresentation role2 = testRealmResource().clients().get(client2.getId()).roles().get("client-role").toRepresentation();
|
||||||
|
|
||||||
|
@ -134,11 +138,8 @@ public class ExportAuthorizationSettingsTest extends AbstractAuthorizationTest {
|
||||||
Map<String, String> config = new HashMap<>();
|
Map<String, String> config = new HashMap<>();
|
||||||
config.put("roles", "[{\"id\":\"" + role1.getId() +"\"},{\"id\":\"" + role2.getId() +"\"}]");
|
config.put("roles", "[{\"id\":\"" + role1.getId() +"\"},{\"id\":\"" + role2.getId() +"\"}]");
|
||||||
policy.setConfig(config);
|
policy.setConfig(config);
|
||||||
Response create = authorizationResource.policies().create(policy);
|
try (Response create = authorizationResource.policies().create(policy)) {
|
||||||
try {
|
|
||||||
Assert.assertEquals(Status.CREATED, create.getStatusInfo());
|
Assert.assertEquals(Status.CREATED, create.getStatusInfo());
|
||||||
} finally {
|
|
||||||
create.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//export authorization settings
|
//export authorization settings
|
||||||
|
|
|
@ -671,7 +671,7 @@ public class GroupTest extends AbstractGroupTest {
|
||||||
|
|
||||||
// List realm roles
|
// List realm roles
|
||||||
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite");
|
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite");
|
||||||
assertNames(roles.realmLevel().listAvailable(), "admin", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "user", "customer-user-premium", "realm-composite-role", "sample-realm-role", "attribute-role");
|
assertNames(roles.realmLevel().listAvailable(), "admin", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "user", "customer-user-premium", "realm-composite-role", "sample-realm-role", "attribute-role", Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child");
|
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child");
|
||||||
|
|
||||||
// List client roles
|
// List client roles
|
||||||
|
|
|
@ -48,9 +48,6 @@ public class PartialExportTest extends AbstractAdminTest {
|
||||||
Assert.assertNull("Default groups are empty", rep.getDefaultGroups());
|
Assert.assertNull("Default groups are empty", rep.getDefaultGroups());
|
||||||
Assert.assertNull("Groups are empty", rep.getGroups());
|
Assert.assertNull("Groups are empty", rep.getGroups());
|
||||||
|
|
||||||
Assert.assertNotNull("Default roles not empty", rep.getDefaultRoles());
|
|
||||||
checkDefaultRoles(rep.getDefaultRoles());
|
|
||||||
|
|
||||||
Assert.assertNull("Realm and client roles are empty", rep.getRoles());
|
Assert.assertNull("Realm and client roles are empty", rep.getRoles());
|
||||||
Assert.assertNull("Clients are empty", rep.getClients());
|
Assert.assertNull("Clients are empty", rep.getClients());
|
||||||
|
|
||||||
|
@ -65,9 +62,6 @@ public class PartialExportTest extends AbstractAdminTest {
|
||||||
Assert.assertNotNull("Groups not empty", rep.getGroups());
|
Assert.assertNotNull("Groups not empty", rep.getGroups());
|
||||||
checkGroups(rep.getGroups());
|
checkGroups(rep.getGroups());
|
||||||
|
|
||||||
Assert.assertNotNull("Default roles not empty", rep.getDefaultRoles());
|
|
||||||
checkDefaultRoles(rep.getDefaultRoles());
|
|
||||||
|
|
||||||
Assert.assertNotNull("Realm and client roles not empty", rep.getRoles());
|
Assert.assertNotNull("Realm and client roles not empty", rep.getRoles());
|
||||||
Assert.assertNotNull("Realm roles not empty", rep.getRoles().getRealm());
|
Assert.assertNotNull("Realm roles not empty", rep.getRoles().getRealm());
|
||||||
checkRealmRoles(rep.getRoles().getRealm());
|
checkRealmRoles(rep.getRoles().getRealm());
|
||||||
|
@ -86,8 +80,6 @@ public class PartialExportTest extends AbstractAdminTest {
|
||||||
checkServiceAccountRoles(rep.getUsers().get(0), false); // export but without roles
|
checkServiceAccountRoles(rep.getUsers().get(0), false); // export but without roles
|
||||||
Assert.assertNull("Default groups are empty", rep.getDefaultGroups());
|
Assert.assertNull("Default groups are empty", rep.getDefaultGroups());
|
||||||
Assert.assertNull("Groups are empty", rep.getGroups());
|
Assert.assertNull("Groups are empty", rep.getGroups());
|
||||||
Assert.assertNotNull("Default roles not empty", rep.getDefaultRoles());
|
|
||||||
checkDefaultRoles(rep.getDefaultRoles());
|
|
||||||
|
|
||||||
Assert.assertNull("Realm and client roles are empty", rep.getRoles());
|
Assert.assertNull("Realm and client roles are empty", rep.getRoles());
|
||||||
Assert.assertNotNull("Clients not empty", rep.getClients());
|
Assert.assertNotNull("Clients not empty", rep.getClients());
|
||||||
|
@ -107,8 +99,6 @@ public class PartialExportTest extends AbstractAdminTest {
|
||||||
Assert.assertNotNull("Groups not empty", rep.getGroups());
|
Assert.assertNotNull("Groups not empty", rep.getGroups());
|
||||||
checkGroups(rep.getGroups());
|
checkGroups(rep.getGroups());
|
||||||
|
|
||||||
Assert.assertNotNull("Default roles not empty", rep.getDefaultRoles());
|
|
||||||
checkDefaultRoles(rep.getDefaultRoles());
|
|
||||||
|
|
||||||
Assert.assertNotNull("Realm and client roles not empty", rep.getRoles());
|
Assert.assertNotNull("Realm and client roles not empty", rep.getRoles());
|
||||||
Assert.assertNotNull("Realm roles not empty", rep.getRoles().getRealm());
|
Assert.assertNotNull("Realm roles not empty", rep.getRoles().getRealm());
|
||||||
|
|
|
@ -46,12 +46,16 @@ 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.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.ws.rs.ClientErrorException;
|
import javax.ws.rs.ClientErrorException;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
@ -59,6 +63,7 @@ import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -84,10 +89,10 @@ public class RealmRolesTest extends AbstractAdminTest {
|
||||||
|
|
||||||
|
|
||||||
ClientRepresentation clientRep = ClientBuilder.create().clientId("client-a").build();
|
ClientRepresentation clientRep = ClientBuilder.create().clientId("client-a").build();
|
||||||
Response response = adminClient.realm(REALM_NAME).clients().create(clientRep);
|
try (Response response = adminClient.realm(REALM_NAME).clients().create(clientRep)) {
|
||||||
clientUuid = ApiUtil.getCreatedId(response);
|
clientUuid = ApiUtil.getCreatedId(response);
|
||||||
getCleanup().addClientUuid(clientUuid);
|
getCleanup().addClientUuid(clientUuid);
|
||||||
response.close();
|
}
|
||||||
|
|
||||||
RoleRepresentation roleC = RoleBuilder.create().name("role-c").description("Role C").build();
|
RoleRepresentation roleC = RoleBuilder.create().name("role-c").description("Role C").build();
|
||||||
adminClient.realm(REALM_NAME).clients().get(clientUuid).roles().create(roleC);
|
adminClient.realm(REALM_NAME).clients().get(clientUuid).roles().create(roleC);
|
||||||
|
@ -368,17 +373,17 @@ public class RealmRolesTest extends AbstractAdminTest {
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(roleName), role, ResourceType.REALM_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(roleName), role, ResourceType.REALM_ROLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
String roleNameA = "abcdef";
|
String roleNameA = "abcdefg";
|
||||||
RoleRepresentation roleA = makeRole(roleNameA);
|
RoleRepresentation roleA = makeRole(roleNameA);
|
||||||
resource.create(roleA);
|
resource.create(roleA);
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(roleNameA), roleA, ResourceType.REALM_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(roleNameA), roleA, ResourceType.REALM_ROLE);
|
||||||
|
|
||||||
String roleNameB = "defghi";
|
String roleNameB = "defghij";
|
||||||
RoleRepresentation roleB = makeRole(roleNameB);
|
RoleRepresentation roleB = makeRole(roleNameB);
|
||||||
resource.create(roleB);
|
resource.create(roleB);
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(roleNameB), roleB, ResourceType.REALM_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(roleNameB), roleB, ResourceType.REALM_ROLE);
|
||||||
|
|
||||||
List<RoleRepresentation> resultSearch = resource.list("def", -1, -1);
|
List<RoleRepresentation> resultSearch = resource.list("defg", -1, -1);
|
||||||
assertEquals(2,resultSearch.size());
|
assertEquals(2,resultSearch.size());
|
||||||
|
|
||||||
List<RoleRepresentation> resultSearch2 = resource.list("testrole", -1, -1);
|
List<RoleRepresentation> resultSearch2 = resource.list("testrole", -1, -1);
|
||||||
|
@ -485,4 +490,49 @@ public class RealmRolesTest extends AbstractAdminTest {
|
||||||
List<RoleRepresentation> roles = resource.list("attributesrolebrief", true);
|
List<RoleRepresentation> roles = resource.list("attributesrolebrief", true);
|
||||||
assertNull(roles.get(0).getAttributes());
|
assertNull(roles.get(0).getAttributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultRoles() {
|
||||||
|
RoleResource defaultRole = adminClient.realm(REALM_NAME).roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME);
|
||||||
|
|
||||||
|
UserRepresentation user = adminClient.realm(REALM_NAME).users().search("test-role-member").get(0);
|
||||||
|
|
||||||
|
UserResource userResource = adminClient.realm(REALM_NAME).users().get(user.getId());
|
||||||
|
assertThat(convertRolesToNames(userResource.roles().realmLevel().listAll()), hasItem(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME));
|
||||||
|
assertThat(convertRolesToNames(userResource.roles().realmLevel().listEffective()), allOf(
|
||||||
|
hasItem(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME),
|
||||||
|
hasItem(Constants.OFFLINE_ACCESS_ROLE),
|
||||||
|
hasItem(Constants.AUTHZ_UMA_AUTHORIZATION)
|
||||||
|
));
|
||||||
|
|
||||||
|
defaultRole.addComposites(Collections.singletonList(resource.get("role-a").toRepresentation()));
|
||||||
|
|
||||||
|
userResource = adminClient.realm(REALM_NAME).users().get(user.getId());
|
||||||
|
assertThat(convertRolesToNames(userResource.roles().realmLevel().listAll()), allOf(
|
||||||
|
hasItem(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME),
|
||||||
|
not(hasItem("role-a"))
|
||||||
|
));
|
||||||
|
assertThat(convertRolesToNames(userResource.roles().realmLevel().listEffective()), allOf(
|
||||||
|
hasItem(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME),
|
||||||
|
hasItem(Constants.OFFLINE_ACCESS_ROLE),
|
||||||
|
hasItem(Constants.AUTHZ_UMA_AUTHORIZATION),
|
||||||
|
hasItem("role-a")
|
||||||
|
));
|
||||||
|
|
||||||
|
assertThat(userResource.roles().clientLevel(clientUuid).listAll(), empty());
|
||||||
|
assertThat(userResource.roles().clientLevel(clientUuid).listEffective(), empty());
|
||||||
|
|
||||||
|
defaultRole.addComposites(Collections.singletonList(adminClient.realm(REALM_NAME).clients().get(clientUuid).roles().get("role-c").toRepresentation()));
|
||||||
|
|
||||||
|
userResource = adminClient.realm(REALM_NAME).users().get(user.getId());
|
||||||
|
|
||||||
|
assertThat(userResource.roles().clientLevel(clientUuid).listAll(), empty());
|
||||||
|
assertThat(convertRolesToNames(userResource.roles().clientLevel(clientUuid).listEffective()),
|
||||||
|
hasItem("role-c")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> convertRolesToNames(List<RoleRepresentation> roles) {
|
||||||
|
return roles.stream().map(RoleRepresentation::getName).collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,12 +240,15 @@ public class RealmTest extends AbstractAdminTest {
|
||||||
@Test
|
@Test
|
||||||
public void createRealmFromJson() {
|
public void createRealmFromJson() {
|
||||||
RealmRepresentation rep = loadJson(getClass().getResourceAsStream("/admin-test/testrealm.json"), RealmRepresentation.class);
|
RealmRepresentation rep = loadJson(getClass().getResourceAsStream("/admin-test/testrealm.json"), RealmRepresentation.class);
|
||||||
adminClient.realms().create(rep);
|
try {
|
||||||
|
adminClient.realms().create(rep);
|
||||||
|
|
||||||
RealmRepresentation created = adminClient.realms().realm("admin-test-1").toRepresentation();
|
RealmRepresentation created = adminClient.realms().realm("admin-test-1").toRepresentation();
|
||||||
assertRealm(rep, created);
|
assertRealm(rep, created);
|
||||||
|
|
||||||
adminClient.realms().realm("admin-test-1").remove();
|
} finally {
|
||||||
|
adminClient.realms().realm("admin-test-1").remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//KEYCLOAK-6146
|
//KEYCLOAK-6146
|
||||||
|
@ -531,14 +534,12 @@ public class RealmTest extends AbstractAdminTest {
|
||||||
realm.roles().create(role);
|
realm.roles().create(role);
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role, ResourceType.REALM_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role, ResourceType.REALM_ROLE);
|
||||||
|
|
||||||
assertNotNull(realm.roles().get("test").toRepresentation());
|
role = realm.roles().get("test").toRepresentation();
|
||||||
|
assertNotNull(role);
|
||||||
|
|
||||||
RealmRepresentation rep = realm.toRepresentation();
|
realm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME).addComposites(Collections.singletonList(role));
|
||||||
rep.setDefaultRoles(new LinkedList<String>());
|
|
||||||
rep.getDefaultRoles().add("test");
|
|
||||||
|
|
||||||
realm.update(rep);
|
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + REALM_NAME), Collections.singletonList(role), ResourceType.REALM_ROLE);
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM);
|
|
||||||
|
|
||||||
realm.roles().deleteRole("test");
|
realm.roles().deleteRole("test");
|
||||||
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourcePath("test"), ResourceType.REALM_ROLE);
|
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourcePath("test"), ResourceType.REALM_ROLE);
|
||||||
|
@ -642,13 +643,6 @@ public class RealmTest extends AbstractAdminTest {
|
||||||
|
|
||||||
if (realm.getPasswordPolicy() != null) assertEquals(realm.getPasswordPolicy(), storedRealm.getPasswordPolicy());
|
if (realm.getPasswordPolicy() != null) assertEquals(realm.getPasswordPolicy(), storedRealm.getPasswordPolicy());
|
||||||
|
|
||||||
if (realm.getDefaultRoles() != null) {
|
|
||||||
assertNotNull(storedRealm.getDefaultRoles());
|
|
||||||
for (String role : realm.getDefaultRoles()) {
|
|
||||||
assertTrue(storedRealm.getDefaultRoles().contains(role));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (realm.getSmtpServer() != null) {
|
if (realm.getSmtpServer() != null) {
|
||||||
assertEquals(realm.getSmtpServer(), storedRealm.getSmtpServer());
|
assertEquals(realm.getSmtpServer(), storedRealm.getSmtpServer());
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,11 @@ public abstract class AbstractIdentityProviderMapperTest extends AbstractBaseBro
|
||||||
user.setRealmRoles(realmRoles);
|
user.setRealmRoles(realmRoles);
|
||||||
|
|
||||||
Map<String, List<String>> clientRoles = new HashMap<>();
|
Map<String, List<String>> clientRoles = new HashMap<>();
|
||||||
roles.getClientMappings().forEach((key, value) -> clientRoles.put(key, value.getMappings().stream()
|
if (roles.getClientMappings() != null) {
|
||||||
|
roles.getClientMappings().forEach((key, value) -> clientRoles.put(key, value.getMappings().stream()
|
||||||
.map(RoleRepresentation::getName)
|
.map(RoleRepresentation::getName)
|
||||||
.collect(Collectors.toList())));
|
.collect(Collectors.toList())));
|
||||||
|
}
|
||||||
user.setClientRoles(clientRoles);
|
user.setClientRoles(clientRoles);
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
|
@ -69,7 +70,7 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
|
|
||||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||||
List<ObjectNode> roles = loadJson(exe.stdout(), LIST_OF_JSON);
|
List<ObjectNode> roles = loadJson(exe.stdout(), LIST_OF_JSON);
|
||||||
Assert.assertTrue("expect two realm roles available", roles.size() == 2);
|
Assert.assertThat("expected three realm roles available", roles.size(), equalTo(3));
|
||||||
|
|
||||||
// create realm role
|
// create realm role
|
||||||
exe = execute("create roles --config '" + configFile.getName() + "' -s name=testrole -s 'description=Test role' -o");
|
exe = execute("create roles --config '" + configFile.getName() + "' -s name=testrole -s 'description=Test role' -o");
|
||||||
|
@ -84,7 +85,7 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
|
|
||||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||||
roles = loadJson(exe.stdout(), LIST_OF_JSON);
|
roles = loadJson(exe.stdout(), LIST_OF_JSON);
|
||||||
Assert.assertTrue("expect three realm roles available", roles.size() == 3);
|
Assert.assertThat("expected four realm roles available", roles.size(), equalTo(4));
|
||||||
|
|
||||||
// create client
|
// create client
|
||||||
exe = execute("create clients --config '" + configFile.getName() + "' -s clientId=testclient -i");
|
exe = execute("create clients --config '" + configFile.getName() + "' -s clientId=testclient -i");
|
||||||
|
@ -104,7 +105,7 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
|
|
||||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||||
roles = loadJson(exe.stdout(), LIST_OF_JSON);
|
roles = loadJson(exe.stdout(), LIST_OF_JSON);
|
||||||
Assert.assertTrue("expect one role", roles.size() == 1);
|
Assert.assertThat("expected one role", roles.size(), equalTo(1));
|
||||||
Assert.assertEquals("clientrole", roles.get(0).get("name").asText());
|
Assert.assertEquals("clientrole", roles.get(0).get("name").asText());
|
||||||
|
|
||||||
// add created role to user - we are realm admin so we can add role to ourself
|
// add created role to user - we are realm admin so we can add role to ourself
|
||||||
|
@ -122,17 +123,13 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
|
|
||||||
List<String> realmMappings = StreamSupport.stream(node.get("realmMappings").spliterator(), false)
|
List<String> realmMappings = StreamSupport.stream(node.get("realmMappings").spliterator(), false)
|
||||||
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
||||||
Assert.assertEquals(Arrays.asList("offline_access", "uma_authorization"), realmMappings);
|
Assert.assertEquals(Arrays.asList("default-roles-demorealm"), realmMappings);
|
||||||
|
|
||||||
ObjectNode clientRoles = (ObjectNode) node.get("clientMappings");
|
ObjectNode clientRoles = (ObjectNode) node.get("clientMappings");
|
||||||
//List<String> fields = asSortedList(clientRoles.fieldNames());
|
//List<String> fields = asSortedList(clientRoles.fieldNames());
|
||||||
List<String> fields = StreamSupport.stream(clientRoles.spliterator(), false)
|
List<String> fields = StreamSupport.stream(clientRoles.spliterator(), false)
|
||||||
.map(o -> o.get("client").asText()).sorted().collect(Collectors.toList());
|
.map(o -> o.get("client").asText()).sorted().collect(Collectors.toList());
|
||||||
Assert.assertEquals(Arrays.asList("account", "realm-management", "testclient"), fields);
|
Assert.assertEquals(Arrays.asList("realm-management", "testclient"), fields);
|
||||||
|
|
||||||
realmMappings = StreamSupport.stream(clientRoles.get("account").get("mappings").spliterator(), false)
|
|
||||||
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
|
||||||
Assert.assertEquals(Arrays.asList("manage-account", "view-profile"), realmMappings);
|
|
||||||
|
|
||||||
realmMappings = StreamSupport.stream(clientRoles.get("realm-management").get("mappings").spliterator(), false)
|
realmMappings = StreamSupport.stream(clientRoles.get("realm-management").get("mappings").spliterator(), false)
|
||||||
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
||||||
|
@ -159,7 +156,7 @@ public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
|
|
||||||
realmMappings = StreamSupport.stream(node.get("realmMappings").spliterator(), false)
|
realmMappings = StreamSupport.stream(node.get("realmMappings").spliterator(), false)
|
||||||
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
.map(o -> o.get("name").asText()).sorted().collect(Collectors.toList());
|
||||||
Assert.assertEquals(Arrays.asList("offline_access", "testrole", "uma_authorization"), realmMappings);
|
Assert.assertEquals(Arrays.asList("default-roles-demorealm", "testrole"), realmMappings);
|
||||||
|
|
||||||
// create a group
|
// create a group
|
||||||
exe = execute("create groups --config '" + configFile.getName() + "' -s name=TestUsers -i");
|
exe = execute("create groups --config '" + configFile.getName() + "' -s name=TestUsers -i");
|
||||||
|
|
|
@ -147,6 +147,8 @@ import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.keycloak.admin.client.resource.RolesResource;
|
||||||
|
import org.keycloak.testsuite.util.RoleBuilder;
|
||||||
|
|
||||||
import org.keycloak.testsuite.util.ServerURLs;
|
import org.keycloak.testsuite.util.ServerURLs;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
@ -396,9 +398,7 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
assertEquals(OIDCLoginProtocol.CLIENT_SECRET_BASIC, response.getTokenEndpointAuthMethod());
|
assertEquals(OIDCLoginProtocol.CLIENT_SECRET_BASIC, response.getTokenEndpointAuthMethod());
|
||||||
events.expect(EventType.CLIENT_INFO).client(clientId).user(Matchers.isEmptyOrNullString()).assertEvent();
|
events.expect(EventType.CLIENT_INFO).client(clientId).user(Matchers.isEmptyOrNullString()).assertEvent();
|
||||||
|
|
||||||
updateClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
adminClient.realm(REALM_NAME).clients().get(clientId).roles().create(RoleBuilder.create().name("sample-client-role").build());
|
||||||
clientRep.setDefaultRoles(Arrays.asList("sample-client-role").toArray(new String[1]));
|
|
||||||
});
|
|
||||||
|
|
||||||
successfulLoginAndLogoutWithPKCE(response.getClientId(), clientSecret, userName, userPassword);
|
successfulLoginAndLogoutWithPKCE(response.getClientId(), clientSecret, userName, userPassword);
|
||||||
}
|
}
|
||||||
|
@ -411,9 +411,7 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
assertEquals(OIDCLoginProtocol.CLIENT_SECRET_BASIC, clientRep.getTokenEndpointAuthMethod());
|
assertEquals(OIDCLoginProtocol.CLIENT_SECRET_BASIC, clientRep.getTokenEndpointAuthMethod());
|
||||||
events.expect(EventType.CLIENT_REGISTER).client(clientId).user(Matchers.isEmptyOrNullString()).assertEvent();
|
events.expect(EventType.CLIENT_REGISTER).client(clientId).user(Matchers.isEmptyOrNullString()).assertEvent();
|
||||||
events.expect(EventType.CLIENT_INFO).client(clientId).user(Matchers.isEmptyOrNullString()).assertEvent();
|
events.expect(EventType.CLIENT_INFO).client(clientId).user(Matchers.isEmptyOrNullString()).assertEvent();
|
||||||
updateClientByAdmin(clientId, (ClientRepresentation cr) -> {
|
adminClient.realm(REALM_NAME).clients().get(clientId).roles().create(RoleBuilder.create().name("sample-client-role").build());
|
||||||
cr.setDefaultRoles((String[]) Arrays.asList("sample-client-role").toArray(new String[1]));
|
|
||||||
});
|
|
||||||
|
|
||||||
successfulLoginAndLogout(clientId, clientRep.getClientSecret());
|
successfulLoginAndLogout(clientId, clientRep.getClientSecret());
|
||||||
|
|
||||||
|
@ -446,9 +444,9 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
String clientId = "Zahlungs-App";
|
String clientId = "Zahlungs-App";
|
||||||
String clientSecret = "secret";
|
String clientSecret = "secret";
|
||||||
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role").toArray(new String[1]));
|
|
||||||
clientRep.setSecret(clientSecret);
|
clientRep.setSecret(clientSecret);
|
||||||
});
|
});
|
||||||
|
adminClient.realm(REALM_NAME).clients().get(cid).roles().create(RoleBuilder.create().name("sample-client-role").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
successfulLoginAndLogout(clientId, clientSecret);
|
successfulLoginAndLogout(clientId, clientSecret);
|
||||||
|
@ -497,10 +495,9 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
String clientId = "Zahlungs-App";
|
String clientId = "Zahlungs-App";
|
||||||
String clientSecret = "secret";
|
String clientSecret = "secret";
|
||||||
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
||||||
String[] defaultRoles = {"sample-client-role"};
|
|
||||||
clientRep.setDefaultRoles(defaultRoles);
|
|
||||||
clientRep.setSecret(clientSecret);
|
clientRep.setSecret(clientSecret);
|
||||||
});
|
});
|
||||||
|
adminClient.realm(REALM_NAME).clients().get(cid).roles().create(RoleBuilder.create().name("sample-client-role").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
successfulLoginAndLogout(clientId, clientSecret);
|
successfulLoginAndLogout(clientId, clientSecret);
|
||||||
|
@ -584,17 +581,21 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
String clientAlphaId = "Alpha-App";
|
String clientAlphaId = "Alpha-App";
|
||||||
String clientAlphaSecret = "secretAlpha";
|
String clientAlphaSecret = "secretAlpha";
|
||||||
String cAlphaId = createClientByAdmin(clientAlphaId, (ClientRepresentation clientRep) -> {
|
String cAlphaId = createClientByAdmin(clientAlphaId, (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role-alpha", "sample-client-role-common").toArray(new String[2]));
|
|
||||||
clientRep.setSecret(clientAlphaSecret);
|
clientRep.setSecret(clientAlphaSecret);
|
||||||
clientRep.setClientAuthenticatorType(JWTClientSecretAuthenticator.PROVIDER_ID);
|
clientRep.setClientAuthenticatorType(JWTClientSecretAuthenticator.PROVIDER_ID);
|
||||||
});
|
});
|
||||||
|
RolesResource rolesResourceAlpha = adminClient.realm(REALM_NAME).clients().get(cAlphaId).roles();
|
||||||
|
rolesResourceAlpha.create(RoleBuilder.create().name("sample-client-role-alpha").build());
|
||||||
|
rolesResourceAlpha.create(RoleBuilder.create().name("sample-client-role-common").build());
|
||||||
|
|
||||||
String clientBetaId = "Beta-App";
|
String clientBetaId = "Beta-App";
|
||||||
String clientBetaSecret = "secretBeta";
|
String clientBetaSecret = "secretBeta";
|
||||||
String cBetaId = createClientByAdmin(clientBetaId, (ClientRepresentation clientRep) -> {
|
String cBetaId = createClientByAdmin(clientBetaId, (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role-beta", "sample-client-role-common").toArray(new String[2]));
|
|
||||||
clientRep.setSecret(clientBetaSecret);
|
clientRep.setSecret(clientBetaSecret);
|
||||||
});
|
});
|
||||||
|
RolesResource rolesResourceBeta = adminClient.realm(REALM_NAME).clients().get(cBetaId).roles();
|
||||||
|
rolesResourceBeta.create(RoleBuilder.create().name("sample-client-role-beta").build());
|
||||||
|
rolesResourceBeta.create(RoleBuilder.create().name("sample-client-role-common").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertEquals(ClientIdAndSecretAuthenticator.PROVIDER_ID, getClientByAdmin(cAlphaId).getClientAuthenticatorType());
|
assertEquals(ClientIdAndSecretAuthenticator.PROVIDER_ID, getClientByAdmin(cAlphaId).getClientAuthenticatorType());
|
||||||
|
@ -649,13 +650,12 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
String clientId = "Zahlungs-App";
|
String clientId = "Zahlungs-App";
|
||||||
String clientSecret = "secret";
|
String clientSecret = "secret";
|
||||||
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
||||||
String[] defaultRoles = {"sample-client-role"};
|
|
||||||
clientRep.setDefaultRoles(defaultRoles);
|
|
||||||
clientRep.setSecret(clientSecret);
|
clientRep.setSecret(clientSecret);
|
||||||
clientRep.setStandardFlowEnabled(Boolean.TRUE);
|
clientRep.setStandardFlowEnabled(Boolean.TRUE);
|
||||||
clientRep.setImplicitFlowEnabled(Boolean.TRUE);
|
clientRep.setImplicitFlowEnabled(Boolean.TRUE);
|
||||||
clientRep.setPublicClient(Boolean.FALSE);
|
clientRep.setPublicClient(Boolean.FALSE);
|
||||||
});
|
});
|
||||||
|
adminClient.realm(REALM_NAME).clients().get(cid).roles().create(RoleBuilder.create().name("sample-client-role").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
oauth.clientId(clientId);
|
oauth.clientId(clientId);
|
||||||
|
@ -717,10 +717,9 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
String clientId = "Zahlungs-App";
|
String clientId = "Zahlungs-App";
|
||||||
String clientSecret = "secret";
|
String clientSecret = "secret";
|
||||||
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
|
||||||
String[] defaultRoles = {"sample-client-role"};
|
|
||||||
clientRep.setDefaultRoles(defaultRoles);
|
|
||||||
clientRep.setSecret(clientSecret);
|
clientRep.setSecret(clientSecret);
|
||||||
});
|
});
|
||||||
|
adminClient.realm(REALM_NAME).clients().get(cid).roles().create(RoleBuilder.create().name("sample-client-role").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
oauth.clientId(clientId);
|
oauth.clientId(clientId);
|
||||||
|
@ -822,16 +821,16 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
String clientAlphaId = "Alpha-App";
|
String clientAlphaId = "Alpha-App";
|
||||||
String clientAlphaSecret = "secretAlpha";
|
String clientAlphaSecret = "secretAlpha";
|
||||||
String cAlphaId = createClientByAdmin(clientAlphaId, (ClientRepresentation clientRep) -> {
|
String cAlphaId = createClientByAdmin(clientAlphaId, (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role-alpha").toArray(new String[1]));
|
|
||||||
clientRep.setSecret(clientAlphaSecret);
|
clientRep.setSecret(clientAlphaSecret);
|
||||||
});
|
});
|
||||||
|
adminClient.realm(REALM_NAME).clients().get(cAlphaId).roles().create(RoleBuilder.create().name("sample-client-role-alpha").build());
|
||||||
|
|
||||||
String clientBetaId = "Beta-App";
|
String clientBetaId = "Beta-App";
|
||||||
String clientBetaSecret = "secretBeta";
|
String clientBetaSecret = "secretBeta";
|
||||||
String cBetaId = createClientByAdmin(clientBetaId, (ClientRepresentation clientRep) -> {
|
String cBetaId = createClientByAdmin(clientBetaId, (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role-beta").toArray(new String[1]));
|
|
||||||
clientRep.setSecret(clientBetaSecret);
|
clientRep.setSecret(clientBetaSecret);
|
||||||
});
|
});
|
||||||
|
adminClient.realm(REALM_NAME).clients().get(cBetaId).roles().create(RoleBuilder.create().name("sample-client-role-beta").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
successfulLoginAndLogout(clientAlphaId, clientAlphaSecret);
|
successfulLoginAndLogout(clientAlphaId, clientAlphaSecret);
|
||||||
|
@ -923,7 +922,6 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
// create by Admin REST API - fail
|
// create by Admin REST API - fail
|
||||||
try {
|
try {
|
||||||
createClientByAdmin("App-by-Admin", (ClientRepresentation clientRep) -> {
|
createClientByAdmin("App-by-Admin", (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role-beta").toArray(new String[1]));
|
|
||||||
clientRep.setSecret("secretBeta");
|
clientRep.setSecret("secretBeta");
|
||||||
clientRep.setAttributes(new HashMap<>());
|
clientRep.setAttributes(new HashMap<>());
|
||||||
clientRep.getAttributes().put(OIDCConfigAttributes.USER_INFO_RESPONSE_SIGNATURE_ALG, Algorithm.none.name());
|
clientRep.getAttributes().put(OIDCConfigAttributes.USER_INFO_RESPONSE_SIGNATURE_ALG, Algorithm.none.name());
|
||||||
|
@ -966,7 +964,6 @@ public class ClientPolicyBasicsTest extends AbstractKeycloakTest {
|
||||||
// create dynamically - fail
|
// create dynamically - fail
|
||||||
try {
|
try {
|
||||||
createClientByAdmin("App-in-Dynamic", (ClientRepresentation clientRep) -> {
|
createClientByAdmin("App-in-Dynamic", (ClientRepresentation clientRep) -> {
|
||||||
clientRep.setDefaultRoles((String[]) Arrays.asList("sample-client-role-beta").toArray(new String[1]));
|
|
||||||
clientRep.setSecret("secretBeta");
|
clientRep.setSecret("secretBeta");
|
||||||
clientRep.setAttributes(new HashMap<>());
|
clientRep.setAttributes(new HashMap<>());
|
||||||
clientRep.getAttributes().put(OIDCConfigAttributes.USER_INFO_RESPONSE_SIGNATURE_ALG, Algorithm.RS384.name());
|
clientRep.getAttributes().put(OIDCConfigAttributes.USER_INFO_RESPONSE_SIGNATURE_ALG, Algorithm.RS384.name());
|
||||||
|
|
|
@ -101,10 +101,6 @@ public class ExportImportUtil {
|
||||||
Assert.assertEquals(1, creds.size());
|
Assert.assertEquals(1, creds.size());
|
||||||
String cred = (String)creds.iterator().next();
|
String cred = (String)creds.iterator().next();
|
||||||
Assert.assertEquals("password", cred);
|
Assert.assertEquals("password", cred);
|
||||||
Assert.assertEquals(4, realm.getDefaultRoles().size());
|
|
||||||
|
|
||||||
Assert.assertNotNull(RealmRepUtil.findDefaultRole(realm, "foo"));
|
|
||||||
Assert.assertNotNull(RealmRepUtil.findDefaultRole(realm, "bar"));
|
|
||||||
|
|
||||||
RealmResource realmRsc = adminClient.realm(realm.getRealm());
|
RealmResource realmRsc = adminClient.realm(realm.getRealm());
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,6 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
ClientModel accountApp = appRealm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
ClientModel accountApp = appRealm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||||
ClientModel financeApp = appRealm.getClientByClientId("finance");
|
ClientModel financeApp = appRealm.getClientByClientId("finance");
|
||||||
|
|
||||||
RoleModel manageAccountRole = accountApp.getRole(AccountRoles.MANAGE_ACCOUNT);
|
|
||||||
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
||||||
john.grantRole(financeRole1);
|
john.grantRole(financeRole1);
|
||||||
|
|
||||||
|
@ -163,7 +162,6 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
Assert.assertFalse(johnDbRoles.contains(realmRole2));
|
Assert.assertFalse(johnDbRoles.contains(realmRole2));
|
||||||
Assert.assertFalse(johnDbRoles.contains(realmRole3));
|
Assert.assertFalse(johnDbRoles.contains(realmRole3));
|
||||||
Assert.assertFalse(johnDbRoles.contains(financeRole1));
|
Assert.assertFalse(johnDbRoles.contains(financeRole1));
|
||||||
Assert.assertTrue(johnDbRoles.contains(manageAccountRole));
|
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
|
@ -172,17 +170,12 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
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));
|
|
||||||
|
|
||||||
Set<RoleModel> johnRealmRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
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
|
|
||||||
Set<RoleModel> johnAccountRoles = john.getClientRoleMappingsStream(accountApp).collect(Collectors.toSet());
|
|
||||||
Assert.assertTrue(johnAccountRoles.contains(manageAccountRole));
|
|
||||||
|
|
||||||
Set<RoleModel> johnFinanceRoles = john.getClientRoleMappingsStream(financeApp).collect(Collectors.toSet());
|
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));
|
||||||
|
@ -192,19 +185,16 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
john.deleteRoleMapping(realmRole3);
|
john.deleteRoleMapping(realmRole3);
|
||||||
john.deleteRoleMapping(realmRole1);
|
john.deleteRoleMapping(realmRole1);
|
||||||
john.deleteRoleMapping(financeRole1);
|
john.deleteRoleMapping(financeRole1);
|
||||||
john.deleteRoleMapping(manageAccountRole);
|
|
||||||
|
|
||||||
johnRoles = john.getRoleMappingsStream().collect(Collectors.toSet());
|
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));
|
||||||
Assert.assertFalse(johnRoles.contains(financeRole1));
|
Assert.assertFalse(johnRoles.contains(financeRole1));
|
||||||
Assert.assertFalse(johnRoles.contains(manageAccountRole));
|
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
mary.deleteRoleMapping(realmRole2);
|
mary.deleteRoleMapping(realmRole2);
|
||||||
mary.deleteRoleMapping(realmRole3);
|
mary.deleteRoleMapping(realmRole3);
|
||||||
john.grantRole(manageAccountRole);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,9 +480,6 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = ctx.getRealm();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// Set a default role on the realm
|
|
||||||
appRealm.addDefaultRole("realmRole1");
|
|
||||||
|
|
||||||
UserModel david = session.users().addUser(appRealm, "davidkeycloak");
|
UserModel david = session.users().addUser(appRealm, "davidkeycloak");
|
||||||
|
|
||||||
RoleModel defaultRole = appRealm.getRole("realmRole1");
|
RoleModel defaultRole = appRealm.getRole("realmRole1");
|
||||||
|
@ -501,11 +488,18 @@ public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
Assert.assertNotNull(defaultRole);
|
Assert.assertNotNull(defaultRole);
|
||||||
Assert.assertNotNull(realmRole2);
|
Assert.assertNotNull(realmRole2);
|
||||||
|
|
||||||
|
// Set a default role on the realm
|
||||||
|
appRealm.addToDefaultRoles(defaultRole);
|
||||||
|
|
||||||
Set<RoleModel> davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
Set<RoleModel> davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
||||||
|
|
||||||
Assert.assertTrue(davidRoles.contains(defaultRole));
|
// default role is not assigned directly
|
||||||
|
Assert.assertFalse(davidRoles.contains(defaultRole));
|
||||||
Assert.assertFalse(davidRoles.contains(realmRole2));
|
Assert.assertFalse(davidRoles.contains(realmRole2));
|
||||||
|
|
||||||
|
// but david should have the role as effective
|
||||||
|
Assert.assertTrue(david.hasRole(defaultRole));
|
||||||
|
Assert.assertFalse(david.hasRole(realmRole2));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,6 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
|
||||||
RoleModel realmRole3 = appRealm.getRole("realmRole3");
|
RoleModel realmRole3 = appRealm.getRole("realmRole3");
|
||||||
ClientModel accountApp = appRealm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
ClientModel accountApp = appRealm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||||
ClientModel financeApp = appRealm.getClientByClientId("finance");
|
ClientModel financeApp = appRealm.getClientByClientId("finance");
|
||||||
RoleModel manageAccountRole = accountApp.getRole(AccountRoles.MANAGE_ACCOUNT);
|
|
||||||
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -257,17 +256,12 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
|
||||||
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));
|
|
||||||
|
|
||||||
Set<RoleModel> johnRealmRoles = john.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
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
|
|
||||||
Set<RoleModel> johnAccountRoles = john.getClientRoleMappingsStream(accountApp).collect(Collectors.toSet());
|
|
||||||
Assert.assertTrue(johnAccountRoles.contains(manageAccountRole));
|
|
||||||
|
|
||||||
Set<RoleModel> johnFinanceRoles = john.getClientRoleMappingsStream(financeApp).collect(Collectors.toSet());
|
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));
|
||||||
|
@ -303,9 +297,6 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
|
|
||||||
// Set a default role on the realm
|
|
||||||
appRealm.addDefaultRole("realmRole1");
|
|
||||||
|
|
||||||
UserModel david = session.users().addUser(appRealm, "davidkeycloak");
|
UserModel david = session.users().addUser(appRealm, "davidkeycloak");
|
||||||
|
|
||||||
// make sure we are in no-import mode
|
// make sure we are in no-import mode
|
||||||
|
@ -317,16 +308,23 @@ public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
|
||||||
Assert.assertNotNull(defaultRole);
|
Assert.assertNotNull(defaultRole);
|
||||||
Assert.assertNotNull(realmRole2);
|
Assert.assertNotNull(realmRole2);
|
||||||
|
|
||||||
|
// Set a default role on the realm
|
||||||
|
appRealm.addToDefaultRoles(defaultRole);
|
||||||
|
|
||||||
Set<RoleModel> davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
Set<RoleModel> davidRoles = david.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
||||||
|
|
||||||
Assert.assertTrue(davidRoles.contains(defaultRole));
|
// default role is not assigned directly
|
||||||
|
Assert.assertFalse(davidRoles.contains(defaultRole));
|
||||||
Assert.assertFalse(davidRoles.contains(realmRole2));
|
Assert.assertFalse(davidRoles.contains(realmRole2));
|
||||||
|
|
||||||
|
// but david should have the role as effective
|
||||||
|
Assert.assertTrue(david.hasRole(defaultRole));
|
||||||
|
Assert.assertFalse(david.hasRole(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.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
|
||||||
|
|
||||||
Assert.assertFalse(johnRoles.contains(defaultRole));
|
Assert.assertFalse(john.hasRole(defaultRole));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,4 +46,11 @@ public abstract class AbstractJsonFileImportMigrationTest extends AbstractMigrat
|
||||||
Assert.assertThat(migrationRealm.toRepresentation().getRealm(), is(equalTo("Migration")));
|
Assert.assertThat(migrationRealm.toRepresentation().getRealm(), is(equalTo("Migration")));
|
||||||
Assert.assertThat(migrationRealm2.toRepresentation().getRealm(), is(equalTo("Migration2")));
|
Assert.assertThat(migrationRealm2.toRepresentation().getRealm(), is(equalTo("Migration2")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void testMigrationTo13_0_0() {
|
||||||
|
testDefaultRoles(migrationRealm);
|
||||||
|
|
||||||
|
testDefaultRolesNameWhenTaken();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,9 @@ import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.admin.ApiUtil;
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
import org.keycloak.testsuite.arquillian.migration.MigrationContext;
|
|
||||||
import org.keycloak.testsuite.exportimport.ExportImportUtil;
|
import org.keycloak.testsuite.exportimport.ExportImportUtil;
|
||||||
import org.keycloak.testsuite.runonserver.RunHelpers;
|
import org.keycloak.testsuite.runonserver.RunHelpers;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.WaitUtils;
|
|
||||||
import org.keycloak.util.TokenUtil;
|
import org.keycloak.util.TokenUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -83,11 +81,15 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
|
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
|
||||||
|
@ -120,7 +122,7 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigratedMigrationData(boolean supportsAuthzService) {
|
protected void testMigratedMigrationData(boolean supportsAuthzService) {
|
||||||
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "default-roles-migration", "migration-test-realm-role");
|
||||||
List<String> expectedClientIds = new ArrayList<>(Arrays.asList("account", "account-console", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console"));
|
List<String> expectedClientIds = new ArrayList<>(Arrays.asList("account", "account-console", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console"));
|
||||||
|
|
||||||
if (supportsAuthzService) {
|
if (supportsAuthzService) {
|
||||||
|
@ -136,7 +138,7 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigratedMasterData() {
|
protected void testMigratedMasterData() {
|
||||||
assertNames(masterRealm.roles().list(), "offline_access", "uma_authorization", "create-realm", "master-test-realm-role", "admin");
|
assertNames(masterRealm.roles().list(), "offline_access", "uma_authorization", "default-roles-master", "create-realm", "master-test-realm-role", "admin");
|
||||||
assertNames(masterRealm.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account", "account-console",
|
assertNames(masterRealm.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account", "account-console",
|
||||||
"master-realm", "master-test-client", "Migration-realm", "Migration2-realm");
|
"master-realm", "master-test-client", "Migration-realm", "Migration2-realm");
|
||||||
String id = masterRealm.clients().findByClientId("master-test-client").get(0).getId();
|
String id = masterRealm.clients().findByClientId("master-test-client").get(0).getId();
|
||||||
|
@ -290,7 +292,14 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
testDeleteAccount(migrationRealm);
|
testDeleteAccount(migrationRealm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testDeleteAccount(RealmResource realm) {
|
protected void testMigrationTo13_0_0() {
|
||||||
|
testDefaultRoles(masterRealm);
|
||||||
|
testDefaultRoles(migrationRealm);
|
||||||
|
|
||||||
|
testDefaultRolesNameWhenTaken();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testDeleteAccount(RealmResource realm) {
|
||||||
ClientRepresentation accountClient = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0);
|
ClientRepresentation accountClient = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0);
|
||||||
ClientResource accountResource = realm.clients().get(accountClient.getId());
|
ClientResource accountResource = realm.clients().get(accountClient.getId());
|
||||||
|
|
||||||
|
@ -570,7 +579,8 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
assertFalse("Role shouldn't be composite should be false.", role.toRepresentation().isComposite());
|
assertFalse("Role shouldn't be composite should be false.", role.toRepresentation().isComposite());
|
||||||
|
|
||||||
assertTrue("role should be added to default roles for new users", realm.toRepresentation().getDefaultRoles().contains(roleName));
|
assertThat("role should be added to default roles for new users", realm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.toRepresentation().getRealm().toLowerCase()).getRoleComposites().stream()
|
||||||
|
.map(RoleRepresentation::getName).collect(Collectors.toSet()), hasItem(roleName));
|
||||||
}
|
}
|
||||||
//test admin roles - master admin client
|
//test admin roles - master admin client
|
||||||
List<ClientRepresentation> clients = realm.clients().findByClientId(realm.toRepresentation().getRealm() + "-realm");
|
List<ClientRepresentation> clients = realm.clients().findByClientId(realm.toRepresentation().getRealm() + "-realm");
|
||||||
|
@ -902,9 +912,9 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
protected void testMigrationTo9_x() {
|
protected void testMigrationTo9_x() {
|
||||||
testMigrationTo9_0_0();
|
testMigrationTo9_0_0();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo12_x() {
|
protected void testMigrationTo12_x() {
|
||||||
testMigrationTo12_0_0();
|
testMigrationTo12_0_0();
|
||||||
|
testMigrationTo13_0_0();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo7_x(boolean supportedAuthzServices) {
|
protected void testMigrationTo7_x(boolean supportedAuthzServices) {
|
||||||
|
@ -930,4 +940,19 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
Assert.assertFalse(clientRep.isAlwaysDisplayInConsole());
|
Assert.assertFalse(clientRep.isAlwaysDisplayInConsole());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void testDefaultRoles(RealmResource realm) {
|
||||||
|
String realmName = realm.toRepresentation().getRealm().toLowerCase();
|
||||||
|
assertThat(realm.roles().get("default-roles-" + realmName).getRoleComposites().stream()
|
||||||
|
.map(RoleRepresentation::getName).collect(Collectors.toSet()),
|
||||||
|
allOf(
|
||||||
|
hasItem(realmName + "-test-realm-role"),
|
||||||
|
hasItem(realmName + "-test-client-role"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testDefaultRolesNameWhenTaken() {
|
||||||
|
// 'default-roles-migration2' name is used, we test that 'default-roles-migration2-1' is created instead
|
||||||
|
assertThat(migrationRealm2.toRepresentation().getDefaultRole().getName(), equalTo("default-roles-migration2-1"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ import static org.hamcrest.core.Is.is;
|
||||||
import static org.hamcrest.core.IsNull.notNullValue;
|
import static org.hamcrest.core.IsNull.notNullValue;
|
||||||
import static org.hamcrest.core.IsNull.nullValue;
|
import static org.hamcrest.core.IsNull.nullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
import static org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer.REMOTE;
|
import static org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer.REMOTE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -248,6 +250,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak
|
||||||
KeycloakSession currentSession = sesRealmRemoved1;
|
KeycloakSession currentSession = sesRealmRemoved1;
|
||||||
RealmModel realm = currentSession.realms().getRealm("test");
|
RealmModel realm = currentSession.realms().getRealm("test");
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo-realm");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo-realm");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName()));
|
||||||
|
|
||||||
fooRealm.addClient("foo-client");
|
fooRealm.addClient("foo-client");
|
||||||
|
|
||||||
|
|
|
@ -79,9 +79,6 @@ 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.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));
|
||||||
assertThat(expected.getRegisteredNodes(), is(actual.getRegisteredNodes()));
|
assertThat(expected.getRegisteredNodes(), is(actual.getRegisteredNodes()));
|
||||||
|
@ -99,8 +96,6 @@ public class ClientModelTest extends AbstractKeycloakTest {
|
||||||
client.addRole("role-1");
|
client.addRole("role-1");
|
||||||
client.addRole("role-2");
|
client.addRole("role-2");
|
||||||
client.addRole("role-3");
|
client.addRole("role-3");
|
||||||
client.addDefaultRole("role-1");
|
|
||||||
client.addDefaultRole("role-2");
|
|
||||||
client.addRedirectUri("redirect-1");
|
client.addRedirectUri("redirect-1");
|
||||||
client.addRedirectUri("redirect-2");
|
client.addRedirectUri("redirect-2");
|
||||||
client.addWebOrigin("origin-1");
|
client.addWebOrigin("origin-1");
|
||||||
|
@ -288,7 +283,7 @@ public class ClientModelTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
realm = currentSession.realms().createRealm("copy");
|
realm = currentSession.realms().createRealm("copy");
|
||||||
ClientModel copyClient = RepresentationToModel.createClient(currentSession, realm, representation, true);
|
ClientModel copyClient = RepresentationToModel.createClient(currentSession, realm, representation);
|
||||||
|
|
||||||
assertEquals(client, copyClient);
|
assertEquals(client, copyClient);
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
|
|
||||||
|
@ -68,6 +70,8 @@ public class ConcurrentTransactionsTest extends AbstractTestRealmKeycloakTest {
|
||||||
sessionSetup.users().addUser(realm, "user2").setEmail("user2@localhost");
|
sessionSetup.users().addUser(realm, "user2").setEmail("user2@localhost");
|
||||||
|
|
||||||
realm = sessionSetup.realms().createRealm("original");
|
realm = sessionSetup.realms().createRealm("original");
|
||||||
|
RoleModel defaultRole = sessionSetup.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName());
|
||||||
|
realm.setDefaultRole(defaultRole);
|
||||||
|
|
||||||
client[0] = sessionSetup.clients().addClient(realm, "client");
|
client[0] = sessionSetup.clients().addClient(realm, "client");
|
||||||
client[0].setSecret("old");
|
client[0].setSecret("old");
|
||||||
|
@ -195,6 +199,7 @@ public class ConcurrentTransactionsTest extends AbstractTestRealmKeycloakTest {
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSet) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSet) -> {
|
||||||
|
|
||||||
RealmModel realm = sessionSet.realms().createRealm("original");
|
RealmModel realm = sessionSet.realms().createRealm("original");
|
||||||
|
realm.setDefaultRole(sessionSet.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
|
||||||
|
|
||||||
UserModel john = sessionSet.users().addUser(realm, "john");
|
UserModel john = sessionSet.users().addUser(realm, "john");
|
||||||
john.setSingleAttribute("foo", "val1");
|
john.setSingleAttribute("foo", "val1");
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
|
|
||||||
|
@ -70,6 +71,9 @@ public class MultipleRealmsTest extends AbstractTestRealmKeycloakTest {
|
||||||
RealmModel realm1 = currentSession.realms().createRealm("id1", "realm1");
|
RealmModel realm1 = currentSession.realms().createRealm("id1", "realm1");
|
||||||
RealmModel realm2 = currentSession.realms().createRealm("id2", "realm2");
|
RealmModel realm2 = currentSession.realms().createRealm("id2", "realm2");
|
||||||
|
|
||||||
|
realm1.setDefaultRole(currentSession.roles().addRealmRole(realm1, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm1.getName()));
|
||||||
|
realm2.setDefaultRole(currentSession.roles().addRealmRole(realm2, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm2.getName()));
|
||||||
|
|
||||||
createObjects(currentSession, realm1);
|
createObjects(currentSession, realm1);
|
||||||
createObjects(currentSession, realm2);
|
createObjects(currentSession, realm2);
|
||||||
|
|
||||||
|
@ -137,6 +141,9 @@ public class MultipleRealmsTest extends AbstractTestRealmKeycloakTest {
|
||||||
RealmModel realm1 = currentSession.realms().createRealm("id1", "realm1");
|
RealmModel realm1 = currentSession.realms().createRealm("id1", "realm1");
|
||||||
RealmModel realm2 = currentSession.realms().createRealm("id2", "realm2");
|
RealmModel realm2 = currentSession.realms().createRealm("id2", "realm2");
|
||||||
|
|
||||||
|
realm1.setDefaultRole(currentSession.roles().addRealmRole(realm1, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm1.getName()));
|
||||||
|
realm2.setDefaultRole(currentSession.roles().addRealmRole(realm2, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm2.getName()));
|
||||||
|
|
||||||
createObjects(currentSession, realm1);
|
createObjects(currentSession, realm1);
|
||||||
createObjects(currentSession, realm2);
|
createObjects(currentSession, realm2);
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,6 @@ public class OwnerReplacementTest extends AbstractKeycloakTest {
|
||||||
((session, realm1) -> {
|
((session, realm1) -> {
|
||||||
|
|
||||||
RoleModel role = session.getProvider(RoleProvider.class).addRealmRole(realm1, "foo");
|
RoleModel role = session.getProvider(RoleProvider.class).addRealmRole(realm1, "foo");
|
||||||
realm1.addDefaultRole("foo");
|
|
||||||
return role.getId();
|
return role.getId();
|
||||||
|
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||||
import org.keycloak.testsuite.runonserver.RunOnServerException;
|
import org.keycloak.testsuite.runonserver.RunOnServerException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
|
|
||||||
|
@ -61,7 +62,8 @@ public class SimpleModelTest extends AbstractKeycloakTest {
|
||||||
// Transaction 1
|
// Transaction 1
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> {
|
||||||
|
|
||||||
session1.realms().createRealm("foo");
|
RealmModel realm = session1.realms().createRealm("foo");
|
||||||
|
realm.setDefaultRole(session1.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,6 +229,7 @@ public class UserSessionPersisterProviderTest extends AbstractTestRealmKeycloakT
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR1) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR1) -> {
|
||||||
KeycloakSession currentSession = sessionRR1;
|
KeycloakSession currentSession = sessionRR1;
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName()));
|
||||||
|
|
||||||
fooRealm.addClient("foo-app");
|
fooRealm.addClient("foo-app");
|
||||||
currentSession.users().addUser(fooRealm, "user3");
|
currentSession.users().addUser(fooRealm, "user3");
|
||||||
|
@ -275,6 +277,7 @@ public class UserSessionPersisterProviderTest extends AbstractTestRealmKeycloakT
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR1) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR1) -> {
|
||||||
KeycloakSession currentSession = sessionCR1;
|
KeycloakSession currentSession = sessionCR1;
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX));
|
||||||
|
|
||||||
fooRealm.addClient("foo-app");
|
fooRealm.addClient("foo-app");
|
||||||
fooRealm.addClient("bar-app");
|
fooRealm.addClient("bar-app");
|
||||||
|
|
|
@ -53,6 +53,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,6 +227,7 @@ public class UserSessionProviderOfflineTest extends AbstractTestRealmKeycloakTes
|
||||||
currentSession = sessionRR1;
|
currentSession = sessionRR1;
|
||||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName()));
|
||||||
fooRealm.addClient("foo-app");
|
fooRealm.addClient("foo-app");
|
||||||
currentSession.users().addUser(fooRealm, "user3");
|
currentSession.users().addUser(fooRealm, "user3");
|
||||||
|
|
||||||
|
@ -258,6 +260,7 @@ public class UserSessionProviderOfflineTest extends AbstractTestRealmKeycloakTes
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR3) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR3) -> {
|
||||||
currentSession = sessionRR3;
|
currentSession = sessionRR3;
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName()));
|
||||||
|
|
||||||
fooRealm.addClient("foo-app");
|
fooRealm.addClient("foo-app");
|
||||||
currentSession.users().addUser(fooRealm, "user3");
|
currentSession.users().addUser(fooRealm, "user3");
|
||||||
|
@ -289,6 +292,7 @@ public class UserSessionProviderOfflineTest extends AbstractTestRealmKeycloakTes
|
||||||
sessionManager = new UserSessionManager(currentSession);
|
sessionManager = new UserSessionManager(currentSession);
|
||||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName()));
|
||||||
|
|
||||||
fooRealm.addClient("foo-app");
|
fooRealm.addClient("foo-app");
|
||||||
fooRealm.addClient("bar-app");
|
fooRealm.addClient("bar-app");
|
||||||
|
@ -381,6 +385,7 @@ public class UserSessionProviderOfflineTest extends AbstractTestRealmKeycloakTes
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUR1) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUR1) -> {
|
||||||
currentSession = sessionUR1;
|
currentSession = sessionUR1;
|
||||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||||
|
fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName()));
|
||||||
fooRealm.addClient("foo-app");
|
fooRealm.addClient("foo-app");
|
||||||
currentSession.users().addUser(fooRealm, "user3");
|
currentSession.users().addUser(fooRealm, "user3");
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ import static org.junit.Assert.assertThat;
|
||||||
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO;
|
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO;
|
||||||
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
||||||
import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT;
|
import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT;
|
||||||
|
import org.keycloak.testsuite.util.RoleBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author pedroigor
|
* @author pedroigor
|
||||||
|
@ -177,13 +178,12 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
||||||
// KEYCLOAK-8838
|
// KEYCLOAK-8838
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_dotsInClientId() throws Exception {
|
public void testSuccess_dotsInClientId() throws Exception {
|
||||||
// Create client with dot in the name and with some role
|
// Create client with dot in the name
|
||||||
ClientRepresentation clientRep = org.keycloak.testsuite.util.ClientBuilder.create()
|
ClientRepresentation clientRep = org.keycloak.testsuite.util.ClientBuilder.create()
|
||||||
.clientId("my.foo.client")
|
.clientId("my.foo.client")
|
||||||
.addRedirectUri("http://foo.host")
|
.addRedirectUri("http://foo.host")
|
||||||
.secret("password")
|
.secret("password")
|
||||||
.directAccessGrants()
|
.directAccessGrants()
|
||||||
.defaultRoles("my.foo.role")
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RealmResource realm = adminClient.realm("test");
|
RealmResource realm = adminClient.realm("test");
|
||||||
|
@ -193,6 +193,9 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
||||||
resp.close();
|
resp.close();
|
||||||
getCleanup().addClientUuid(clientUUID);
|
getCleanup().addClientUuid(clientUUID);
|
||||||
|
|
||||||
|
//Create role with dot in the name
|
||||||
|
realm.clients().get(clientUUID).roles().create(RoleBuilder.create().name("my.foo.role").build());
|
||||||
|
|
||||||
// Assign role to the user
|
// Assign role to the user
|
||||||
RoleRepresentation fooRole = realm.clients().get(clientUUID).roles().get("my.foo.role").toRepresentation();
|
RoleRepresentation fooRole = realm.clients().get(clientUUID).roles().get("my.foo.role").toRepresentation();
|
||||||
UserResource userResource = ApiUtil.findUserByUsernameId(realm, "test-user@localhost");
|
UserResource userResource = ApiUtil.findUserByUsernameId(realm, "test-user@localhost");
|
||||||
|
|
|
@ -73,6 +73,7 @@ public class ClientBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public ClientBuilder defaultRoles(String... roles) {
|
public ClientBuilder defaultRoles(String... roles) {
|
||||||
rep.setDefaultRoles(roles);
|
rep.setDefaultRoles(roles);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -324,7 +324,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access" ],
|
"defaultRoles" : [ "offline_access", "master-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"passwordPolicy" : "hashIterations(20000)",
|
"passwordPolicy" : "hashIterations(20000)",
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
|
@ -1012,6 +1012,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "83dadb00-0510-4cae-b0dc-1ce1a1969ae3",
|
"secret" : "83dadb00-0510-4cae-b0dc-1ce1a1969ae3",
|
||||||
|
"defaultRoles" : [ "master-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -1727,7 +1728,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access" ],
|
"defaultRoles" : [ "offline_access", "migration-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"passwordPolicy" : "hashIterations(20000)",
|
"passwordPolicy" : "hashIterations(20000)",
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
|
@ -2126,6 +2127,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "secret",
|
"secret" : "secret",
|
||||||
|
"defaultRoles" : [ "migration-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -2815,6 +2817,12 @@
|
||||||
"description" : "${role_offline-access}",
|
"description" : "${role_offline-access}",
|
||||||
"scopeParamRequired" : true,
|
"scopeParamRequired" : true,
|
||||||
"composite" : false
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "a495da40-f44c-4e28-8f82-75bb5677e597",
|
||||||
|
"name" : "default-roles-migration2",
|
||||||
|
"description" : "${role_default-roles}",
|
||||||
|
"scopeParamRequired" : true,
|
||||||
|
"composite" : false
|
||||||
} ],
|
} ],
|
||||||
"client" : {
|
"client" : {
|
||||||
"realm-management" : [ {
|
"realm-management" : [ {
|
||||||
|
|
|
@ -466,7 +466,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "master-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"passwordPolicy" : "hashIterations(20000)",
|
"passwordPolicy" : "hashIterations(20000)",
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
|
@ -1181,6 +1181,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "4f427905-9843-4986-9d6c-97a304055f92",
|
"secret" : "4f427905-9843-4986-9d6c-97a304055f92",
|
||||||
|
"defaultRoles" : [ "master-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -2076,7 +2077,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "migration-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"passwordPolicy" : "hashIterations(20000)",
|
"passwordPolicy" : "hashIterations(20000)",
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
|
@ -2499,6 +2500,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "secret",
|
"secret" : "secret",
|
||||||
|
"defaultRoles" : [ "migration-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -3434,6 +3436,12 @@
|
||||||
"composite" : false,
|
"composite" : false,
|
||||||
"clientRole" : false,
|
"clientRole" : false,
|
||||||
"containerId" : "Migration2"
|
"containerId" : "Migration2"
|
||||||
|
}, {
|
||||||
|
"id" : "a495da40-f44c-4e28-8f82-75bb5677e597",
|
||||||
|
"name" : "default-roles-migration2",
|
||||||
|
"description" : "${role_default-roles}",
|
||||||
|
"scopeParamRequired" : true,
|
||||||
|
"composite" : false
|
||||||
} ],
|
} ],
|
||||||
"client" : {
|
"client" : {
|
||||||
"realm-management" : [ {
|
"realm-management" : [ {
|
||||||
|
|
|
@ -287,7 +287,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "migration-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
"otpPolicyAlgorithm" : "HmacSHA1",
|
"otpPolicyAlgorithm" : "HmacSHA1",
|
||||||
|
@ -708,6 +708,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "secret",
|
"secret" : "secret",
|
||||||
|
"defaultRoles" : [ "migration-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -1683,6 +1684,12 @@
|
||||||
"composite" : false,
|
"composite" : false,
|
||||||
"clientRole" : false,
|
"clientRole" : false,
|
||||||
"containerId" : "Migration2"
|
"containerId" : "Migration2"
|
||||||
|
}, {
|
||||||
|
"id" : "a495da40-f44c-4e28-8f82-75bb5677e597",
|
||||||
|
"name" : "default-roles-migration2",
|
||||||
|
"description" : "${role_default-roles}",
|
||||||
|
"scopeParamRequired" : true,
|
||||||
|
"composite" : false
|
||||||
} ],
|
} ],
|
||||||
"client" : {
|
"client" : {
|
||||||
"realm-management" : [ {
|
"realm-management" : [ {
|
||||||
|
@ -3553,7 +3560,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "master-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
"otpPolicyAlgorithm" : "HmacSHA1",
|
"otpPolicyAlgorithm" : "HmacSHA1",
|
||||||
|
@ -4266,6 +4273,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "932dd4b7-42e8-44d6-9791-651bec2a757b",
|
"secret" : "932dd4b7-42e8-44d6-9791-651bec2a757b",
|
||||||
|
"defaultRoles" : [ "master-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
|
|
@ -292,7 +292,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "migration-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
"otpPolicyAlgorithm" : "HmacSHA1",
|
"otpPolicyAlgorithm" : "HmacSHA1",
|
||||||
|
@ -509,6 +509,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "secret",
|
"secret" : "secret",
|
||||||
|
"defaultRoles" : [ "migration-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -1584,6 +1585,12 @@
|
||||||
"clientRole" : false,
|
"clientRole" : false,
|
||||||
"containerId" : "Migration2",
|
"containerId" : "Migration2",
|
||||||
"attributes" : { }
|
"attributes" : { }
|
||||||
|
}, {
|
||||||
|
"id" : "a495da40-f44c-4e28-8f82-75bb5677e597",
|
||||||
|
"name" : "default-roles-migration2",
|
||||||
|
"description" : "${role_default-roles}",
|
||||||
|
"scopeParamRequired" : true,
|
||||||
|
"composite" : false
|
||||||
} ],
|
} ],
|
||||||
"client" : {
|
"client" : {
|
||||||
"realm-management" : [ {
|
"realm-management" : [ {
|
||||||
|
@ -3508,7 +3515,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "master-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
"otpPolicyAlgorithm" : "HmacSHA1",
|
"otpPolicyAlgorithm" : "HmacSHA1",
|
||||||
|
@ -3727,6 +3734,7 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "21e5b3ab-d978-4552-bbb5-dead19284b5d",
|
"secret" : "21e5b3ab-d978-4552-bbb5-dead19284b5d",
|
||||||
|
"defaultRoles" : [ "master-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
|
|
@ -320,7 +320,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "offline_access", "uma_authorization" ],
|
"defaultRoles" : [ "offline_access", "uma_authorization", "migration-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
"otpPolicyAlgorithm" : "HmacSHA1",
|
"otpPolicyAlgorithm" : "HmacSHA1",
|
||||||
|
@ -534,6 +534,7 @@
|
||||||
"alwaysDisplayInConsole" : false,
|
"alwaysDisplayInConsole" : false,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "ff12b4c2-abba-4b88-a76b-ffbdb4d725fd",
|
"secret" : "ff12b4c2-abba-4b88-a76b-ffbdb4d725fd",
|
||||||
|
"defaultRoles" : [ "migration-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -1762,6 +1763,12 @@
|
||||||
"clientRole" : false,
|
"clientRole" : false,
|
||||||
"containerId" : "Migration2",
|
"containerId" : "Migration2",
|
||||||
"attributes" : { }
|
"attributes" : { }
|
||||||
|
}, {
|
||||||
|
"id" : "a495da40-f44c-4e28-8f82-75bb5677e597",
|
||||||
|
"name" : "default-roles-migration2",
|
||||||
|
"description" : "${role_default-roles}",
|
||||||
|
"scopeParamRequired" : true,
|
||||||
|
"composite" : false
|
||||||
} ],
|
} ],
|
||||||
"client" : {
|
"client" : {
|
||||||
"realm-management" : [ {
|
"realm-management" : [ {
|
||||||
|
@ -3968,7 +3975,7 @@
|
||||||
"clientRoles" : { },
|
"clientRoles" : { },
|
||||||
"subGroups" : [ ]
|
"subGroups" : [ ]
|
||||||
} ],
|
} ],
|
||||||
"defaultRoles" : [ "uma_authorization", "offline_access" ],
|
"defaultRoles" : [ "uma_authorization", "offline_access", "master-test-realm-role" ],
|
||||||
"requiredCredentials" : [ "password" ],
|
"requiredCredentials" : [ "password" ],
|
||||||
"otpPolicyType" : "totp",
|
"otpPolicyType" : "totp",
|
||||||
"otpPolicyAlgorithm" : "HmacSHA1",
|
"otpPolicyAlgorithm" : "HmacSHA1",
|
||||||
|
@ -4255,6 +4262,7 @@
|
||||||
"alwaysDisplayInConsole" : false,
|
"alwaysDisplayInConsole" : false,
|
||||||
"clientAuthenticatorType" : "client-secret",
|
"clientAuthenticatorType" : "client-secret",
|
||||||
"secret" : "a7064a25-7d2d-4a2d-a916-e7b033870803",
|
"secret" : "a7064a25-7d2d-4a2d-a916-e7b033870803",
|
||||||
|
"defaultRoles" : [ "master-test-client-role" ],
|
||||||
"redirectUris" : [ ],
|
"redirectUris" : [ ],
|
||||||
"webOrigins" : [ ],
|
"webOrigins" : [ ],
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
|
|
@ -14,6 +14,8 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
import org.keycloak.testsuite.console.page.roles.DefaultRoles;
|
||||||
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
|
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
|
||||||
import static org.keycloak.testsuite.util.WaitUtils.pause;
|
import static org.keycloak.testsuite.util.WaitUtils.pause;
|
||||||
|
|
||||||
|
@ -30,6 +32,8 @@ public class RealmRolesTest extends AbstractRolesTest {
|
||||||
private CreateRole createRolePage;
|
private CreateRole createRolePage;
|
||||||
@Page
|
@Page
|
||||||
private RoleDetails roleDetailsPage;
|
private RoleDetails roleDetailsPage;
|
||||||
|
@Page
|
||||||
|
private DefaultRoles defaultRolesPage;
|
||||||
|
|
||||||
private RoleRepresentation testRole;
|
private RoleRepresentation testRole;
|
||||||
|
|
||||||
|
@ -123,6 +127,24 @@ public class RealmRolesTest extends AbstractRolesTest {
|
||||||
assertAlertDanger();
|
assertAlertDanger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultRoleWithinRoleList() {
|
||||||
|
//test role name link leads to Default Roles tab
|
||||||
|
configure().roles();
|
||||||
|
realmRolesPage.table().clickRole(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
defaultRolesPage.assertCurrent();
|
||||||
|
|
||||||
|
//test role edit button leads to Default Roles tab
|
||||||
|
configure().roles();
|
||||||
|
realmRolesPage.table().editRole(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
defaultRolesPage.assertCurrent();
|
||||||
|
|
||||||
|
//test delete default role doesn't work
|
||||||
|
configure().roles();
|
||||||
|
realmRolesPage.table().deleteRole(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test");
|
||||||
|
assertTrue(realmRolesPage.table().containsRole(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-test"));
|
||||||
|
}
|
||||||
|
|
||||||
public void createTestRoles(String namePrefix, int count) {
|
public void createTestRoles(String namePrefix, int count) {
|
||||||
Timer.DEFAULT.reset();
|
Timer.DEFAULT.reset();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.keycloak.testsuite.model;
|
package org.keycloak.testsuite.model;
|
||||||
|
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
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;
|
||||||
|
@ -67,6 +68,7 @@ public class UserModelTest extends KeycloakModelTest {
|
||||||
@Override
|
@Override
|
||||||
public void createEnvironment(KeycloakSession s) {
|
public void createEnvironment(KeycloakSession s) {
|
||||||
RealmModel realm = s.realms().createRealm("realm");
|
RealmModel realm = s.realms().createRealm("realm");
|
||||||
|
realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
|
||||||
this.realmId = realm.getId();
|
this.realmId = realm.getId();
|
||||||
|
|
||||||
IntStream.range(0, NUM_GROUPS).forEach(i -> {
|
IntStream.range(0, NUM_GROUPS).forEach(i -> {
|
||||||
|
|
|
@ -747,13 +747,12 @@ module.controller('RealmPasswordPolicyCtrl', function($scope, Realm, realm, $htt
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('RealmDefaultRolesCtrl', function ($scope, $route, Realm, realm, roles, Notifications, ClientRole, Client) {
|
module.controller('RealmDefaultRolesCtrl', function ($scope, $route, realm, roles, Notifications, ClientRole, Client, RoleRealmComposites, RoleClientComposites, ComponentUtils, $http) {
|
||||||
|
|
||||||
console.log('RealmDefaultRolesCtrl');
|
console.log('RealmDefaultRolesCtrl');
|
||||||
|
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
|
$scope.availableRealmRoles = angular.copy(roles);
|
||||||
$scope.availableRealmRoles = [];
|
|
||||||
$scope.selectedRealmRoles = [];
|
$scope.selectedRealmRoles = [];
|
||||||
$scope.selectedRealmDefRoles = [];
|
$scope.selectedRealmDefRoles = [];
|
||||||
|
|
||||||
|
@ -761,85 +760,106 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, $route, Realm, real
|
||||||
$scope.selectedClientRoles = [];
|
$scope.selectedClientRoles = [];
|
||||||
$scope.selectedClientDefRoles = [];
|
$scope.selectedClientDefRoles = [];
|
||||||
|
|
||||||
if (!$scope.realm.hasOwnProperty('defaultRoles') || $scope.realm.defaultRoles === null) {
|
for (var j = 0; j < $scope.availableRealmRoles.length; j++) {
|
||||||
$scope.realm.defaultRoles = [];
|
if ($scope.availableRealmRoles[j].id === realm.defaultRole.id) {
|
||||||
}
|
var realmRole = $scope.availableRealmRoles[j];
|
||||||
|
var idx = $scope.availableRealmRoles.indexOf(realmRole);
|
||||||
// Populate available roles. Available roles are neither already assigned
|
$scope.availableRealmRoles.splice(idx, 1);
|
||||||
for (var i = 0; i < roles.length; i++) {
|
break;
|
||||||
var item = roles[i].name;
|
|
||||||
|
|
||||||
if ($scope.realm.defaultRoles.indexOf(item) < 0) {
|
|
||||||
$scope.availableRealmRoles.push(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.realmMappings = RoleRealmComposites.query({realm : realm.realm, role : realm.defaultRole.id}, function(){
|
||||||
|
for (var i = 0; i < $scope.realmMappings.length; i++) {
|
||||||
|
var role = $scope.realmMappings[i];
|
||||||
|
for (var j = 0; j < $scope.availableRealmRoles.length; j++) {
|
||||||
|
var realmRole = $scope.availableRealmRoles[j];
|
||||||
|
if (realmRole.id === role.id) {
|
||||||
|
var idx = $scope.availableRealmRoles.indexOf(realmRole);
|
||||||
|
if (idx !== -1) {
|
||||||
|
$scope.availableRealmRoles.splice(idx, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$scope.addRealmDefaultRole = function () {
|
$scope.addRealmDefaultRole = function () {
|
||||||
|
|
||||||
// Remove selected roles from the Available roles and add them to realm default roles (move from left to right).
|
$scope.selectedRealmRolesToAdd = JSON.parse('[' + $scope.selectedRealmRoles + ']');
|
||||||
for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
|
||||||
var selectedRole = $scope.selectedRealmRoles[i];
|
$scope.selectedRealmRolesToAdd).then(function() {
|
||||||
|
// Remove selected roles from the Available roles and add them to realm default roles (move from left to right).
|
||||||
$scope.realm.defaultRoles.push(selectedRole);
|
for (var i = 0; i < $scope.selectedRealmRolesToAdd.length; i++) {
|
||||||
|
var selectedRole = $scope.selectedRealmRolesToAdd[i];
|
||||||
var index = $scope.availableRealmRoles.indexOf(selectedRole);
|
var index = ComponentUtils.findIndexById($scope.availableRealmRoles, selectedRole.id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
$scope.availableRealmRoles.splice(index, 1);
|
$scope.availableRealmRoles.splice(index, 1);
|
||||||
|
$scope.realmMappings.push(selectedRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$scope.selectedRealmRoles = [];
|
$scope.selectedRealmRoles = [];
|
||||||
|
$scope.selectedRealmRolesToAdd = [];
|
||||||
// Update/save the realm with new default roles.
|
Notifications.success("Default roles updated.");
|
||||||
Realm.update($scope.realm, function () {
|
|
||||||
Notifications.success("Realm default roles updated.");
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteRealmDefaultRole = function () {
|
$scope.deleteRealmDefaultRole = function () {
|
||||||
|
|
||||||
// Remove selected roles from the realm default roles and add them to available roles (move from right to left).
|
$scope.selectedClientRolesToRemove = JSON.parse('[' + $scope.selectedRealmDefRoles + ']');
|
||||||
for (var i = 0; i < $scope.selectedRealmDefRoles.length; i++) {
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
|
||||||
$scope.availableRealmRoles.push($scope.selectedRealmDefRoles[i]);
|
{data : $scope.selectedClientRolesToRemove, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
|
// Remove selected roles from the realm default roles and add them to available roles (move from right to left).
|
||||||
var index = $scope.realm.defaultRoles.indexOf($scope.selectedRealmDefRoles[i]);
|
for (var i = 0; i < $scope.selectedClientRolesToRemove.length; i++) {
|
||||||
if (index > -1) {
|
var selectedRole = $scope.selectedClientRolesToRemove[i];
|
||||||
$scope.realm.defaultRoles.splice(index, 1);
|
var index = ComponentUtils.findIndexById($scope.realmMappings, selectedRole.id);
|
||||||
|
if (index > -1) {
|
||||||
|
$scope.realmMappings.splice(index, 1);
|
||||||
|
$scope.availableRealmRoles.push(selectedRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$scope.selectedRealmDefRoles = [];
|
$scope.selectedRealmDefRoles = [];
|
||||||
|
$scope.selectedClientRolesToRemove = [];
|
||||||
// Update/save the realm with new default roles.
|
Notifications.success("Default roles updated.");
|
||||||
//var realmCopy = angular.copy($scope.realm);
|
|
||||||
Realm.update($scope.realm, function () {
|
|
||||||
Notifications.success("Realm default roles updated.");
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.changeClient = function (client) {
|
$scope.changeClient = function (client) {
|
||||||
$scope.selectedClient = client;
|
|
||||||
$scope.selectedClientRoles = [];
|
|
||||||
$scope.selectedClientDefRoles = [];
|
|
||||||
if (!client || !client.id) {
|
if (!client || !client.id) {
|
||||||
$scope.selectedClient = null;
|
$scope.selectedClient = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$scope.selectedClient = client;
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientDefRoles = [];
|
||||||
|
|
||||||
// Populate available roles for selected client
|
// Populate available roles for selected client
|
||||||
if ($scope.selectedClient) {
|
if ($scope.selectedClient) {
|
||||||
ClientRole.query({realm: $scope.realm.realm, client: $scope.selectedClient.id}, function (appDefaultRoles) {
|
$scope.availableClientRoles = ClientRole.query({realm: realm.realm, client: client.id}, function () {
|
||||||
if (!$scope.selectedClient.hasOwnProperty('defaultRoles') || $scope.selectedClient.defaultRoles === null) {
|
$scope.clientMappings = RoleClientComposites.query({realm : realm.realm, role : realm.defaultRole.id, client : client.id}, function(){
|
||||||
$scope.selectedClient.defaultRoles = [];
|
for (var i = 0; i < $scope.clientMappings.length; i++) {
|
||||||
}
|
var role = $scope.clientMappings[i];
|
||||||
|
for (var j = 0; j < $scope.availableClientRoles.length; j++) {
|
||||||
$scope.availableClientRoles = [];
|
var clientRole = $scope.availableClientRoles[j];
|
||||||
console.log('default roles', appDefaultRoles);
|
if (clientRole.id === role.id) {
|
||||||
for (var i = 0; i < appDefaultRoles.length; i++) {
|
var idx = $scope.availableClientRoles.indexOf(clientRole);
|
||||||
|
if (idx !== -1) {
|
||||||
var roleName = appDefaultRoles[i].name;
|
$scope.availableClientRoles.splice(idx, 1);
|
||||||
if ($scope.selectedClient.defaultRoles.indexOf(roleName) < 0) {
|
break;
|
||||||
$scope.availableClientRoles.push(roleName);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (var j = 0; j < $scope.availableClientRoles.length; j++) {
|
||||||
|
if ($scope.availableClientRoles[j] === realm.defaultRole.id) {
|
||||||
|
var clientRole = $scope.availableClientRoles[j];
|
||||||
|
var idx = $scope.availableClientRoles.indexof(clientRole);
|
||||||
|
$scope.availableClientRoles.splice(idx, 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -850,66 +870,44 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, $route, Realm, real
|
||||||
|
|
||||||
$scope.addClientDefaultRole = function () {
|
$scope.addClientDefaultRole = function () {
|
||||||
|
|
||||||
// Remove selected roles from the app available roles and add them to app default roles (move from left to right).
|
$scope.selectedClientRolesToAdd = JSON.parse('[' + $scope.selectedClientRoles + ']');
|
||||||
for (var i = 0; i < $scope.selectedClientRoles.length; i++) {
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
|
||||||
var role = $scope.selectedClientRoles[i];
|
$scope.selectedClientRolesToAdd).then(function() {
|
||||||
|
// Remove selected roles from the app available roles and add them to app default roles (move from left to right).
|
||||||
|
for (var i = 0; i < $scope.selectedClientRolesToAdd.length; i++) {
|
||||||
|
var selectedRole = $scope.selectedClientRolesToAdd[i];
|
||||||
|
|
||||||
var idx = $scope.selectedClient.defaultRoles.indexOf(role);
|
var index = ComponentUtils.findIndexById($scope.availableClientRoles, selectedRole.id);
|
||||||
if (idx < 0) {
|
if (index > -1) {
|
||||||
$scope.selectedClient.defaultRoles.push(role);
|
$scope.availableClientRoles.splice(index, 1);
|
||||||
|
$scope.clientMappings.push(selectedRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = $scope.availableClientRoles.indexOf(role);
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientRolesToAdd = [];
|
||||||
if (idx != -1) {
|
Notifications.success("Default roles updated.");
|
||||||
$scope.availableClientRoles.splice(idx, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.selectedClientRoles = [];
|
|
||||||
|
|
||||||
// Update/save the selected client with new default roles.
|
|
||||||
delete $scope.selectedClient.text;
|
|
||||||
Client.update({
|
|
||||||
realm: $scope.realm.realm,
|
|
||||||
client: $scope.selectedClient.id
|
|
||||||
}, $scope.selectedClient, function () {
|
|
||||||
Notifications.success("Your changes have been saved to the client.");
|
|
||||||
Client.get({realm: realm.realm, client: $scope.selectedClient.id}, function(response) {
|
|
||||||
response.text = response.clientId;
|
|
||||||
$scope.changeClient(response);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.rmClientDefaultRole = function () {
|
$scope.rmClientDefaultRole = function () {
|
||||||
|
|
||||||
// Remove selected roles from the app default roles and add them to app available roles (move from right to left).
|
$scope.selectedClientRolesToRemove = JSON.parse('[' + $scope.selectedClientDefRoles + ']');
|
||||||
for (var i = 0; i < $scope.selectedClientDefRoles.length; i++) {
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
|
||||||
var role = $scope.selectedClientDefRoles[i];
|
{data : $scope.selectedClientRolesToRemove, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
var idx = $scope.selectedClient.defaultRoles.indexOf(role);
|
// Remove selected roles from the realm default roles and add them to available roles (move from right to left).
|
||||||
if (idx != -1) {
|
for (var i = 0; i < $scope.selectedClientRolesToRemove.length; i++) {
|
||||||
$scope.selectedClient.defaultRoles.splice(idx, 1);
|
var selectedRole = $scope.selectedClientRolesToRemove[i];
|
||||||
|
var index = ComponentUtils.findIndexById($scope.clientMappings, selectedRole.id);
|
||||||
|
if (index > -1) {
|
||||||
|
$scope.clientMappings.splice(index, 1);
|
||||||
|
$scope.availableClientRoles.push(selectedRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
idx = $scope.availableClientRoles.indexOf(role);
|
|
||||||
if (idx < 0) {
|
|
||||||
$scope.availableClientRoles.push(role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.selectedClientDefRoles = [];
|
$scope.selectedClientDefRoles = [];
|
||||||
|
$scope.selectedClientRolesToRemove = [];
|
||||||
// Update/save the selected client with new default roles.
|
Notifications.success("Default roles updated.");
|
||||||
delete $scope.selectedClient.text;
|
|
||||||
Client.update({
|
|
||||||
realm: $scope.realm.realm,
|
|
||||||
client: $scope.selectedClient.id
|
|
||||||
}, $scope.selectedClient, function () {
|
|
||||||
Notifications.success("Your changes have been saved to the client.");
|
|
||||||
Client.get({realm: realm.realm, client: $scope.selectedClient.id}, function(response) {
|
|
||||||
response.text = response.clientId;
|
|
||||||
$scope.changeClient(response);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1658,6 +1656,7 @@ module.controller('RoleTabCtrl', function(Dialog, $scope, Current, Notifications
|
||||||
module.controller('RoleListCtrl', function($scope, $route, Dialog, Notifications, realm, RoleList, RoleById, filterFilter) {
|
module.controller('RoleListCtrl', function($scope, $route, Dialog, Notifications, realm, RoleList, RoleById, filterFilter) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
$scope.roles = [];
|
$scope.roles = [];
|
||||||
|
$scope.defaultRoleName = realm.defaultRole.name;
|
||||||
|
|
||||||
$scope.query = {
|
$scope.query = {
|
||||||
realm: realm.realm,
|
realm: realm.realm,
|
||||||
|
@ -1701,7 +1700,13 @@ module.controller('RoleListCtrl', function($scope, $route, Dialog, Notifications
|
||||||
|
|
||||||
$scope.searchQuery();
|
$scope.searchQuery();
|
||||||
|
|
||||||
|
$scope.determineEditLink = function(role) {
|
||||||
|
return role.name === $scope.defaultRoleName ? "/realms/" + $scope.realm.realm + "/default-roles" : "/realms/" + $scope.realm.realm + "/roles/" + role.id;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.removeRole = function (role) {
|
$scope.removeRole = function (role) {
|
||||||
|
if (role.name === $scope.defaultRoleName) return;
|
||||||
|
|
||||||
Dialog.confirmDelete(role.name, 'role', function () {
|
Dialog.confirmDelete(role.name, 'role', function () {
|
||||||
RoleById.remove({
|
RoleById.remove({
|
||||||
realm: realm.realm,
|
realm: realm.realm,
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
<select id="available" class="form-control overflow-select" multiple size="5"
|
<select id="available" class="form-control overflow-select" multiple size="5"
|
||||||
ng-multiple="true"
|
ng-multiple="true"
|
||||||
ng-model="selectedRealmRoles">
|
ng-model="selectedRealmRoles">
|
||||||
<option ng-repeat="r in availableRealmRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}">
|
<option ng-repeat="r in availableRealmRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}">
|
||||||
{{r.toString()}}
|
{{r.name}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmDefaultRole()">
|
<button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmDefaultRole()">
|
||||||
|
@ -31,8 +31,8 @@
|
||||||
<select id="assigned" class="form-control overflow-select" multiple size=5
|
<select id="assigned" class="form-control overflow-select" multiple size=5
|
||||||
ng-multiple="true"
|
ng-multiple="true"
|
||||||
ng-model="selectedRealmDefRoles">
|
ng-model="selectedRealmDefRoles">
|
||||||
<option ng-repeat="r in realm.defaultRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}">
|
<option ng-repeat="r in realmMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}">
|
||||||
{{r.toString()}}
|
{{r.name}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button ng-disabled="selectedRealmDefRoles.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmDefaultRole()">
|
<button ng-disabled="selectedRealmDefRoles.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmDefaultRole()">
|
||||||
|
@ -57,8 +57,8 @@
|
||||||
<select id="available-client" class="form-control overflow-select" multiple size="5"
|
<select id="available-client" class="form-control overflow-select" multiple size="5"
|
||||||
ng-multiple="true"
|
ng-multiple="true"
|
||||||
ng-model="selectedClientRoles">
|
ng-model="selectedClientRoles">
|
||||||
<option ng-repeat="r in availableClientRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}">
|
<option ng-repeat="r in availableClientRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}">
|
||||||
{{r.toString()}}
|
{{r.name}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientDefaultRole()">
|
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientDefaultRole()">
|
||||||
|
@ -71,8 +71,8 @@
|
||||||
<select id="assigned-client" class="form-control overflow-select" multiple size=5
|
<select id="assigned-client" class="form-control overflow-select" multiple size=5
|
||||||
ng-multiple="true"
|
ng-multiple="true"
|
||||||
ng-model="selectedClientDefRoles">
|
ng-model="selectedClientDefRoles">
|
||||||
<option ng-repeat="r in selectedClient.defaultRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}">
|
<option ng-repeat="r in clientMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}">
|
||||||
{{r.toString()}}
|
{{r.name}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button ng-disabled="selectedClientDefRoles.length == 0" class="btn btn-default" type="submit" ng-click="rmClientDefaultRole()">
|
<button ng-disabled="selectedClientDefRoles.length == 0" class="btn btn-default" type="submit" ng-click="rmClientDefaultRole()">
|
||||||
|
|
|
@ -35,11 +35,11 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="role in roles">
|
<tr ng-repeat="role in roles">
|
||||||
<td><a href="#/realms/{{realm.realm}}/roles/{{role.id}}">{{role.name}}</a></td>
|
<td><a href="#{{determineEditLink(role)}}">{{role.name}}</a></td>
|
||||||
<td translate="{{role.composite}}"></td>
|
<td translate="{{role.composite}}"></td>
|
||||||
<td>{{role.description}}</td>
|
<td>{{role.description}}</td>
|
||||||
<td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/roles/{{role.id}}">{{:: 'edit' | translate}}</td>
|
<td class="kc-action-cell" kc-open="{{determineEditLink(role)}}">{{:: 'edit' | translate}}</td>
|
||||||
<td class="kc-action-cell" data-ng-click="removeRole(role)">{{:: 'delete' | translate}}</td>
|
<td class="kc-action-cell" data-ng-click="removeRole(role)" ng-class="{'kc-action-cell-disabled': role.name === defaultRoleName}">{{:: 'delete' | translate}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr data-ng-show="(roles | filter:{name: query.search}).length == 0">
|
<tr data-ng-show="(roles | filter:{name: query.search}).length == 0">
|
||||||
<td class="text-muted" colspan="4" data-ng-show="searchLoaded && roles.length == 0 && lastSearch != null">{{:: 'no-results' | translate}}</td>
|
<td class="text-muted" colspan="4" data-ng-show="searchLoaded && roles.length == 0 && lastSearch != null">{{:: 'no-results' | translate}}</td>
|
||||||
|
|
|
@ -355,6 +355,13 @@ h1 i {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kc-action-cell-disabled {
|
||||||
|
background-color: #fafafa;
|
||||||
|
color: #8b8d8f;
|
||||||
|
background-image: none;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.kc-sorter span {
|
.kc-sorter span {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue