commit
2117db5e6d
28 changed files with 1140 additions and 548 deletions
|
@ -26,6 +26,7 @@ import org.keycloak.models.ClientModel;
|
|||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RealmProvider;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
|
@ -188,6 +189,9 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
}
|
||||
@Override
|
||||
public RoleModel addRealmRole(RealmModel realm, String id, String name) {
|
||||
if (getRealmRole(realm, name) != null) {
|
||||
throw new ModelDuplicateException();
|
||||
}
|
||||
RoleEntity entity = new RoleEntity();
|
||||
entity.setId(id);
|
||||
entity.setName(name);
|
||||
|
@ -217,6 +221,9 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
}
|
||||
@Override
|
||||
public RoleModel addClientRole(RealmModel realm, ClientModel client, String id, String name) {
|
||||
if (getClientRole(realm, client, name) != null) {
|
||||
throw new ModelDuplicateException();
|
||||
}
|
||||
ClientEntity clientEntity = em.getReference(ClientEntity.class, client.getId());
|
||||
RoleEntity roleEntity = new RoleEntity();
|
||||
roleEntity.setId(id);
|
||||
|
|
|
@ -39,6 +39,8 @@ import org.keycloak.migration.migrators.MigrateTo3_4_0;
|
|||
import org.keycloak.migration.migrators.MigrateTo3_4_1;
|
||||
import org.keycloak.migration.migrators.Migration;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -91,4 +93,48 @@ public class MigrationModelManager {
|
|||
|
||||
model.setStoredVersion(latest.toString());
|
||||
}
|
||||
|
||||
public static final ModelVersion RHSSO_VERSION_7_0_KEYCLOAK_VERSION = new ModelVersion("1.9.8");
|
||||
public static final ModelVersion RHSSO_VERSION_7_1_KEYCLOAK_VERSION = new ModelVersion("2.5.0");
|
||||
public static final ModelVersion RHSSO_VERSION_7_2_KEYCLOAK_VERSION = new ModelVersion("3.4.2");
|
||||
|
||||
|
||||
public static void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
ModelVersion latest = migrations[migrations.length-1].getVersion();
|
||||
ModelVersion stored = migrations[0].getVersion();
|
||||
if (rep.getKeycloakVersion() != null) {
|
||||
stored = new ModelVersion(rep.getKeycloakVersion());
|
||||
// hack for importing RH-SSO json export
|
||||
// NOTE!!!!! We need to do something once we reach community version 7. If community version is 7 or higher, look for the GA qualifier to identify it as RH SSO
|
||||
if (latest.getMajor() < 7 || (stored.getMajor() == 7 && stored.getQualifier().equals("GA"))) {
|
||||
if (stored.getMajor() == 7) {
|
||||
if (stored.getMinor() == 0) {
|
||||
stored = RHSSO_VERSION_7_0_KEYCLOAK_VERSION;
|
||||
} else if (stored.getMinor() == 1) {
|
||||
stored = RHSSO_VERSION_7_1_KEYCLOAK_VERSION;
|
||||
} else if (stored.getMinor() == 2) {
|
||||
stored = RHSSO_VERSION_7_2_KEYCLOAK_VERSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
// strip out qualifier
|
||||
stored = new ModelVersion(stored.major, stored.minor, stored.micro);
|
||||
if (latest.equals(stored) || latest.lessThan(stored)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (Migration m : migrations) {
|
||||
if (stored == null || stored.lessThan(m.getVersion())) {
|
||||
if (stored != null) {
|
||||
logger.debugf("Migrating older json representation to %s", m.getVersion());
|
||||
}
|
||||
try {
|
||||
m.migrateImport(session, realm, rep, skipUserDependent);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to migrate json representation for version: " + m.getVersion(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -48,7 +49,9 @@ public class MigrateTo1_2_0 implements Migration {
|
|||
client.setFullScopeAllowed(false);
|
||||
|
||||
for (String role : Constants.BROKER_SERVICE_ROLES) {
|
||||
RoleModel roleModel = client.addRole(role);
|
||||
RoleModel roleModel = client.getRole(role);
|
||||
if (roleModel != null) continue;
|
||||
roleModel = client.addRole(role);
|
||||
roleModel.setDescription("${role_" + role.toLowerCase().replaceAll("_", "-") + "}");
|
||||
roleModel.setScopeParamRequired(false);
|
||||
}
|
||||
|
@ -73,4 +76,10 @@ public class MigrateTo1_2_0 implements Migration {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
setupBrokerService(realm);
|
||||
setupClientNames(realm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
|
||||
|
@ -52,6 +53,11 @@ public class MigrateTo1_3_0 implements Migration {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateLDAPProviders(session, realm);
|
||||
}
|
||||
|
||||
private void migrateLDAPProviders(KeycloakSession session, RealmModel realm) {
|
||||
List<UserStorageProviderModel> federationProviders = realm.getUserStorageProviders();
|
||||
for (UserStorageProviderModel fedProvider : federationProviders) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.keycloak.models.cache.UserCache;
|
|||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -46,6 +47,12 @@ public class MigrateTo1_4_0 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
migrateRealm(session, realm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void migrateRealm(KeycloakSession session, RealmModel realm) {
|
||||
if (realm.getAuthenticationFlows().size() == 0) {
|
||||
DefaultAuthenticationFlows.migrateFlows(realm);
|
||||
DefaultRequiredActions.addActions(realm);
|
||||
|
@ -56,6 +63,10 @@ public class MigrateTo1_4_0 implements Migration {
|
|||
migrateUsers(session, realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(session, realm);
|
||||
|
||||
}
|
||||
|
||||
private void migrateLDAPMappers(KeycloakSession session, RealmModel realm) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.models.OTPPolicy;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -42,6 +43,17 @@ public class MigrateTo1_5_0 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
DefaultAuthenticationFlows.migrateFlows(realm); // add reset credentials flo
|
||||
realm.setOTPPolicy(OTPPolicy.DEFAULT_POLICY);
|
||||
realm.setBrowserFlow(realm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW));
|
||||
|
@ -66,6 +78,4 @@ public class MigrateTo1_5_0 implements Migration {
|
|||
client.setClientAuthenticatorType(KeycloakModelUtils.getDefaultClientAuthenticatorType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.keycloak.models.ProtocolMapperModel;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -58,6 +59,29 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
migrateRealm(session, localeMapper, realm);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
MigrationProvider provider = session.getProvider(MigrationProvider.class);
|
||||
List<ProtocolMapperModel> builtinMappers = provider.getBuiltinMappers("openid-connect");
|
||||
ProtocolMapperModel localeMapper = null;
|
||||
for (ProtocolMapperModel m : builtinMappers) {
|
||||
if (m.getName().equals("locale")) {
|
||||
localeMapper = m;
|
||||
}
|
||||
}
|
||||
if (localeMapper == null) {
|
||||
throw new RuntimeException("Can't find default locale mapper");
|
||||
}
|
||||
migrateRealm(session, localeMapper, realm);
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void migrateRealm(KeycloakSession session, ProtocolMapperModel localeMapper, RealmModel realm) {
|
||||
realm.setOfflineSessionIdleTimeout(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
||||
|
||||
if (realm.getRole(Constants.OFFLINE_ACCESS_ROLE) == null) {
|
||||
|
@ -102,7 +126,6 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean localeMapperAdded(ClientModel adminConsoleClient) {
|
||||
return adminConsoleClient.getProtocolMapperByName("openid-connect", "locale") != null;
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.models.IdentityProviderModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -42,6 +43,17 @@ public class MigrateTo1_7_0 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
migrateRealm(session, realm);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(session, realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(KeycloakSession session, RealmModel realm) {
|
||||
// Set default accessToken timeout for implicit flow
|
||||
realm.setAccessTokenLifespanForImplicitFlow(Constants.DEFAULT_ACCESS_TOKEN_LIFESPAN_FOR_IMPLICIT_FLOW_TIMEOUT);
|
||||
|
||||
|
@ -62,4 +74,3 @@ public class MigrateTo1_7_0 implements Migration {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -45,6 +46,17 @@ public class MigrateTo1_8_0 implements Migration {
|
|||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
|
||||
migrateRealm(realm);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
List<UserStorageProviderModel> federationProviders = realm.getUserStorageProviders();
|
||||
for (UserStorageProviderModel fedProvider : federationProviders) {
|
||||
|
||||
|
@ -59,8 +71,6 @@ public class MigrateTo1_8_0 implements Migration {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static ComponentModel getMapperByName(RealmModel realm, ComponentModel providerModel, String name) {
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.migration.migrators;
|
|||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -35,6 +36,16 @@ public class MigrateTo1_9_2 implements Migration {
|
|||
|
||||
public void migrate(KeycloakSession session) {
|
||||
for (RealmModel realm : session.realms().getRealms()) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
if (realm.getBrowserSecurityHeaders() != null) {
|
||||
|
||||
Map<String, String> browserSecurityHeaders = new HashMap<>(realm.getBrowserSecurityHeaders());
|
||||
|
@ -43,6 +54,5 @@ public class MigrateTo1_9_2 implements Migration {
|
|||
realm.setBrowserSecurityHeaders(Collections.unmodifiableMap(browserSecurityHeaders));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.keycloak.models.AdminRoles;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
public class MigrateTo2_0_0 implements Migration {
|
||||
|
||||
|
@ -37,6 +38,12 @@ public class MigrateTo2_0_0 implements Migration {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateAuthorizationServices(realm);
|
||||
|
||||
}
|
||||
|
||||
private void migrateAuthorizationServices(RealmModel realm) {
|
||||
KeycloakModelUtils.setupAuthorizationServices(realm);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -52,6 +53,13 @@ public class MigrateTo2_1_0 implements Migration {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateDefaultRequiredAction(realm);
|
||||
migrateRolePolicies(realm, session);
|
||||
|
||||
}
|
||||
|
||||
// KEYCLOAK-3244: Required Action "Configure Totp" should be "Configure OTP"
|
||||
private void migrateDefaultRequiredAction(RealmModel realm) {
|
||||
RequiredActionProviderModel otpAction = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name());
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.models.IdentityProviderModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
public class MigrateTo2_2_0 implements Migration {
|
||||
public static final ModelVersion VERSION = new ModelVersion("2.2.0");
|
||||
|
@ -39,6 +40,12 @@ public class MigrateTo2_2_0 implements Migration {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
addIdentityProviderAuthenticator(realm);
|
||||
|
||||
}
|
||||
|
||||
private void addIdentityProviderAuthenticator(RealmModel realm) {
|
||||
String defaultProvider = null;
|
||||
for (IdentityProviderModel provider : realm.getIdentityProviders()) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.models.ClientModel;
|
|||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
@ -34,6 +35,11 @@ public class MigrateTo2_3_0 implements Migration {
|
|||
@Override
|
||||
public void migrate(KeycloakSession session) {
|
||||
for (RealmModel realm : session.realms().getRealms()) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
for (ClientModel client : realm.getClients()) {
|
||||
MigrationUtils.updateProtocolMappers(client);
|
||||
}
|
||||
|
@ -42,6 +48,10 @@ public class MigrateTo2_3_0 implements Migration {
|
|||
MigrationUtils.updateProtocolMappers(clientTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.ClientTemplateModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultKeyProviders;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
@ -39,6 +40,11 @@ public class MigrateTo2_5_0 implements Migration {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
DefaultKeyProviders.createSecretProvider(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelVersion getVersion() {
|
||||
return VERSION;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.Constants;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.oidc.OIDCClientRepresentation;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -44,24 +45,33 @@ public class MigrateTo3_0_0 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
for (RealmModel realm : session.realms().getRealms()) {
|
||||
|
||||
migrateRealm(realm);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
realm.getClients().stream()
|
||||
.filter(clientModel -> defaultClients.contains(clientModel.getId()))
|
||||
.filter(clientModel -> Objects.isNull(clientModel.getProtocol()))
|
||||
.forEach(clientModel -> clientModel.setProtocol("openid-connect"));
|
||||
|
||||
ClientModel client = realm.getClientByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
if (client == null) continue;
|
||||
if (client == null) return;
|
||||
RoleModel linkRole = client.getRole(MANAGE_ACCOUNT_LINKS);
|
||||
if (linkRole == null) {
|
||||
client.addRole(MANAGE_ACCOUNT_LINKS);
|
||||
}
|
||||
RoleModel manageAccount = client.getRole(MANAGE_ACCOUNT);
|
||||
if (manageAccount == null) continue;
|
||||
if (manageAccount == null) return;
|
||||
RoleModel manageAccountLinks = client.getRole(MANAGE_ACCOUNT_LINKS);
|
||||
manageAccount.addCompositeRole(manageAccountLinks);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.keycloak.migration.migrators;
|
|||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -36,6 +37,11 @@ public class MigrateTo3_1_0 implements Migration {
|
|||
@Override
|
||||
public void migrate(KeycloakSession session) {
|
||||
for (RealmModel realm : session.realms().getRealms()) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
if (realm.getBrowserSecurityHeaders() != null) {
|
||||
|
||||
Map<String, String> browserSecurityHeaders = new HashMap<>(realm.getBrowserSecurityHeaders());
|
||||
|
@ -45,6 +51,11 @@ public class MigrateTo3_1_0 implements Migration {
|
|||
realm.setBrowserSecurityHeaders(Collections.unmodifiableMap(browserSecurityHeaders));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.PasswordPolicy;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
public class MigrateTo3_2_0 implements Migration {
|
||||
|
||||
|
@ -36,6 +37,17 @@ public class MigrateTo3_2_0 implements Migration {
|
|||
@Override
|
||||
public void migrate(KeycloakSession session) {
|
||||
for (RealmModel realm : session.realms().getRealms()) {
|
||||
migrateRealm(session, realm);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(session, realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(KeycloakSession session, RealmModel realm) {
|
||||
PasswordPolicy.Builder builder = realm.getPasswordPolicy().toBuilder();
|
||||
if (!builder.contains(PasswordPolicy.HASH_ALGORITHM_ID) && "20000".equals(builder.get(PasswordPolicy.HASH_ITERATIONS_ID))) {
|
||||
realm.setPasswordPolicy(builder.remove(PasswordPolicy.HASH_ITERATIONS_ID).build(session));
|
||||
|
@ -54,23 +66,26 @@ public class MigrateTo3_2_0 implements Migration {
|
|||
addRoles(masterAdminClient);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void addRoles(ClientModel realmAccess) {
|
||||
RoleModel queryClients = realmAccess.addRole(AdminRoles.QUERY_CLIENTS);
|
||||
RoleModel queryUsers = realmAccess.addRole(AdminRoles.QUERY_USERS);
|
||||
RoleModel queryGroups = realmAccess.addRole(AdminRoles.QUERY_GROUPS);
|
||||
|
||||
RoleModel queryClients = realmAccess.getRole(AdminRoles.QUERY_CLIENTS);
|
||||
if (queryClients == null) {
|
||||
queryClients = realmAccess.addRole(AdminRoles.QUERY_CLIENTS);
|
||||
RoleModel viewClients = realmAccess.getRole(AdminRoles.VIEW_CLIENTS);
|
||||
if (viewClients != null) {
|
||||
viewClients.addCompositeRole(queryClients);
|
||||
}
|
||||
}
|
||||
RoleModel queryUsers = realmAccess.getRole(AdminRoles.QUERY_USERS);
|
||||
if (queryUsers == null) queryUsers = realmAccess.addRole(AdminRoles.QUERY_USERS);
|
||||
RoleModel queryGroups = realmAccess.getRole(AdminRoles.QUERY_GROUPS);
|
||||
if (queryGroups == null) queryGroups = realmAccess.addRole(AdminRoles.QUERY_GROUPS);
|
||||
|
||||
RoleModel viewUsers = realmAccess.getRole(AdminRoles.VIEW_USERS);
|
||||
if (viewUsers != null) {
|
||||
viewUsers.addCompositeRole(queryUsers);
|
||||
viewUsers.addCompositeRole(queryGroups);
|
||||
if (!viewUsers.hasRole(queryUsers)) viewUsers.addCompositeRole(queryUsers);
|
||||
if (!viewUsers.hasRole(queryGroups)) viewUsers.addCompositeRole(queryGroups);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
|
||||
package org.keycloak.migration.migrators;
|
||||
|
||||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultKeyProviders;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -36,6 +39,18 @@ public class MigrateTo3_4_0 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
session.realms().getRealms().stream().forEach(
|
||||
r -> {
|
||||
migrateRealm(r);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel r) {
|
||||
DefaultKeyProviders.createAesProvider(r);
|
||||
Map<String, String> securityHeaders = r.getBrowserSecurityHeaders();
|
||||
if (securityHeaders != null) {
|
||||
|
@ -46,8 +61,6 @@ public class MigrateTo3_4_0 implements Migration {
|
|||
r.setBrowserSecurityHeaders(Collections.unmodifiableMap(browserSecurityHeaders));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelVersion getVersion() {
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.keycloak.migration.migrators;
|
|||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -38,6 +39,17 @@ public class MigrateTo3_4_1 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
session.realms().getRealms().stream().forEach(
|
||||
r -> {
|
||||
migrateRealm(r);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(realm);
|
||||
}
|
||||
|
||||
protected void migrateRealm(RealmModel r) {
|
||||
Map<String, String> securityHeaders = new HashMap<>(r.getBrowserSecurityHeaders());
|
||||
securityHeaders.entrySet().stream()
|
||||
.filter(Objects::nonNull)
|
||||
|
@ -45,8 +57,6 @@ public class MigrateTo3_4_1 implements Migration {
|
|||
.forEach(entry -> entry.setValue("frame-src 'self'; frame-ancestors 'self'; object-src 'none';"));
|
||||
r.setBrowserSecurityHeaders(Collections.unmodifiableMap(securityHeaders));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelVersion getVersion() {
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.keycloak.migration.migrators;
|
|||
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
@ -27,6 +29,22 @@ public interface Migration {
|
|||
|
||||
void migrate(KeycloakSession session);
|
||||
|
||||
/**
|
||||
* Called after full import of representation.
|
||||
*
|
||||
* Implementations of this method should try not make assumptions about what was imported from the representations.
|
||||
* We have no idea what the user will do to an exported json file.
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param rep
|
||||
* @param skipUserDependent
|
||||
*/
|
||||
default
|
||||
void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
|
||||
}
|
||||
|
||||
ModelVersion getVersion();
|
||||
|
||||
}
|
||||
|
|
|
@ -22,12 +22,15 @@ import org.keycloak.component.ComponentModel;
|
|||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class DefaultKeyProviders {
|
||||
|
||||
public static void createProviders(RealmModel realm) {
|
||||
if (!hasProvider(realm, "rsa-generated")) {
|
||||
ComponentModel generated = new ComponentModel();
|
||||
generated.setName("rsa-generated");
|
||||
generated.setParentId(realm.getId());
|
||||
|
@ -39,12 +42,14 @@ public class DefaultKeyProviders {
|
|||
generated.setConfig(config);
|
||||
|
||||
realm.addComponentModel(generated);
|
||||
}
|
||||
|
||||
createSecretProvider(realm);
|
||||
createAesProvider(realm);
|
||||
}
|
||||
|
||||
public static void createSecretProvider(RealmModel realm) {
|
||||
if (hasProvider(realm, "hmac-generated")) return;
|
||||
ComponentModel generated = new ComponentModel();
|
||||
generated.setName("hmac-generated");
|
||||
generated.setParentId(realm.getId());
|
||||
|
@ -59,6 +64,7 @@ public class DefaultKeyProviders {
|
|||
}
|
||||
|
||||
public static void createAesProvider(RealmModel realm) {
|
||||
if (hasProvider(realm, "aes-generated")) return;
|
||||
ComponentModel generated = new ComponentModel();
|
||||
generated.setName("aes-generated");
|
||||
generated.setParentId(realm.getId());
|
||||
|
@ -72,7 +78,18 @@ public class DefaultKeyProviders {
|
|||
realm.addComponentModel(generated);
|
||||
}
|
||||
|
||||
protected static boolean hasProvider(RealmModel realm, String providerId) {
|
||||
List<ComponentModel> currentComponents = realm.getComponents(realm.getId(), KeyProvider.class.getName());
|
||||
for (ComponentModel current : currentComponents) {
|
||||
if (current.getProviderId().equals(providerId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void createProviders(RealmModel realm, String privateKeyPem, String certificatePem) {
|
||||
if (!hasProvider(realm, "rsa")) {
|
||||
ComponentModel rsa = new ComponentModel();
|
||||
rsa.setName("rsa");
|
||||
rsa.setParentId(realm.getId());
|
||||
|
@ -88,6 +105,7 @@ public class DefaultKeyProviders {
|
|||
rsa.setConfig(config);
|
||||
|
||||
realm.addComponentModel(rsa);
|
||||
}
|
||||
|
||||
createSecretProvider(realm);
|
||||
createAesProvider(realm);
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.keycloak.services.managers;
|
|||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.common.enums.SslRequired;
|
||||
import org.keycloak.migration.MigrationModelManager;
|
||||
import org.keycloak.models.AccountRoles;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.BrowserSecurityHeaders;
|
||||
|
@ -534,6 +535,10 @@ public class RealmManager {
|
|||
setupAuthorizationServices(realm);
|
||||
setupClientRegistrations(realm);
|
||||
|
||||
if (rep.getKeycloakVersion() != null) {
|
||||
MigrationModelManager.migrateImport(session, realm, rep, skipUserDependent);
|
||||
}
|
||||
|
||||
fireRealmPostCreate(realm);
|
||||
|
||||
return realm;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.testsuite.migration;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public abstract class AbstractJsonFileImportMigrationTest extends AbstractMigrationTest {
|
||||
protected RealmRepresentation masterRep;
|
||||
protected String masterTestClientId;
|
||||
|
||||
@Before
|
||||
public void beforeMigrationTest() {
|
||||
migrationRealm = adminClient.realms().realm(MIGRATION);
|
||||
migrationRealm2 = adminClient.realms().realm(MIGRATION2);
|
||||
migrationRealm3 = adminClient.realms().realm("authorization");
|
||||
masterRealm = adminClient.realms().realm(MASTER);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
// hack to reuse AbstractMigrationTest need to create a bunch of stuff in master realm for tests to work
|
||||
|
||||
RoleRepresentation newRole = new RoleRepresentation();
|
||||
newRole.setName("master-test-realm-role");
|
||||
|
||||
masterRealm.roles().create(newRole);
|
||||
ClientRepresentation newClient = new ClientRepresentation();
|
||||
newClient.setClientId("master-test-client");
|
||||
masterRealm.clients().create(newClient);
|
||||
newClient = masterRealm.clients().findByClientId("master-test-client").get(0);
|
||||
newRole.setName("master-test-client-role");
|
||||
masterTestClientId = newClient.getId();
|
||||
masterRealm.clients().get(masterTestClientId).roles().create(newRole);
|
||||
|
||||
for (GroupRepresentation group : masterRep.getGroups()) {
|
||||
group.setId(null);
|
||||
masterRealm.groups().add(group);
|
||||
}
|
||||
for (UserRepresentation user : masterRep.getUsers()) {
|
||||
user.setId(null);
|
||||
if (!user.getUsername().equals("admin")) masterRealm.users().create(user);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterMigrationTest() {
|
||||
masterRealm.clients().get(masterTestClientId).remove();
|
||||
masterRealm.roles().get("master-test-realm-role").remove();
|
||||
GroupRepresentation group = masterRealm.getGroupByPath("/master-test-group");
|
||||
masterRealm.groups().group(group.getId()).remove();
|
||||
UserRepresentation user = masterRealm.users().search("master-test-user").get(0);
|
||||
masterRealm.users().get(user.getId()).remove();
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* 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.testsuite.migration;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.RoleResource;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.component.PrioritizedComponentModel;
|
||||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.runonserver.RunHelpers;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
|
||||
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT_LINKS;
|
||||
import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
|
||||
import static org.keycloak.testsuite.Assert.assertNames;
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||
public static final String MIGRATION = "Migration";
|
||||
public static final String MIGRATION2 = "Migration2";
|
||||
protected RealmResource migrationRealm;
|
||||
protected RealmResource migrationRealm2;
|
||||
protected RealmResource migrationRealm3;
|
||||
protected RealmResource masterRealm;
|
||||
|
||||
protected void testMigratedData() {
|
||||
log.info("testing migrated data");
|
||||
//master realm
|
||||
testMigratedMasterData();
|
||||
//migrationRealm
|
||||
testMigratedMigrationData();
|
||||
}
|
||||
|
||||
protected void testMigratedMigrationData() {
|
||||
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
||||
assertNames(migrationRealm.clients().findAll(), "account", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console");
|
||||
String id2 = migrationRealm.clients().findByClientId("migration-test-client").get(0).getId();
|
||||
assertNames(migrationRealm.clients().get(id2).roles().list(), "migration-test-client-role");
|
||||
assertNames(migrationRealm.users().search("", 0, 5), "migration-test-user");
|
||||
assertNames(migrationRealm.groups().groups(), "migration-test-group");
|
||||
}
|
||||
|
||||
protected void testMigratedMasterData() {
|
||||
assertNames(masterRealm.roles().list(), "offline_access", "uma_authorization", "create-realm", "master-test-realm-role", "admin");
|
||||
assertNames(masterRealm.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account",
|
||||
"master-realm", "master-test-client", "Migration-realm", "Migration2-realm");
|
||||
String id = masterRealm.clients().findByClientId("master-test-client").get(0).getId();
|
||||
assertNames(masterRealm.clients().get(id).roles().list(), "master-test-client-role");
|
||||
assertNames(masterRealm.users().search("", 0, 5), "admin", "master-test-user");
|
||||
assertNames(masterRealm.groups().groups(), "master-test-group");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_0_0
|
||||
*/
|
||||
protected void testMigrationTo2_0_0() {
|
||||
testAuthorizationServices(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_1_0
|
||||
*/
|
||||
protected void testMigrationTo2_1_0() {
|
||||
testNameOfOTPRequiredAction(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_2_0
|
||||
*/
|
||||
protected void testMigrationTo2_2_0() {
|
||||
testIdentityProviderAuthenticator(masterRealm, migrationRealm);
|
||||
//MigrateTo2_2_0#migrateRolePolicies is not relevant any more
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_3_0
|
||||
*/
|
||||
protected void testMigrationTo2_3_0() {
|
||||
testUpdateProtocolMappers(masterRealm, migrationRealm);
|
||||
testExtractRealmKeysMasterRealm(masterRealm);
|
||||
testExtractRealmKeysMigrationRealm(migrationRealm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_5_0
|
||||
*/
|
||||
protected void testMigrationTo2_5_0() {
|
||||
testLdapKerberosMigration_2_5_0();
|
||||
//https://github.com/keycloak/keycloak/pull/3630
|
||||
testDuplicateEmailSupport(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
protected void testMigrationTo2_5_1() throws Exception {
|
||||
testOfflineTokenLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo3_0_0
|
||||
*/
|
||||
protected void testMigrationTo3_0_0() {
|
||||
testRoleManageAccountLinks(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
protected void testMigrationTo3_2_0() {
|
||||
assertNull(masterRealm.toRepresentation().getPasswordPolicy());
|
||||
assertNull(migrationRealm.toRepresentation().getPasswordPolicy());
|
||||
|
||||
testDockerAuthenticationFlow(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
protected void testMigrationTo3_4_0() {
|
||||
Map<String, String> securityHeaders = masterRealm.toRepresentation().getBrowserSecurityHeaders();
|
||||
if (securityHeaders != null) {
|
||||
assertEquals("max-age=31536000; includeSubDomains",
|
||||
securityHeaders.get("strictTransportSecurity"));
|
||||
} else {
|
||||
fail("Browser security headers not found");
|
||||
}
|
||||
}
|
||||
|
||||
protected void testMigrationTo3_4_1() {
|
||||
Map<String, String> securityHeaders = masterRealm.toRepresentation().getBrowserSecurityHeaders();
|
||||
if (securityHeaders != null) {
|
||||
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
|
||||
securityHeaders.get("contentSecurityPolicy"));
|
||||
} else {
|
||||
fail("Browser security headers not found");
|
||||
}
|
||||
}
|
||||
|
||||
protected void testDockerAuthenticationFlow(RealmResource... realms) {
|
||||
for (RealmResource realm : realms) {
|
||||
AuthenticationFlowRepresentation flow = null;
|
||||
for (AuthenticationFlowRepresentation f : realm.flows().getFlows()) {
|
||||
if (DefaultAuthenticationFlows.DOCKER_AUTH.equals(f.getAlias())) {
|
||||
flow = f;
|
||||
}
|
||||
}
|
||||
assertNotNull(flow);
|
||||
}
|
||||
}
|
||||
|
||||
protected void testRoleManageAccountLinks(RealmResource... realms) {
|
||||
log.info("testing role manage account links");
|
||||
for (RealmResource realm : realms) {
|
||||
List<ClientRepresentation> clients = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
if (!clients.isEmpty()) {
|
||||
String accountClientId = clients.get(0).getId();
|
||||
ClientResource accountClient = realm.clients().get(accountClientId);
|
||||
accountClient.roles().get(MANAGE_ACCOUNT_LINKS).toRepresentation(); //the role should be presented, it'll throw javax.ws.rs.NotFoundException in case the role is not found
|
||||
|
||||
Set<RoleRepresentation> roleComposites = accountClient.roles().get(MANAGE_ACCOUNT).getRoleComposites();
|
||||
boolean success = false;
|
||||
for (RoleRepresentation roleComposite : roleComposites) {
|
||||
if (roleComposite.getName().equals(MANAGE_ACCOUNT_LINKS)) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
fail("'manage-account' role of client 'account' should have composite role 'manage-account-links'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void testExtractRealmKeysMasterRealm(RealmResource masterRealm) {
|
||||
log.info("testing extract realm keys");
|
||||
String expectedMasterRealmKey = "MIIEowIBAAKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQABAoIBAHcbPKsPLZ8SJfOF1iblW8OzFulAbaaSf2pJHIMJrQrw7LKkMkPjVXoLX+/rgr7xYZmWIP2OLBWfEHCeYTzQUyHiZpSf7vgHx7Fa45/5uVQOe/ttHIiYa37bCtP4vvEdJkOpvP7qGPvljwsebqsk9Ns28LfVez66bHOjK5Mt2yOIulbTeEs7ch//h39YwKJv96vc+CHbV2O6qoOxZessO6y+287cOBvbFXmS2GaGle5Nx/EwncBNS4b7czoetmm70+9ht3yX+kxaP311YUT31KQjuaJt275kOiKsrXr27PvgO++bsIyGuSzqyS7G7fmxF2zUyphEqEpalyDGMKMnrAECgYEA1fCgFox03rPDjm0MhW/ThoS2Ld27sbWQ6reS+PBMdUTJZVZIU1D2//h6VXDnlddhk6avKjA4smdy1aDKzmjz3pt9AKn+kgkXqtTC2fD3wp+fC9hND0z+rQPGe/Gk7ZUnTdsqnfyowxr+woIgzdnRukOUrG+xQiP3RUUT7tt6NQECgYEApEz2xvgqMm+9/f/YxjLdsFUfLqc4WlafB863stYEVqlCYy5ujyo0VQ0ahKSKJkLDnf52+aMUqPOpwaGePpu3O6VkvpcKfPY2MUlZW7/6Sa9et9hxNkdTS7Gui2d1ELpaCBe1Bc62sk8EA01iHXE1PpvyUqDWrhNh+NrDICA9oU8CgYBgGDYACtTP11TmW2r9YK5VRLUDww30k4ZlN1GnyV++aMhBYVEZQ0u+y+A/EnijIFwu0vbo70H4OGknNZMCxbeMbLDoJHM5KyZbUDe5ZvgSjloFGwH59m6KTiDQOUkIgi9mVCQ/VGaFRFHcElEjxUvj60kTbxPijn8ZuR5r8l9hAQKBgQCQ9jL5pHWeoIayN20smi6M6N2lTPbkhe60dcgQatHTIG2pkosLl8IqlHAkPgSB84AiwyR351JQKwRJCm7TcJI/dxMnMZ6YWKfB3qSP1hdfsfJRJQ/mQxIUBAYrizF3e+P5peka4aLCOgMhYsJBlePThMZN7wja99EGPwXQL4IQ8wKBgB8Nis1lQK6Z30GCp9u4dYleGfEP71Lwqvk/eJb89/uz0fjF9CTpJMULFc+nA5u4yHP3LFnRg3zCU6aEwfwUyk4GH9lWGV/qIAisQtgrCEraVe4qxz0DVE59C7qjO26IhU2U66TEzPAqvQ3zqey+woDn/cz/JMWK1vpcSk+TKn3K";
|
||||
List<ComponentRepresentation> components = masterRealm.components().query(MASTER, KeyProvider.class.getName());
|
||||
assertEquals(3, components.size());
|
||||
|
||||
components = masterRealm.components().query(MASTER, KeyProvider.class.getName(), "rsa");
|
||||
assertEquals(1, components.size());
|
||||
|
||||
ComponentRepresentation component = testingClient.server(MASTER).fetch(RunHelpers.internalComponent(components.get(0).getId()));
|
||||
assertEquals(expectedMasterRealmKey, component.getConfig().getFirst("privateKey"));
|
||||
|
||||
components = masterRealm.components().query(MASTER, KeyProvider.class.getName(), "hmac-generated");
|
||||
assertEquals(1, components.size());
|
||||
|
||||
}
|
||||
|
||||
protected void testExtractRealmKeysMigrationRealm(RealmResource migrationRealm) {
|
||||
log.info("testing extract realm keys");
|
||||
String expectedMigrationRealmKey = "MIIEpAIBAAKCAQEApt6gCllWkVTZ7fy/oRIx6Bxjt9x3eKKyKGFXvN4iaafrNqpYU9lcqPngWJ9DyXGqUf8RpjPaQWiLWLxjw3xGBqLk2E1/Frb9e/dy8rj//fHGq6bujN1iguzyFwxPGT5Asd7jflRI3qU04M8JE52PArqPhGL2Fn+FiSK5SWRIGm+hVL7Ck/E/tVxM25sFG1/UTQqvrROm4q76TmP8FsyZaTLVf7cCwW2QPIX0N5HTVb3QbBb5KIsk4kKmk/g7uUxS9r42tu533LISzRr5CTyWZAL2XFRuF2RrKdE8gwqkEubw6sDmB2mE0EoPdY1DUhBQgVP/5rwJrCtTsUBR2xdEYQIDAQABAoIBAFbbsNBSOlZBpYJUOmcb8nBQPrOYhXN8tGGCccn0klMOvcdhmcJjdPDbyCQ5Gm7DxJUTwNsTSHsdcNMKlJ9Pk5+msJnKlOl87KrXXbTsCQvlCrWUmb0nCzz9GvJWTOHl3oT3cND0DE4gDksqWR4luCgCdevCGzgQvrBoK6wBD+r578uEW3iw10hnJ0+wnGiw8IvPzE1a9xbY4HD8/QrYdaLxuLb/aC1PDuzrz0cOjnvPkrws5JrbUSnbFygJiOv1z4l2Q00uGIxlHtXdwQBnTZZjVi4vOec2BYSHffgwDYEZIglw1mnrV7y0N1nnPbtJK/cegIkXoBQHXm8Q99TrWMUCgYEA9au86qcwrXZZg5H4BpR5cpy0MSkcKDbA1aRL1cAyTCqJxsczlAtLhFADF+NhnlXj4y7gwDEYWrz064nF73I+ZGicvCiyOy+tCTugTyTGS+XR948ElDMS6PCUUXsotS3dKa0b3c9wd2mxeddTjq/ArfgEVZJ6fE1KtjLt9dtfA+8CgYEAreK3JsvjR5b/Xct28TghYUU7Qnasombb/shqqy8FOMjYUr5OUm/OjNIgoCqhOlE8oQDJ4dOZofNSa7tL+oM8Gmbal+E3fRzxnx/9/EC4QV6sVaPLTIyk7EPfKTcZuzH7+BNZtAziTxJw9d6YJQRbkpg92EZIEoR8iDj2Xs5xrK8CgYEAwMVWwwYX8zT3vn7ukTM2LRH7bsvkVUXJgJqgCwT6Mrv6SmkK9vL5+cPS+Y6pjdW1sRGauBSOGL1Grf/4ug/6F03jFt4UJM8fRyxreU7Q7sNSQ6AMpsGA6BnHODycz7ZCYa59PErG5FyiL4of/cm5Nolz1TXQOPNpWZiTEqVlZC8CgYA4YPbjVF4nuxSnU64H/hwMjsbtAM9uhI016cN0J3W4+J3zDhMU9X1x+Tts0wWdg/N1fGz4lIQOl3cUyRCUc/KL2OdtMS+tmDHbVyMho9ZaE5kq10W2Vy+uDz+O/HeSU12QDK4cC8Vgv+jyPy7zaZtLR6NduUPrBRvfiyCOkr8WrwKBgQCY0h4RCdNFhr0KKLLmJipAtV8wBCGcg1jY1KoWKQswbcykfBKwHbF6EooVqkRW0ITjWB7ZZCf8TnSUxe0NXCUAkVBrhzS4DScgtoSZYOOUaSHgOxpfwgnQ3oYotKi98Yg3IsaLs1j4RuPG5Sp1z6o+ELP1uvr8azyn9YlLa+523Q==";
|
||||
|
||||
List<ComponentRepresentation> components = migrationRealm.components().query(MIGRATION, KeyProvider.class.getName());
|
||||
assertEquals(3, components.size());
|
||||
|
||||
components = migrationRealm.components().query(MIGRATION, KeyProvider.class.getName(), "rsa");
|
||||
assertEquals(1, components.size());
|
||||
|
||||
ComponentRepresentation component = testingClient.server(MIGRATION).fetch(RunHelpers.internalComponent(components.get(0).getId()));
|
||||
assertEquals(expectedMigrationRealmKey, component.getConfig().getFirst("privateKey"));
|
||||
|
||||
components = migrationRealm.components().query(MIGRATION, KeyProvider.class.getName(), "hmac-generated");
|
||||
assertEquals(1, components.size());
|
||||
}
|
||||
|
||||
protected void testLdapKerberosMigration_2_5_0() {
|
||||
log.info("testing ldap kerberos migration");
|
||||
RealmRepresentation realmRep = migrationRealm2.toRepresentation();
|
||||
List<ComponentRepresentation> components = migrationRealm2.components().query(realmRep.getId(), UserStorageProvider.class.getName());
|
||||
assertEquals(2, components.size());
|
||||
boolean testedLdap = false;
|
||||
boolean testedKerberos = false;
|
||||
|
||||
for (ComponentRepresentation component : components) {
|
||||
if (component.getName().equals("ldap-provider")) {
|
||||
assertEquals("2", component.getConfig().getFirst(PrioritizedComponentModel.PRIORITY));
|
||||
assertEquals("READ_ONLY", component.getConfig().getFirst(LDAPConstants.EDIT_MODE));
|
||||
assertEquals("true", component.getConfig().getFirst(LDAPConstants.SYNC_REGISTRATIONS));
|
||||
assertEquals(LDAPConstants.VENDOR_RHDS, component.getConfig().getFirst(LDAPConstants.VENDOR));
|
||||
assertEquals("uid", component.getConfig().getFirst(LDAPConstants.USERNAME_LDAP_ATTRIBUTE));
|
||||
assertEquals("uid", component.getConfig().getFirst(LDAPConstants.RDN_LDAP_ATTRIBUTE));
|
||||
assertEquals("nsuniqueid", component.getConfig().getFirst(LDAPConstants.UUID_LDAP_ATTRIBUTE));
|
||||
assertEquals("inetOrgPerson, organizationalPerson", component.getConfig().getFirst(LDAPConstants.USER_OBJECT_CLASSES));
|
||||
assertEquals("http://localhost", component.getConfig().getFirst(LDAPConstants.CONNECTION_URL));
|
||||
assertEquals("dn", component.getConfig().getFirst(LDAPConstants.USERS_DN));
|
||||
assertEquals(LDAPConstants.AUTH_TYPE_NONE, component.getConfig().getFirst(LDAPConstants.AUTH_TYPE));
|
||||
assertEquals("true", component.getConfig().getFirst(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION));
|
||||
assertEquals("realm", component.getConfig().getFirst(KerberosConstants.KERBEROS_REALM));
|
||||
assertEquals("principal", component.getConfig().getFirst(KerberosConstants.SERVER_PRINCIPAL));
|
||||
assertEquals("keytab", component.getConfig().getFirst(KerberosConstants.KEYTAB));
|
||||
testedLdap = true;
|
||||
} else if (component.getName().equals("kerberos-provider")) {
|
||||
assertEquals("3", component.getConfig().getFirst(PrioritizedComponentModel.PRIORITY));
|
||||
assertEquals("realm", component.getConfig().getFirst(KerberosConstants.KERBEROS_REALM));
|
||||
assertEquals("principal", component.getConfig().getFirst(KerberosConstants.SERVER_PRINCIPAL));
|
||||
assertEquals("keytab", component.getConfig().getFirst(KerberosConstants.KEYTAB));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void testDroolsToRulesPolicyTypeMigration() {
|
||||
log.info("testing drools to rules in authorization services");
|
||||
List<ClientRepresentation> client = migrationRealm3.clients().findByClientId("photoz-restful-api");
|
||||
|
||||
assertEquals(1, client.size());
|
||||
|
||||
ClientRepresentation representation = client.get(0);
|
||||
|
||||
List<PolicyRepresentation> policies = migrationRealm3.clients().get(representation.getId()).authorization().policies().policies();
|
||||
|
||||
List<PolicyRepresentation> migratedRulesPolicies = policies.stream().filter(policyRepresentation -> "rules".equals(policyRepresentation.getType())).collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, migratedRulesPolicies.size());
|
||||
}
|
||||
|
||||
protected void testAuthorizationServices(RealmResource... realms) {
|
||||
log.info("testing authorization services");
|
||||
for (RealmResource realm : realms) {
|
||||
//test setup of authorization services
|
||||
for (String roleName : Constants.AUTHZ_DEFAULT_AUTHORIZATION_ROLES) {
|
||||
RoleResource role = realm.roles().get(roleName); //throws javax.ws.rs.NotFoundException if not found
|
||||
|
||||
assertFalse("Role's scopeParamRequired should be false.", role.toRepresentation().isScopeParamRequired());
|
||||
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));
|
||||
}
|
||||
//test admin roles - master admin client
|
||||
List<ClientRepresentation> clients = realm.clients().findByClientId(realm.toRepresentation().getRealm() + "-realm");
|
||||
if (!clients.isEmpty()) {
|
||||
ClientResource masterAdminClient = realm.clients().get(clients.get(0).getId());
|
||||
masterAdminClient.roles().get(AdminRoles.VIEW_AUTHORIZATION).toRepresentation();
|
||||
masterAdminClient.roles().get(AdminRoles.MANAGE_AUTHORIZATION).toRepresentation();
|
||||
//test admin roles - admin role composite
|
||||
Set<String> roleNames = new HashSet<>();
|
||||
for (RoleRepresentation role : realm.roles().get(AdminRoles.ADMIN).getRoleComposites()) {
|
||||
roleNames.add(role.getName());
|
||||
}
|
||||
assertTrue(AdminRoles.VIEW_AUTHORIZATION + " should be composite role of " + AdminRoles.ADMIN, roleNames.contains(AdminRoles.VIEW_AUTHORIZATION));
|
||||
assertTrue(AdminRoles.MANAGE_AUTHORIZATION + " should be composite role of " + AdminRoles.ADMIN, roleNames.contains(AdminRoles.MANAGE_AUTHORIZATION));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void testNameOfOTPRequiredAction(RealmResource... realms) {
|
||||
log.info("testing OTP Required Action");
|
||||
for (RealmResource realm : realms) {
|
||||
RequiredActionProviderRepresentation otpAction = realm.flows().getRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
|
||||
|
||||
assertEquals("The name of CONFIGURE_TOTP required action should be 'Configure OTP'.", "Configure OTP", otpAction.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void testIdentityProviderAuthenticator(RealmResource... realms) {
|
||||
log.info("testing identity provider authenticator");
|
||||
for (RealmResource realm : realms) {
|
||||
boolean success = false;
|
||||
for (AuthenticationFlowRepresentation flow : realm.flows().getFlows()) {
|
||||
if (flow.getAlias().equals(DefaultAuthenticationFlows.BROWSER_FLOW)) {
|
||||
for (AuthenticationExecutionExportRepresentation execution : flow.getAuthenticationExecutions()) {
|
||||
if ("identity-provider-redirector".equals(execution.getAuthenticator())) {
|
||||
assertEquals("Requirement should be ALTERNATIVE.", AuthenticationExecutionModel.Requirement.ALTERNATIVE.name(), execution.getRequirement());
|
||||
assertTrue("Priority should be 25.", execution.getPriority() == 25);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
fail("BROWSER_FLOW should contain execution: 'identity-provider-redirector' authenticator.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void testUpdateProtocolMappers(RealmResource... realms) {
|
||||
log.info("testing updated protocol mappers");
|
||||
for (RealmResource realm : realms) {
|
||||
for (ClientRepresentation client : realm.clients().findAll()) {
|
||||
for (ProtocolMapperRepresentation protocolMapper : client.getProtocolMappers()) {
|
||||
testUpdateProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
for (ClientTemplateRepresentation clientTemlate : realm.clientTemplates().findAll()) {
|
||||
for (ProtocolMapperRepresentation protocolMapper : clientTemlate.getProtocolMappers()) {
|
||||
testUpdateProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void testUpdateProtocolMapper(ProtocolMapperRepresentation protocolMapper) {
|
||||
if (protocolMapper.getConfig().get("id.token.claim") != null) {
|
||||
assertEquals("ProtocolMapper's config should contain key 'userinfo.token.claim'.",
|
||||
protocolMapper.getConfig().get("id.token.claim"), protocolMapper.getConfig().get("userinfo.token.claim"));
|
||||
}
|
||||
}
|
||||
|
||||
protected void testDuplicateEmailSupport(RealmResource... realms) {
|
||||
log.info("testing duplicate email");
|
||||
for (RealmResource realm : realms) {
|
||||
RealmRepresentation rep = realm.toRepresentation();
|
||||
assertTrue("LoginWithEmailAllowed should be enabled.", rep.isLoginWithEmailAllowed());
|
||||
assertFalse("DuplicateEmailsAllowed should be disabled.", rep.isDuplicateEmailsAllowed());
|
||||
}
|
||||
}
|
||||
|
||||
protected void testOfflineTokenLogin() throws Exception {
|
||||
if (isImportMigrationMode()) {
|
||||
log.info("Skip offline token login test in the 'import' migrationMode");
|
||||
} else {
|
||||
log.info("test login with old offline token");
|
||||
String oldOfflineToken = suiteContext.getMigrationContext().loadOfflineToken();
|
||||
Assert.assertNotNull(oldOfflineToken);
|
||||
|
||||
oauth.realm(MIGRATION);
|
||||
oauth.clientId("migration-test-client");
|
||||
OAuthClient.AccessTokenResponse response = oauth.doRefreshTokenRequest(oldOfflineToken, "b2c07929-69e3-44c6-8d7f-76939000b3e4");
|
||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||
assertEquals("migration-test-user", accessToken.getPreferredUsername());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getMigrationMode() {
|
||||
return System.getProperty("migration.mode");
|
||||
}
|
||||
|
||||
protected boolean isImportMigrationMode() {
|
||||
String mode = getMigrationMode();
|
||||
return "import".equals(mode);
|
||||
}
|
||||
protected void testMigrationTo3_x() {
|
||||
// NOTE:
|
||||
testMigrationTo3_0_0();
|
||||
testMigrationTo3_2_0();
|
||||
testMigrationTo3_4_0();
|
||||
testMigrationTo3_4_1();
|
||||
}
|
||||
|
||||
|
||||
protected void testMigrationTo3_x_and_higher() {
|
||||
// NOTE: add future methods
|
||||
testMigrationTo3_x();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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.testsuite.migration;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.exportimport.util.ImportUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.arquillian.DeploymentTargetModifier;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
import org.keycloak.testsuite.util.IOUtil;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Tests that we can import json file from previous version. MigrationTest only tests DB.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JsonFileImport198MigrationTest extends AbstractJsonFileImportMigrationTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(DeploymentTargetModifier.AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
Map<String, RealmRepresentation> reps = null;
|
||||
try {
|
||||
reps = ImportUtils.getRealmsFromStream(JsonSerialization.mapper, IOUtil.class.getResourceAsStream("/migration-test/migration-realm-1.9.8.Final.json"));
|
||||
masterRep = reps.remove("master");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
for (RealmRepresentation rep : reps.values()) {
|
||||
testRealms.add(rep);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migration1_9_8Test() throws Exception {
|
||||
testMigratedMigrationData();
|
||||
testMigrationTo2_0_0();
|
||||
testMigrationTo2_1_0();
|
||||
testMigrationTo2_2_0();
|
||||
testMigrationTo2_3_0();
|
||||
testMigrationTo2_5_0();
|
||||
//testMigrationTo2_5_1(); // todo do not know how to fix
|
||||
testMigrationTo3_x_and_higher();
|
||||
}
|
||||
|
||||
protected void testMigrationTo2_3_0() {
|
||||
testUpdateProtocolMappers(migrationRealm);
|
||||
testExtractRealmKeysMigrationRealm(migrationRealm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.testsuite.migration;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.exportimport.util.ImportUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.arquillian.DeploymentTargetModifier;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
import org.keycloak.testsuite.util.IOUtil;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Tests that we can import json file from previous version. MigrationTest only tests DB.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JsonFileImport255MigrationTest extends AbstractJsonFileImportMigrationTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(DeploymentTargetModifier.AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
Map<String, RealmRepresentation> reps = null;
|
||||
try {
|
||||
reps = ImportUtils.getRealmsFromStream(JsonSerialization.mapper, IOUtil.class.getResourceAsStream("/migration-test/migration-realm-2.5.5.Final.json"));
|
||||
masterRep = reps.remove("master");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
for (RealmRepresentation rep : reps.values()) {
|
||||
testRealms.add(rep);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migration2_5_5Test() throws Exception {
|
||||
testMigrationTo3_x_and_higher();
|
||||
}
|
||||
|
||||
}
|
|
@ -21,49 +21,17 @@ import org.jboss.arquillian.container.test.api.TargetsContainer;
|
|||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.RoleResource;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.component.PrioritizedComponentModel;
|
||||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.arquillian.DeploymentTargetModifier;
|
||||
import org.keycloak.testsuite.arquillian.migration.Migration;
|
||||
import org.keycloak.testsuite.runonserver.RunHelpers;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
|
||||
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT_LINKS;
|
||||
import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
|
||||
import static org.keycloak.testsuite.Assert.assertEquals;
|
||||
import static org.keycloak.testsuite.Assert.assertFalse;
|
||||
import static org.keycloak.testsuite.Assert.assertNames;
|
||||
|
@ -74,15 +42,7 @@ import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
|||
/**
|
||||
* @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
|
||||
*/
|
||||
public class MigrationTest extends AbstractKeycloakTest {
|
||||
|
||||
public static final String MIGRATION = "Migration";
|
||||
public static final String MIGRATION2 = "Migration2";
|
||||
|
||||
private RealmResource migrationRealm;
|
||||
private RealmResource migrationRealm2;
|
||||
private RealmResource migrationRealm3;
|
||||
private RealmResource masterRealm;
|
||||
public class MigrationTest extends AbstractMigrationTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(DeploymentTargetModifier.AUTH_SERVER_CURRENT)
|
||||
|
@ -115,8 +75,7 @@ public class MigrationTest extends AbstractKeycloakTest {
|
|||
@Migration(versionFrom = "2.5.5.Final")
|
||||
public void migration2_5_5Test() {
|
||||
testMigratedData();
|
||||
testMigrationTo3_0_0();
|
||||
testMigrationTo3_4_1();
|
||||
testMigrationTo3_x_and_higher();
|
||||
}
|
||||
@Test
|
||||
@Migration(versionFrom = "1.9.8.Final")
|
||||
|
@ -128,328 +87,13 @@ public class MigrationTest extends AbstractKeycloakTest {
|
|||
testMigrationTo2_3_0();
|
||||
testMigrationTo2_5_0();
|
||||
testMigrationTo2_5_1();
|
||||
testMigrationTo3_0_0();
|
||||
testMigrationTo3_2_0();
|
||||
testMigrationTo3_4_0();
|
||||
testMigrationTo3_4_1();
|
||||
testMigrationTo3_x_and_higher();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Migration(versionFrom = "2.2.1.Final")
|
||||
public void migrationInAuthorizationServicesTest() {
|
||||
testDroolsToRulesPolicyTypeMigration();
|
||||
}
|
||||
|
||||
private void testMigratedData() {
|
||||
log.info("testing migrated data");
|
||||
//master realm
|
||||
assertNames(masterRealm.roles().list(), "offline_access", "uma_authorization", "create-realm", "master-test-realm-role", "admin");
|
||||
assertNames(masterRealm.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account",
|
||||
"master-realm", "master-test-client", "Migration-realm", "Migration2-realm");
|
||||
String id = masterRealm.clients().findByClientId("master-test-client").get(0).getId();
|
||||
assertNames(masterRealm.clients().get(id).roles().list(), "master-test-client-role");
|
||||
assertNames(masterRealm.users().search("", 0, 5), "admin", "master-test-user");
|
||||
assertNames(masterRealm.groups().groups(), "master-test-group");
|
||||
//migrationRealm
|
||||
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
||||
assertNames(migrationRealm.clients().findAll(), "account", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console");
|
||||
String id2 = migrationRealm.clients().findByClientId("migration-test-client").get(0).getId();
|
||||
assertNames(migrationRealm.clients().get(id2).roles().list(), "migration-test-client-role");
|
||||
assertNames(migrationRealm.users().search("", 0, 5), "migration-test-user");
|
||||
assertNames(migrationRealm.groups().groups(), "migration-test-group");
|
||||
}
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_0_0
|
||||
*/
|
||||
private void testMigrationTo2_0_0() {
|
||||
testAuthorizationServices(masterRealm, migrationRealm);
|
||||
}
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_1_0
|
||||
*/
|
||||
private void testMigrationTo2_1_0() {
|
||||
testNameOfOTPRequiredAction(masterRealm, migrationRealm);
|
||||
}
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_2_0
|
||||
*/
|
||||
private void testMigrationTo2_2_0() {
|
||||
testIdentityProviderAuthenticator(masterRealm, migrationRealm);
|
||||
//MigrateTo2_2_0#migrateRolePolicies is not relevant any more
|
||||
}
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_3_0
|
||||
*/
|
||||
private void testMigrationTo2_3_0() {
|
||||
testUpdateProtocolMappers(masterRealm, migrationRealm);
|
||||
testExtractRealmKeys(masterRealm, migrationRealm);
|
||||
}
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_5_0
|
||||
*/
|
||||
private void testMigrationTo2_5_0() {
|
||||
testLdapKerberosMigration_2_5_0();
|
||||
//https://github.com/keycloak/keycloak/pull/3630
|
||||
testDuplicateEmailSupport(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
private void testMigrationTo2_5_1() throws Exception {
|
||||
testOfflineTokenLogin();
|
||||
}
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo3_0_0
|
||||
*/
|
||||
private void testMigrationTo3_0_0() {
|
||||
testRoleManageAccountLinks(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
private void testMigrationTo3_2_0() {
|
||||
assertNull(masterRealm.toRepresentation().getPasswordPolicy());
|
||||
assertNull(migrationRealm.toRepresentation().getPasswordPolicy());
|
||||
|
||||
testDockerAuthenticationFlow(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
private void testMigrationTo3_4_0() {
|
||||
Map<String, String> securityHeaders = masterRealm.toRepresentation().getBrowserSecurityHeaders();
|
||||
if (securityHeaders != null) {
|
||||
assertEquals("max-age=31536000; includeSubDomains",
|
||||
securityHeaders.get("strictTransportSecurity"));
|
||||
} else {
|
||||
fail("Browser security headers not found");
|
||||
}
|
||||
}
|
||||
|
||||
private void testMigrationTo3_4_1() {
|
||||
Map<String, String> securityHeaders = masterRealm.toRepresentation().getBrowserSecurityHeaders();
|
||||
if (securityHeaders != null) {
|
||||
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
|
||||
securityHeaders.get("contentSecurityPolicy"));
|
||||
} else {
|
||||
fail("Browser security headers not found");
|
||||
}
|
||||
}
|
||||
|
||||
private void testDockerAuthenticationFlow(RealmResource... realms) {
|
||||
for (RealmResource realm : realms) {
|
||||
AuthenticationFlowRepresentation flow = null;
|
||||
for (AuthenticationFlowRepresentation f : realm.flows().getFlows()) {
|
||||
if (DefaultAuthenticationFlows.DOCKER_AUTH.equals(f.getAlias())) {
|
||||
flow = f;
|
||||
}
|
||||
}
|
||||
assertNotNull(flow);
|
||||
}
|
||||
}
|
||||
|
||||
private void testRoleManageAccountLinks(RealmResource... realms) {
|
||||
log.info("testing role manage account links");
|
||||
for (RealmResource realm : realms) {
|
||||
List<ClientRepresentation> clients = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
if (!clients.isEmpty()) {
|
||||
String accountClientId = clients.get(0).getId();
|
||||
ClientResource accountClient = realm.clients().get(accountClientId);
|
||||
accountClient.roles().get(MANAGE_ACCOUNT_LINKS).toRepresentation(); //the role should be presented, it'll throw javax.ws.rs.NotFoundException in case the role is not found
|
||||
|
||||
Set<RoleRepresentation> roleComposites = accountClient.roles().get(MANAGE_ACCOUNT).getRoleComposites();
|
||||
boolean success = false;
|
||||
for (RoleRepresentation roleComposite : roleComposites) {
|
||||
if (roleComposite.getName().equals(MANAGE_ACCOUNT_LINKS)) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
fail("'manage-account' role of client 'account' should have composite role 'manage-account-links'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void testExtractRealmKeys(RealmResource masterRealm, RealmResource migrationRealm) {
|
||||
log.info("testing extract realm keys");
|
||||
String expectedMasterRealmKey = "MIIEowIBAAKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQABAoIBAHcbPKsPLZ8SJfOF1iblW8OzFulAbaaSf2pJHIMJrQrw7LKkMkPjVXoLX+/rgr7xYZmWIP2OLBWfEHCeYTzQUyHiZpSf7vgHx7Fa45/5uVQOe/ttHIiYa37bCtP4vvEdJkOpvP7qGPvljwsebqsk9Ns28LfVez66bHOjK5Mt2yOIulbTeEs7ch//h39YwKJv96vc+CHbV2O6qoOxZessO6y+287cOBvbFXmS2GaGle5Nx/EwncBNS4b7czoetmm70+9ht3yX+kxaP311YUT31KQjuaJt275kOiKsrXr27PvgO++bsIyGuSzqyS7G7fmxF2zUyphEqEpalyDGMKMnrAECgYEA1fCgFox03rPDjm0MhW/ThoS2Ld27sbWQ6reS+PBMdUTJZVZIU1D2//h6VXDnlddhk6avKjA4smdy1aDKzmjz3pt9AKn+kgkXqtTC2fD3wp+fC9hND0z+rQPGe/Gk7ZUnTdsqnfyowxr+woIgzdnRukOUrG+xQiP3RUUT7tt6NQECgYEApEz2xvgqMm+9/f/YxjLdsFUfLqc4WlafB863stYEVqlCYy5ujyo0VQ0ahKSKJkLDnf52+aMUqPOpwaGePpu3O6VkvpcKfPY2MUlZW7/6Sa9et9hxNkdTS7Gui2d1ELpaCBe1Bc62sk8EA01iHXE1PpvyUqDWrhNh+NrDICA9oU8CgYBgGDYACtTP11TmW2r9YK5VRLUDww30k4ZlN1GnyV++aMhBYVEZQ0u+y+A/EnijIFwu0vbo70H4OGknNZMCxbeMbLDoJHM5KyZbUDe5ZvgSjloFGwH59m6KTiDQOUkIgi9mVCQ/VGaFRFHcElEjxUvj60kTbxPijn8ZuR5r8l9hAQKBgQCQ9jL5pHWeoIayN20smi6M6N2lTPbkhe60dcgQatHTIG2pkosLl8IqlHAkPgSB84AiwyR351JQKwRJCm7TcJI/dxMnMZ6YWKfB3qSP1hdfsfJRJQ/mQxIUBAYrizF3e+P5peka4aLCOgMhYsJBlePThMZN7wja99EGPwXQL4IQ8wKBgB8Nis1lQK6Z30GCp9u4dYleGfEP71Lwqvk/eJb89/uz0fjF9CTpJMULFc+nA5u4yHP3LFnRg3zCU6aEwfwUyk4GH9lWGV/qIAisQtgrCEraVe4qxz0DVE59C7qjO26IhU2U66TEzPAqvQ3zqey+woDn/cz/JMWK1vpcSk+TKn3K";
|
||||
String expectedMigrationRealmKey = "MIIEpAIBAAKCAQEApt6gCllWkVTZ7fy/oRIx6Bxjt9x3eKKyKGFXvN4iaafrNqpYU9lcqPngWJ9DyXGqUf8RpjPaQWiLWLxjw3xGBqLk2E1/Frb9e/dy8rj//fHGq6bujN1iguzyFwxPGT5Asd7jflRI3qU04M8JE52PArqPhGL2Fn+FiSK5SWRIGm+hVL7Ck/E/tVxM25sFG1/UTQqvrROm4q76TmP8FsyZaTLVf7cCwW2QPIX0N5HTVb3QbBb5KIsk4kKmk/g7uUxS9r42tu533LISzRr5CTyWZAL2XFRuF2RrKdE8gwqkEubw6sDmB2mE0EoPdY1DUhBQgVP/5rwJrCtTsUBR2xdEYQIDAQABAoIBAFbbsNBSOlZBpYJUOmcb8nBQPrOYhXN8tGGCccn0klMOvcdhmcJjdPDbyCQ5Gm7DxJUTwNsTSHsdcNMKlJ9Pk5+msJnKlOl87KrXXbTsCQvlCrWUmb0nCzz9GvJWTOHl3oT3cND0DE4gDksqWR4luCgCdevCGzgQvrBoK6wBD+r578uEW3iw10hnJ0+wnGiw8IvPzE1a9xbY4HD8/QrYdaLxuLb/aC1PDuzrz0cOjnvPkrws5JrbUSnbFygJiOv1z4l2Q00uGIxlHtXdwQBnTZZjVi4vOec2BYSHffgwDYEZIglw1mnrV7y0N1nnPbtJK/cegIkXoBQHXm8Q99TrWMUCgYEA9au86qcwrXZZg5H4BpR5cpy0MSkcKDbA1aRL1cAyTCqJxsczlAtLhFADF+NhnlXj4y7gwDEYWrz064nF73I+ZGicvCiyOy+tCTugTyTGS+XR948ElDMS6PCUUXsotS3dKa0b3c9wd2mxeddTjq/ArfgEVZJ6fE1KtjLt9dtfA+8CgYEAreK3JsvjR5b/Xct28TghYUU7Qnasombb/shqqy8FOMjYUr5OUm/OjNIgoCqhOlE8oQDJ4dOZofNSa7tL+oM8Gmbal+E3fRzxnx/9/EC4QV6sVaPLTIyk7EPfKTcZuzH7+BNZtAziTxJw9d6YJQRbkpg92EZIEoR8iDj2Xs5xrK8CgYEAwMVWwwYX8zT3vn7ukTM2LRH7bsvkVUXJgJqgCwT6Mrv6SmkK9vL5+cPS+Y6pjdW1sRGauBSOGL1Grf/4ug/6F03jFt4UJM8fRyxreU7Q7sNSQ6AMpsGA6BnHODycz7ZCYa59PErG5FyiL4of/cm5Nolz1TXQOPNpWZiTEqVlZC8CgYA4YPbjVF4nuxSnU64H/hwMjsbtAM9uhI016cN0J3W4+J3zDhMU9X1x+Tts0wWdg/N1fGz4lIQOl3cUyRCUc/KL2OdtMS+tmDHbVyMho9ZaE5kq10W2Vy+uDz+O/HeSU12QDK4cC8Vgv+jyPy7zaZtLR6NduUPrBRvfiyCOkr8WrwKBgQCY0h4RCdNFhr0KKLLmJipAtV8wBCGcg1jY1KoWKQswbcykfBKwHbF6EooVqkRW0ITjWB7ZZCf8TnSUxe0NXCUAkVBrhzS4DScgtoSZYOOUaSHgOxpfwgnQ3oYotKi98Yg3IsaLs1j4RuPG5Sp1z6o+ELP1uvr8azyn9YlLa+523Q==";
|
||||
|
||||
List<ComponentRepresentation> components = masterRealm.components().query(MASTER, KeyProvider.class.getName());
|
||||
assertEquals(3, components.size());
|
||||
|
||||
components = masterRealm.components().query(MASTER, KeyProvider.class.getName(), "rsa");
|
||||
assertEquals(1, components.size());
|
||||
|
||||
ComponentRepresentation component = testingClient.server(MASTER).fetch(RunHelpers.internalComponent(components.get(0).getId()));
|
||||
assertEquals(expectedMasterRealmKey, component.getConfig().getFirst("privateKey"));
|
||||
|
||||
components = masterRealm.components().query(MASTER, KeyProvider.class.getName(), "hmac-generated");
|
||||
assertEquals(1, components.size());
|
||||
|
||||
components = migrationRealm.components().query(MIGRATION, KeyProvider.class.getName());
|
||||
assertEquals(3, components.size());
|
||||
|
||||
components = migrationRealm.components().query(MIGRATION, KeyProvider.class.getName(), "rsa");
|
||||
assertEquals(1, components.size());
|
||||
|
||||
component = testingClient.server(MIGRATION).fetch(RunHelpers.internalComponent(components.get(0).getId()));
|
||||
assertEquals(expectedMigrationRealmKey, component.getConfig().getFirst("privateKey"));
|
||||
|
||||
components = migrationRealm.components().query(MIGRATION, KeyProvider.class.getName(), "hmac-generated");
|
||||
assertEquals(1, components.size());
|
||||
}
|
||||
|
||||
private void testLdapKerberosMigration_2_5_0() {
|
||||
log.info("testing ldap kerberos migration");
|
||||
RealmRepresentation realmRep = migrationRealm2.toRepresentation();
|
||||
List<ComponentRepresentation> components = migrationRealm2.components().query(realmRep.getId(), UserStorageProvider.class.getName());
|
||||
assertEquals(2, components.size());
|
||||
boolean testedLdap = false;
|
||||
boolean testedKerberos = false;
|
||||
|
||||
for (ComponentRepresentation component : components) {
|
||||
if (component.getName().equals("ldap-provider")) {
|
||||
assertEquals("2", component.getConfig().getFirst(PrioritizedComponentModel.PRIORITY));
|
||||
assertEquals("READ_ONLY", component.getConfig().getFirst(LDAPConstants.EDIT_MODE));
|
||||
assertEquals("true", component.getConfig().getFirst(LDAPConstants.SYNC_REGISTRATIONS));
|
||||
assertEquals(LDAPConstants.VENDOR_RHDS, component.getConfig().getFirst(LDAPConstants.VENDOR));
|
||||
assertEquals("uid", component.getConfig().getFirst(LDAPConstants.USERNAME_LDAP_ATTRIBUTE));
|
||||
assertEquals("uid", component.getConfig().getFirst(LDAPConstants.RDN_LDAP_ATTRIBUTE));
|
||||
assertEquals("nsuniqueid", component.getConfig().getFirst(LDAPConstants.UUID_LDAP_ATTRIBUTE));
|
||||
assertEquals("inetOrgPerson, organizationalPerson", component.getConfig().getFirst(LDAPConstants.USER_OBJECT_CLASSES));
|
||||
assertEquals("http://localhost", component.getConfig().getFirst(LDAPConstants.CONNECTION_URL));
|
||||
assertEquals("dn", component.getConfig().getFirst(LDAPConstants.USERS_DN));
|
||||
assertEquals(LDAPConstants.AUTH_TYPE_NONE, component.getConfig().getFirst(LDAPConstants.AUTH_TYPE));
|
||||
assertEquals("true", component.getConfig().getFirst(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION));
|
||||
assertEquals("realm", component.getConfig().getFirst(KerberosConstants.KERBEROS_REALM));
|
||||
assertEquals("principal", component.getConfig().getFirst(KerberosConstants.SERVER_PRINCIPAL));
|
||||
assertEquals("keytab", component.getConfig().getFirst(KerberosConstants.KEYTAB));
|
||||
testedLdap = true;
|
||||
} else if (component.getName().equals("kerberos-provider")) {
|
||||
assertEquals("3", component.getConfig().getFirst(PrioritizedComponentModel.PRIORITY));
|
||||
assertEquals("realm", component.getConfig().getFirst(KerberosConstants.KERBEROS_REALM));
|
||||
assertEquals("principal", component.getConfig().getFirst(KerberosConstants.SERVER_PRINCIPAL));
|
||||
assertEquals("keytab", component.getConfig().getFirst(KerberosConstants.KEYTAB));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testDroolsToRulesPolicyTypeMigration() {
|
||||
log.info("testing drools to rules in authorization services");
|
||||
List<ClientRepresentation> client = migrationRealm3.clients().findByClientId("photoz-restful-api");
|
||||
|
||||
assertEquals(1, client.size());
|
||||
|
||||
ClientRepresentation representation = client.get(0);
|
||||
|
||||
List<PolicyRepresentation> policies = migrationRealm3.clients().get(representation.getId()).authorization().policies().policies();
|
||||
|
||||
List<PolicyRepresentation> migratedRulesPolicies = policies.stream().filter(policyRepresentation -> "rules".equals(policyRepresentation.getType())).collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, migratedRulesPolicies.size());
|
||||
}
|
||||
private void testAuthorizationServices(RealmResource... realms) {
|
||||
log.info("testing authorization services");
|
||||
for (RealmResource realm : realms) {
|
||||
//test setup of authorization services
|
||||
for (String roleName : Constants.AUTHZ_DEFAULT_AUTHORIZATION_ROLES) {
|
||||
RoleResource role = realm.roles().get(roleName); //throws javax.ws.rs.NotFoundException if not found
|
||||
|
||||
assertFalse("Role's scopeParamRequired should be false.", role.toRepresentation().isScopeParamRequired());
|
||||
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));
|
||||
}
|
||||
//test admin roles - master admin client
|
||||
List<ClientRepresentation> clients = realm.clients().findByClientId(realm.toRepresentation().getRealm() + "-realm");
|
||||
if (!clients.isEmpty()) {
|
||||
ClientResource masterAdminClient = realm.clients().get(clients.get(0).getId());
|
||||
masterAdminClient.roles().get(AdminRoles.VIEW_AUTHORIZATION).toRepresentation();
|
||||
masterAdminClient.roles().get(AdminRoles.MANAGE_AUTHORIZATION).toRepresentation();
|
||||
//test admin roles - admin role composite
|
||||
Set<String> roleNames = new HashSet<>();
|
||||
for (RoleRepresentation role : realm.roles().get(AdminRoles.ADMIN).getRoleComposites()) {
|
||||
roleNames.add(role.getName());
|
||||
}
|
||||
assertTrue(AdminRoles.VIEW_AUTHORIZATION + " should be composite role of " + AdminRoles.ADMIN, roleNames.contains(AdminRoles.VIEW_AUTHORIZATION));
|
||||
assertTrue(AdminRoles.MANAGE_AUTHORIZATION + " should be composite role of " + AdminRoles.ADMIN, roleNames.contains(AdminRoles.MANAGE_AUTHORIZATION));
|
||||
}
|
||||
}
|
||||
}
|
||||
private void testNameOfOTPRequiredAction(RealmResource... realms) {
|
||||
log.info("testing OTP Required Action");
|
||||
for (RealmResource realm : realms) {
|
||||
RequiredActionProviderRepresentation otpAction = realm.flows().getRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
|
||||
|
||||
assertEquals("The name of CONFIGURE_TOTP required action should be 'Configure OTP'.", "Configure OTP", otpAction.getName());
|
||||
}
|
||||
}
|
||||
private void testIdentityProviderAuthenticator(RealmResource... realms) {
|
||||
log.info("testing identity provider authenticator");
|
||||
for (RealmResource realm : realms) {
|
||||
boolean success = false;
|
||||
for (AuthenticationFlowRepresentation flow : realm.flows().getFlows()) {
|
||||
if (flow.getAlias().equals(DefaultAuthenticationFlows.BROWSER_FLOW)) {
|
||||
for (AuthenticationExecutionExportRepresentation execution : flow.getAuthenticationExecutions()) {
|
||||
if ("identity-provider-redirector".equals(execution.getAuthenticator())) {
|
||||
assertEquals("Requirement should be ALTERNATIVE.", AuthenticationExecutionModel.Requirement.ALTERNATIVE.name(), execution.getRequirement());
|
||||
assertTrue("Priority should be 25.", execution.getPriority() == 25);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
fail("BROWSER_FLOW should contain execution: 'identity-provider-redirector' authenticator.");
|
||||
}
|
||||
}
|
||||
}
|
||||
private void testUpdateProtocolMappers(RealmResource... realms) {
|
||||
log.info("testing updated protocol mappers");
|
||||
for (RealmResource realm : realms) {
|
||||
for (ClientRepresentation client : realm.clients().findAll()) {
|
||||
for (ProtocolMapperRepresentation protocolMapper : client.getProtocolMappers()) {
|
||||
testUpdateProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
for (ClientTemplateRepresentation clientTemlate : realm.clientTemplates().findAll()) {
|
||||
for (ProtocolMapperRepresentation protocolMapper : clientTemlate.getProtocolMappers()) {
|
||||
testUpdateProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void testUpdateProtocolMapper(ProtocolMapperRepresentation protocolMapper) {
|
||||
if (protocolMapper.getConfig().get("id.token.claim") != null) {
|
||||
assertEquals("ProtocolMapper's config should contain key 'userinfo.token.claim'.",
|
||||
protocolMapper.getConfig().get("id.token.claim"), protocolMapper.getConfig().get("userinfo.token.claim"));
|
||||
}
|
||||
}
|
||||
private void testDuplicateEmailSupport(RealmResource... realms) {
|
||||
log.info("testing duplicate email");
|
||||
for (RealmResource realm : realms) {
|
||||
RealmRepresentation rep = realm.toRepresentation();
|
||||
assertTrue("LoginWithEmailAllowed should be enabled.", rep.isLoginWithEmailAllowed());
|
||||
assertFalse("DuplicateEmailsAllowed should be disabled.", rep.isDuplicateEmailsAllowed());
|
||||
}
|
||||
}
|
||||
|
||||
private void testOfflineTokenLogin() throws Exception {
|
||||
if (isImportMigrationMode()) {
|
||||
log.info("Skip offline token login test in the 'import' migrationMode");
|
||||
} else {
|
||||
log.info("test login with old offline token");
|
||||
String oldOfflineToken = suiteContext.getMigrationContext().loadOfflineToken();
|
||||
Assert.assertNotNull(oldOfflineToken);
|
||||
|
||||
oauth.realm(MIGRATION);
|
||||
oauth.clientId("migration-test-client");
|
||||
OAuthClient.AccessTokenResponse response = oauth.doRefreshTokenRequest(oldOfflineToken, "b2c07929-69e3-44c6-8d7f-76939000b3e4");
|
||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||
assertEquals("migration-test-user", accessToken.getPreferredUsername());
|
||||
}
|
||||
}
|
||||
|
||||
private String getMigrationMode() {
|
||||
return System.getProperty("migration.mode");
|
||||
}
|
||||
|
||||
private boolean isImportMigrationMode() {
|
||||
String mode = getMigrationMode();
|
||||
return "import".equals(mode);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue