Merge pull request #2517 from mposolda/master
KEYCLOAK-1982 Some builtin objects might be missing when import JSON exported from previous versions
This commit is contained in:
commit
c469109d22
8 changed files with 779 additions and 60 deletions
|
@ -114,8 +114,11 @@ public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider {
|
||||||
List<Update> updatesToRun = getUpdatesToRun(executed);
|
List<Update> updatesToRun = getUpdatesToRun(executed);
|
||||||
|
|
||||||
if (!updatesToRun.isEmpty()) {
|
if (!updatesToRun.isEmpty()) {
|
||||||
String errorMessage = String.format("Failed to validate Mongo database schema. Schema needs updating database from %s to %s. Please change databaseSchema to 'update'",
|
String errorMessage = (executed.isEmpty())
|
||||||
|
? "Failed to validate Mongo database schema. Database is empty. Please change databaseSchema to 'update'"
|
||||||
|
: String.format("Failed to validate Mongo database schema. Schema needs updating database from %s to %s. Please change databaseSchema to 'update'",
|
||||||
executed.get(executed.size() - 1), updatesToRun.get(updatesToRun.size() - 1).getId());
|
executed.get(executed.size() - 1), updatesToRun.get(updatesToRun.size() - 1).getId());
|
||||||
|
|
||||||
throw new RuntimeException(errorMessage);
|
throw new RuntimeException(errorMessage);
|
||||||
} else {
|
} else {
|
||||||
log.debug("Validation passed. Database is up to date");
|
log.debug("Validation passed. Database is up to date");
|
||||||
|
|
|
@ -28,7 +28,6 @@ public interface Constants {
|
||||||
String ADMIN_CLI_CLIENT_ID = "admin-cli";
|
String ADMIN_CLI_CLIENT_ID = "admin-cli";
|
||||||
|
|
||||||
String ACCOUNT_MANAGEMENT_CLIENT_ID = "account";
|
String ACCOUNT_MANAGEMENT_CLIENT_ID = "account";
|
||||||
String IMPERSONATION_SERVICE_CLIENT_ID = "impersonation";
|
|
||||||
String BROKER_SERVICE_CLIENT_ID = "broker";
|
String BROKER_SERVICE_CLIENT_ID = "broker";
|
||||||
String REALM_MANAGEMENT_CLIENT_ID = "realm-management";
|
String REALM_MANAGEMENT_CLIENT_ID = "realm-management";
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||||
import org.keycloak.representations.idm.ApplicationRepresentation;
|
import org.keycloak.representations.idm.ApplicationRepresentation;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.OAuthClientRepresentation;
|
import org.keycloak.representations.idm.OAuthClientRepresentation;
|
||||||
|
@ -111,6 +113,7 @@ public class RealmManager implements RealmImporter {
|
||||||
setupAccountManagement(realm);
|
setupAccountManagement(realm);
|
||||||
setupBrokerService(realm);
|
setupBrokerService(realm);
|
||||||
setupAdminConsole(realm);
|
setupAdminConsole(realm);
|
||||||
|
setupAdminConsoleLocaleMapper(realm);
|
||||||
setupAdminCli(realm);
|
setupAdminCli(realm);
|
||||||
setupImpersonationService(realm);
|
setupImpersonationService(realm);
|
||||||
setupAuthenticationFlows(realm);
|
setupAuthenticationFlows(realm);
|
||||||
|
@ -143,9 +146,6 @@ public class RealmManager implements RealmImporter {
|
||||||
adminConsole.addRedirectUri(baseUrl + "/*");
|
adminConsole.addRedirectUri(baseUrl + "/*");
|
||||||
adminConsole.setFullScopeAllowed(false);
|
adminConsole.setFullScopeAllowed(false);
|
||||||
|
|
||||||
ProtocolMapperModel localeMapper = ProtocolMapperUtils.findLocaleMapper(session);
|
|
||||||
if (localeMapper != null) adminConsole.addProtocolMapper(localeMapper);
|
|
||||||
|
|
||||||
RoleModel adminRole;
|
RoleModel adminRole;
|
||||||
if (realm.getName().equals(Config.getAdminRealm())) {
|
if (realm.getName().equals(Config.getAdminRealm())) {
|
||||||
adminRole = realm.getRole(AdminRoles.ADMIN);
|
adminRole = realm.getRole(AdminRoles.ADMIN);
|
||||||
|
@ -157,6 +157,18 @@ public class RealmManager implements RealmImporter {
|
||||||
adminConsole.addScopeMapping(adminRole);
|
adminConsole.addScopeMapping(adminRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setupAdminConsoleLocaleMapper(RealmModel realm) {
|
||||||
|
ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
|
||||||
|
ProtocolMapperModel localeMapper = adminConsole.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, OIDCLoginProtocolFactory.LOCALE);
|
||||||
|
|
||||||
|
if (localeMapper == null) {
|
||||||
|
localeMapper = ProtocolMapperUtils.findLocaleMapper(session);
|
||||||
|
if (localeMapper != null) {
|
||||||
|
adminConsole.addProtocolMapper(localeMapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setupAdminCli(RealmModel realm) {
|
public void setupAdminCli(RealmModel realm) {
|
||||||
ClientModel adminCli = realm.getClientByClientId(Constants.ADMIN_CLI_CLIENT_ID);
|
ClientModel adminCli = realm.getClientByClientId(Constants.ADMIN_CLI_CLIENT_ID);
|
||||||
if (adminCli == null) {
|
if (adminCli == null) {
|
||||||
|
@ -254,6 +266,7 @@ public class RealmManager implements RealmImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setupMasterAdminManagement(RealmModel realm) {
|
private void setupMasterAdminManagement(RealmModel realm) {
|
||||||
// Need to refresh masterApp for current realm
|
// Need to refresh masterApp for current realm
|
||||||
String adminRealmId = Config.getAdminRealm();
|
String adminRealmId = Config.getAdminRealm();
|
||||||
|
@ -262,11 +275,11 @@ public class RealmManager implements RealmImporter {
|
||||||
if (masterApp != null) {
|
if (masterApp != null) {
|
||||||
realm.setMasterAdminClient(masterApp);
|
realm.setMasterAdminClient(masterApp);
|
||||||
} else {
|
} else {
|
||||||
createMasterAdminManagement(model, realm);
|
createMasterAdminManagement(realm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMasterAdminManagement(RealmProvider model, RealmModel realm) {
|
private void createMasterAdminManagement(RealmModel realm) {
|
||||||
RealmModel adminRealm;
|
RealmModel adminRealm;
|
||||||
RoleModel adminRole;
|
RoleModel adminRole;
|
||||||
|
|
||||||
|
@ -300,11 +313,23 @@ public class RealmManager implements RealmImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkMasterAdminManagementRoles(RealmModel realm) {
|
||||||
|
RealmModel adminRealm = model.getRealmByName(Config.getAdminRealm());
|
||||||
|
RoleModel adminRole = adminRealm.getRole(AdminRoles.ADMIN);
|
||||||
|
|
||||||
|
ClientModel masterAdminClient = realm.getMasterAdminClient();
|
||||||
|
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
||||||
|
RoleModel found = masterAdminClient.getRole(r);
|
||||||
|
if (found == null) {
|
||||||
|
addAndSetAdminRole(r, masterAdminClient, adminRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setupRealmAdminManagement(RealmModel realm) {
|
private void setupRealmAdminManagement(RealmModel realm) {
|
||||||
if (realm.getName().equals(Config.getAdminRealm())) { return; } // don't need to do this for master realm
|
if (realm.getName().equals(Config.getAdminRealm())) { return; } // don't need to do this for master realm
|
||||||
|
|
||||||
ClientManager clientManager = new ClientManager(new RealmManager(session));
|
|
||||||
|
|
||||||
String realmAdminClientId = getRealmAdminClientId(realm);
|
String realmAdminClientId = getRealmAdminClientId(realm);
|
||||||
ClientModel realmAdminClient = realm.getClientByClientId(realmAdminClientId);
|
ClientModel realmAdminClient = realm.getClientByClientId(realmAdminClientId);
|
||||||
if (realmAdminClient == null) {
|
if (realmAdminClient == null) {
|
||||||
|
@ -318,10 +343,30 @@ public class RealmManager implements RealmImporter {
|
||||||
realmAdminClient.setFullScopeAllowed(false);
|
realmAdminClient.setFullScopeAllowed(false);
|
||||||
|
|
||||||
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
||||||
RoleModel role = realmAdminClient.addRole(r);
|
addAndSetAdminRole(r, realmAdminClient, adminRole);
|
||||||
role.setDescription("${role_"+r+"}");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAndSetAdminRole(String roleName, ClientModel parentClient, RoleModel parentRole) {
|
||||||
|
RoleModel role = parentClient.addRole(roleName);
|
||||||
|
role.setDescription("${role_" + roleName + "}");
|
||||||
role.setScopeParamRequired(false);
|
role.setScopeParamRequired(false);
|
||||||
adminRole.addCompositeRole(role);
|
parentRole.addCompositeRole(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkRealmAdminManagementRoles(RealmModel realm) {
|
||||||
|
if (realm.getName().equals(Config.getAdminRealm())) { return; } // don't need to do this for master realm
|
||||||
|
|
||||||
|
String realmAdminClientId = getRealmAdminClientId(realm);
|
||||||
|
ClientModel realmAdminClient = realm.getClientByClientId(realmAdminClientId);
|
||||||
|
RoleModel adminRole = realmAdminClient.getRole(AdminRoles.REALM_ADMIN);
|
||||||
|
|
||||||
|
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
||||||
|
RoleModel found = realmAdminClient.getRole(r);
|
||||||
|
if (found == null) {
|
||||||
|
addAndSetAdminRole(r, realmAdminClient, adminRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,13 +434,12 @@ public class RealmManager implements RealmImporter {
|
||||||
if (!hasAccountManagementClient(rep)) setupAccountManagement(realm);
|
if (!hasAccountManagementClient(rep)) setupAccountManagement(realm);
|
||||||
|
|
||||||
boolean postponeImpersonationSetup = false;
|
boolean postponeImpersonationSetup = false;
|
||||||
if (!hasImpersonationServiceClient(rep)) {
|
|
||||||
if (hasRealmAdminManagementClient(rep)) {
|
if (hasRealmAdminManagementClient(rep)) {
|
||||||
postponeImpersonationSetup = true;
|
postponeImpersonationSetup = true;
|
||||||
} else {
|
} else {
|
||||||
setupImpersonationService(realm);
|
setupImpersonationService(realm);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasBrokerClient(rep)) setupBrokerService(realm);
|
if (!hasBrokerClient(rep)) setupBrokerService(realm);
|
||||||
if (!hasAdminConsoleClient(rep)) setupAdminConsole(realm);
|
if (!hasAdminConsoleClient(rep)) setupAdminConsole(realm);
|
||||||
|
@ -413,10 +457,16 @@ public class RealmManager implements RealmImporter {
|
||||||
|
|
||||||
RepresentationToModel.importRealm(session, rep, realm);
|
RepresentationToModel.importRealm(session, rep, realm);
|
||||||
|
|
||||||
|
setupAdminConsoleLocaleMapper(realm);
|
||||||
|
|
||||||
if (postponeMasterClientSetup) {
|
if (postponeMasterClientSetup) {
|
||||||
setupMasterAdminManagement(realm);
|
setupMasterAdminManagement(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assert all admin roles are available once import took place. This is needed due to import from previous version where JSON file may not contain all admin roles
|
||||||
|
checkMasterAdminManagementRoles(realm);
|
||||||
|
checkRealmAdminManagementRoles(realm);
|
||||||
|
|
||||||
// Could happen when migrating from older version and I have exported JSON file, which contains "realm-management" client but not "impersonation" client
|
// Could happen when migrating from older version and I have exported JSON file, which contains "realm-management" client but not "impersonation" client
|
||||||
// I need to postpone impersonation because it needs "realm-management" client and its roles set
|
// I need to postpone impersonation because it needs "realm-management" client and its roles set
|
||||||
if (postponeImpersonationSetup) {
|
if (postponeImpersonationSetup) {
|
||||||
|
@ -455,9 +505,7 @@ public class RealmManager implements RealmImporter {
|
||||||
private boolean hasAccountManagementClient(RealmRepresentation rep) {
|
private boolean hasAccountManagementClient(RealmRepresentation rep) {
|
||||||
return hasClient(rep, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
return hasClient(rep, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||||
}
|
}
|
||||||
private boolean hasImpersonationServiceClient(RealmRepresentation rep) {
|
|
||||||
return hasClient(rep, Constants.IMPERSONATION_SERVICE_CLIENT_ID);
|
|
||||||
}
|
|
||||||
private boolean hasBrokerClient(RealmRepresentation rep) {
|
private boolean hasBrokerClient(RealmRepresentation rep) {
|
||||||
return hasClient(rep, Constants.BROKER_SERVICE_CLIENT_ID);
|
return hasClient(rep, Constants.BROKER_SERVICE_CLIENT_ID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.jboss.resteasy.spi.ResteasyDeployment;
|
||||||
import org.jboss.shrinkwrap.api.Archive;
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
|
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
|
||||||
import org.jboss.shrinkwrap.undertow.api.UndertowWebArchive;
|
import org.jboss.shrinkwrap.undertow.api.UndertowWebArchive;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.services.filters.KeycloakSessionServletFilter;
|
import org.keycloak.services.filters.KeycloakSessionServletFilter;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
|
|
||||||
private UndertowJaxrsServer undertow;
|
private UndertowJaxrsServer undertow;
|
||||||
private KeycloakOnUndertowConfiguration configuration;
|
private KeycloakOnUndertowConfiguration configuration;
|
||||||
|
private KeycloakSessionFactory sessionFactory;
|
||||||
|
|
||||||
private DeploymentInfo createAuthServerDeploymentInfo() {
|
private DeploymentInfo createAuthServerDeploymentInfo() {
|
||||||
ResteasyDeployment deployment = new ResteasyDeployment();
|
ResteasyDeployment deployment = new ResteasyDeployment();
|
||||||
|
@ -130,7 +132,11 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
.setIoThreads(configuration.getWorkerThreads() / 8)
|
.setIoThreads(configuration.getWorkerThreads() / 8)
|
||||||
);
|
);
|
||||||
|
|
||||||
undertow.deploy(createAuthServerDeploymentInfo());
|
DeploymentInfo di = createAuthServerDeploymentInfo();
|
||||||
|
undertow.deploy(di);
|
||||||
|
ResteasyDeployment deployment = (ResteasyDeployment) di.getServletContextAttributes().get(ResteasyDeployment.class.getName());
|
||||||
|
sessionFactory = ((KeycloakApplication) deployment.getApplication()).getSessionFactory();
|
||||||
|
|
||||||
|
|
||||||
log.info("Auth server started in " + (System.currentTimeMillis() - start) + " ms\n");
|
log.info("Auth server started in " + (System.currentTimeMillis() - start) + " ms\n");
|
||||||
}
|
}
|
||||||
|
@ -138,6 +144,7 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
@Override
|
@Override
|
||||||
public void stop() throws LifecycleException {
|
public void stop() throws LifecycleException {
|
||||||
log.info("Stopping auth server.");
|
log.info("Stopping auth server.");
|
||||||
|
sessionFactory.close();
|
||||||
undertow.stop();
|
undertow.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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.exportimport;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.spi.Container;
|
||||||
|
import org.jboss.arquillian.container.spi.client.container.LifecycleException;
|
||||||
|
import org.keycloak.exportimport.ExportImportConfig;
|
||||||
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractExportImportTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
|
|
||||||
|
public void clearExportImportProperties() {
|
||||||
|
// Clear export/import properties after test
|
||||||
|
Properties systemProps = System.getProperties();
|
||||||
|
Set<String> propsToRemove = new HashSet<String>();
|
||||||
|
|
||||||
|
for (Object key : systemProps.keySet()) {
|
||||||
|
if (key.toString().startsWith(ExportImportConfig.PREFIX)) {
|
||||||
|
propsToRemove.add(key.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String propToRemove : propsToRemove) {
|
||||||
|
systemProps.remove(propToRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void restartServer() throws LifecycleException {
|
||||||
|
Container arqContainer = suiteContext.getAuthServerInfo().getArquillianContainer();
|
||||||
|
arqContainer.stop();
|
||||||
|
arqContainer.start();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* 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.exportimport;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.spi.client.container.LifecycleException;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.admin.client.resource.ClientResource;
|
||||||
|
import org.keycloak.exportimport.ExportImportConfig;
|
||||||
|
import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
|
||||||
|
import org.keycloak.models.AdminRoles;
|
||||||
|
import org.keycloak.models.ImpersonationConstants;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||||
|
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test importing JSON files exported from previous keycloak versions
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class LegacyImportTest extends AbstractExportImportTest {
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
clearExportImportProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void importFrom11() throws LifecycleException {
|
||||||
|
// Setup system properties for import ( TODO: Does this work with external container? )
|
||||||
|
ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID);
|
||||||
|
URL url = LegacyImportTest.class.getResource("/exportimport-test/kc11-exported-realm.json");
|
||||||
|
String targetFilePath = new File(url.getFile()).getAbsolutePath();
|
||||||
|
ExportImportConfig.setFile(targetFilePath);
|
||||||
|
ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT);
|
||||||
|
|
||||||
|
// Restart to enforce full import
|
||||||
|
restartServer();
|
||||||
|
|
||||||
|
|
||||||
|
// Assert "locale" mapper available in security-admin-console client for both master and foo11 realm
|
||||||
|
ClientResource foo11AdminConsoleClient = adminClient.realm("foo11").clients().get("a9ca4217-74a8-4658-92c8-c2f9ed48a474");
|
||||||
|
assertLocaleMapperPresent(foo11AdminConsoleClient);
|
||||||
|
|
||||||
|
ClientResource masterAdminConsoleClient = adminClient.realm(Config.getAdminRealm()).clients().get("22ed594d-8c21-43f0-a080-c8879a411f94");
|
||||||
|
assertLocaleMapperPresent(masterAdminConsoleClient);
|
||||||
|
|
||||||
|
|
||||||
|
// Assert "realm-management" role correctly set and contains all admin roles.
|
||||||
|
ClientResource foo11RealmManagementClient = adminClient.realm("foo11").clients().get("c7a9cf59-feeb-44a4-a467-e008e157efa2");
|
||||||
|
List<RoleRepresentation> roles = foo11RealmManagementClient.roles().list();
|
||||||
|
assertRolesAvailable(roles);
|
||||||
|
|
||||||
|
// Assert all admin roles are also available as composites of "realm-admin"
|
||||||
|
Set<RoleRepresentation> realmAdminComposites = foo11RealmManagementClient.roles().get(AdminRoles.REALM_ADMIN).getChildren();
|
||||||
|
assertRolesAvailable(realmAdminComposites);
|
||||||
|
|
||||||
|
// Assert "foo11-master" client correctly set and contains all admin roles.
|
||||||
|
ClientResource foo11MasterAdminClient = adminClient.realm(Config.getAdminRealm()).clients().get("c9c3bd5f-b69d-4640-8b27-45d4f3866a36");
|
||||||
|
roles = foo11MasterAdminClient.roles().list();
|
||||||
|
assertRolesAvailable(roles);
|
||||||
|
|
||||||
|
// Assert all admin roles are also available as composites of "admin" role
|
||||||
|
Set<RoleRepresentation> masterAdminComposites = adminClient.realm(Config.getAdminRealm()).roles().get(AdminRoles.ADMIN).getChildren();
|
||||||
|
assertRolesAvailable(masterAdminComposites);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void assertLocaleMapperPresent(ClientResource client) {
|
||||||
|
List<ProtocolMapperRepresentation> protMappers = client.getProtocolMappers().getMappersPerProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||||
|
for (ProtocolMapperRepresentation protMapper : protMappers) {
|
||||||
|
if (protMapper.getName().equals(OIDCLoginProtocolFactory.LOCALE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.fail("Locale mapper not found for client");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void assertRolesAvailable(Collection<RoleRepresentation> roles) {
|
||||||
|
assertRoleAvailable(roles, AdminRoles.VIEW_IDENTITY_PROVIDERS);
|
||||||
|
assertRoleAvailable(roles, AdminRoles.MANAGE_IDENTITY_PROVIDERS);
|
||||||
|
assertRoleAvailable(roles, AdminRoles.CREATE_CLIENT);
|
||||||
|
assertRoleAvailable(roles, ImpersonationConstants.IMPERSONATION_ROLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private RoleRepresentation assertRoleAvailable(Collection<RoleRepresentation> roles, String roleName) {
|
||||||
|
for (RoleRepresentation role : roles) {
|
||||||
|
if (role.getName().equals(roleName)) {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.fail("Role " + roleName + " not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,494 @@
|
||||||
|
[ {
|
||||||
|
"id" : "master",
|
||||||
|
"realm" : "master",
|
||||||
|
"notBefore" : 0,
|
||||||
|
"accessTokenLifespan" : 60,
|
||||||
|
"ssoSessionIdleTimeout" : 1800,
|
||||||
|
"ssoSessionMaxLifespan" : 36000,
|
||||||
|
"accessCodeLifespan" : 60,
|
||||||
|
"accessCodeLifespanUserAction" : 300,
|
||||||
|
"enabled" : true,
|
||||||
|
"sslRequired" : "external",
|
||||||
|
"passwordCredentialGrantAllowed" : false,
|
||||||
|
"registrationAllowed" : false,
|
||||||
|
"rememberMe" : false,
|
||||||
|
"verifyEmail" : false,
|
||||||
|
"resetPasswordAllowed" : false,
|
||||||
|
"social" : false,
|
||||||
|
"updateProfileOnInitialSocialLogin" : false,
|
||||||
|
"bruteForceProtected" : false,
|
||||||
|
"maxFailureWaitSeconds" : 900,
|
||||||
|
"minimumQuickLoginWaitSeconds" : 60,
|
||||||
|
"waitIncrementSeconds" : 60,
|
||||||
|
"quickLoginCheckMilliSeconds" : 1000,
|
||||||
|
"maxDeltaTimeSeconds" : 43200,
|
||||||
|
"failureFactor" : 30,
|
||||||
|
"privateKey" : "MIICXQIBAAKBgQC5lddWO92keqWg+QmMUj/jxA2kwH22UZ0iE9454Ail9JnOvwOTXSP8M92JN7D7DSJM/J45E2Kju5RrQ/QM8bBwYPk/vZlQkJcKbnrkQFtUdBrjoaMQlDvoaqIx1u4irSj2phRPR8teT72A867JGnW2clIwScl2dznZs2Br+jCN3QIDAQABAoGBAKdfFMqnyRfKqM+JaewMTaR7rxZTp8yixET0iCnH++S3uXM03+OqT4bnu7dB67IuwS2Pcp7k9cPWq18l9NcrrcPQCS5knpoNzDO2RuLfXDUCGG/N3MMmthRAeILHun8/CBSfBbcdJESn67g4RV5AldWf8dSgwUcwN4RxbnfUdIbdAkEA9ko38bhfszg9VRea/XVNIpUBQZXpsHt951GoL1Sz0u5iUADyDc/lLgV+eNA9mclvBpg+S+2jcAWMY1rN34wU5wJBAMDm78sYQK8ert+bJV8OSl+6Rpu3cLSdBWNnHZWBpDUHO9JlD2GQblDR3MoL+2j0W/F+7MLhT/LZPQkvMCM+KpsCQGoS+RlQcVc9B51Yd1ZmaPxV9J6MtINgDI/OKYOJFZHpPcp7PcUZHvm9QAVEmuNbUEgk1d/Zz6R1n0tDVpvLN00CQQCH0tNq3DPHWkJlXXdN2+EQUDehMuOfuKPvns5c08CMOgCsHs5asviJ3YqplRA7kTsf6m/ItB637rAkRF6PohkbAkBi9CUTSy32o0AKBuhPDVJOgTqfvlNqmraa/0V65IDhactJ3hmgJXpUI7F0u42NU0uXgU5QMFwHet1sSWxnGcaa",
|
||||||
|
"publicKey" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5lddWO92keqWg+QmMUj/jxA2kwH22UZ0iE9454Ail9JnOvwOTXSP8M92JN7D7DSJM/J45E2Kju5RrQ/QM8bBwYPk/vZlQkJcKbnrkQFtUdBrjoaMQlDvoaqIx1u4irSj2phRPR8teT72A867JGnW2clIwScl2dznZs2Br+jCN3QIDAQAB",
|
||||||
|
"certificate" : "MIIBlTCB/wIGAVPnGdy9MA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBm1hc3RlcjAeFw0xNjA0MDUxNTQ0MDVaFw0yNjA0MDUxNTQ1NDVaMBExDzANBgNVBAMTBm1hc3RlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuZXXVjvdpHqloPkJjFI/48QNpMB9tlGdIhPeOeAIpfSZzr8Dk10j/DPdiTew+w0iTPyeORNio7uUa0P0DPGwcGD5P72ZUJCXCm565EBbVHQa46GjEJQ76GqiMdbuIq0o9qYUT0fLXk+9gPOuyRp1tnJSMEnJdnc52bNga/owjd0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQBqQFaqBy50CddfEHPhlf5YDUmTwZIoX/rh74vTESl7thzRQpQ6LhKVI3hfBNI91Xcr58J1WEA3Lm93T7yC5/ShsGbDJi8RJTDhQYY6LBhxT2ZSq+RLFaWyloFLa5V7hTY4F73yml4IM5mKLMmvcxr4xIZvPkKsvR0C+y9yb4dEzg==",
|
||||||
|
"codeSecret" : "8669f9cf-6715-48f0-929d-ec5d66a6efcf",
|
||||||
|
"roles" : {
|
||||||
|
"realm" : [ {
|
||||||
|
"id" : "db49ad9b-6784-4eb8-bedd-07ff716098c0",
|
||||||
|
"name" : "admin",
|
||||||
|
"composite" : true,
|
||||||
|
"composites" : {
|
||||||
|
"realm" : [ "create-realm" ],
|
||||||
|
"application" : {
|
||||||
|
"foo11-realm" : [ "view-events", "view-realm", "manage-events", "manage-clients", "manage-realm", "view-clients", "view-users", "manage-applications", "manage-users", "view-applications" ],
|
||||||
|
"master-realm" : [ "view-realm", "manage-applications", "manage-realm", "manage-users", "view-events", "manage-events", "view-applications", "view-users", "view-clients", "manage-clients" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"id" : "f6b11ea0-0287-4631-9ce1-df4c5998f840",
|
||||||
|
"name" : "create-realm",
|
||||||
|
"composite" : false
|
||||||
|
} ],
|
||||||
|
"application" : {
|
||||||
|
"security-admin-console" : [ ],
|
||||||
|
"foo11-realm" : [ {
|
||||||
|
"id" : "90a00c88-2ad5-4b38-81b2-3ba4583c67c9",
|
||||||
|
"name" : "manage-clients",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "d103fd4a-55f2-409f-8357-5f9645463ac3",
|
||||||
|
"name" : "view-events",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "76952522-6671-4abb-90a9-e6256386b8d3",
|
||||||
|
"name" : "manage-realm",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "973ebcfb-37b2-43ce-af5a-acbc48429c86",
|
||||||
|
"name" : "view-clients",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "b32deca4-a345-4fb6-a6ce-f8666e653c16",
|
||||||
|
"name" : "view-users",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "f030bd3b-3ef8-496c-9c75-f370f19f7a56",
|
||||||
|
"name" : "manage-applications",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "b196345c-07ca-4dea-8a35-84f5aa41f177",
|
||||||
|
"name" : "view-realm",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "747c7af4-60a0-4be4-9c7a-33969572f3e1",
|
||||||
|
"name" : "manage-users",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "ff468d9b-4d5a-4a03-9640-24b0a94a238f",
|
||||||
|
"name" : "manage-events",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "61f9766c-44c2-4195-b9b8-c23d63409c16",
|
||||||
|
"name" : "view-applications",
|
||||||
|
"composite" : false
|
||||||
|
} ],
|
||||||
|
"master-realm" : [ {
|
||||||
|
"id" : "21866bbb-60de-4248-879f-ceb11a75f4e6",
|
||||||
|
"name" : "view-applications",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "267071a5-170f-4438-b333-3d00a0ec268f",
|
||||||
|
"name" : "view-realm",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "53a53160-92b3-43a4-9ba1-a0c19eaf1ad9",
|
||||||
|
"name" : "manage-applications",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "2ce8b8ba-5e15-4a04-bedb-96d74784fd54",
|
||||||
|
"name" : "manage-realm",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "d7045c16-29cb-4e88-bd61-7d6fd77e6c7d",
|
||||||
|
"name" : "manage-users",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "6f933ebd-bbf5-4fea-b4e1-ace854667b9b",
|
||||||
|
"name" : "view-events",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "3588ffcb-96cc-4263-8244-1b71d441202a",
|
||||||
|
"name" : "view-users",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "5a4bcd8f-8cc9-4a01-94d1-3b8a86e228af",
|
||||||
|
"name" : "view-clients",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "5c42606c-f3ec-4abd-aad0-9ec98d6fa39f",
|
||||||
|
"name" : "manage-events",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "678d5c25-b5b0-4447-95c1-b3dc14fa0e3f",
|
||||||
|
"name" : "manage-clients",
|
||||||
|
"composite" : false
|
||||||
|
} ],
|
||||||
|
"account" : [ {
|
||||||
|
"id" : "700d3f40-8e11-47d7-b3f1-14d07a7da647",
|
||||||
|
"name" : "manage-account",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "a9d81246-ec6c-4b71-912a-7a1518ec64d5",
|
||||||
|
"name" : "view-profile",
|
||||||
|
"composite" : false
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requiredCredentials" : [ "password" ],
|
||||||
|
"users" : [ {
|
||||||
|
"id" : "d678f579-29f4-46d5-a124-8bcdbeeeb55d",
|
||||||
|
"username" : "admin",
|
||||||
|
"enabled" : true,
|
||||||
|
"totp" : false,
|
||||||
|
"emailVerified" : false,
|
||||||
|
"credentials" : [ {
|
||||||
|
"type" : "password",
|
||||||
|
"hashedSaltedValue" : "VIw4dTFMrU8aw3xvsI6Kqh2gA5Y0P2TJEyEmgplkColwuXUC2G+RTsahsOgqwG9yIgyrFS9Fe+GlPNUQWxO1Sw==",
|
||||||
|
"salt" : "5IsVTxiv9At7xTHoTN17+g==",
|
||||||
|
"hashIterations" : 1,
|
||||||
|
"temporary" : false
|
||||||
|
} ],
|
||||||
|
"requiredActions" : [ ],
|
||||||
|
"realmRoles" : [ "admin" ],
|
||||||
|
"applicationRoles" : {
|
||||||
|
"account" : [ "manage-account", "view-profile" ]
|
||||||
|
}
|
||||||
|
} ],
|
||||||
|
"scopeMappings" : [ {
|
||||||
|
"client" : "security-admin-console",
|
||||||
|
"roles" : [ "admin" ]
|
||||||
|
} ],
|
||||||
|
"applications" : [ {
|
||||||
|
"id" : "4fe35549-1d84-440e-83c6-48cad624aba4",
|
||||||
|
"name" : "master-realm",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "0da9f8c5-ee7a-4d4b-9c93-944ac72b7ef0",
|
||||||
|
"redirectUris" : [ ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : true,
|
||||||
|
"publicClient" : false,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : true,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
}, {
|
||||||
|
"id" : "5b2a2ae8-f0b9-40cc-a586-4adf46379a49",
|
||||||
|
"name" : "account",
|
||||||
|
"baseUrl" : "/auth/realms/master/account",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "f055644e-e59e-462f-98fd-9a5b7c22e03a",
|
||||||
|
"defaultRoles" : [ "view-profile", "manage-account" ],
|
||||||
|
"redirectUris" : [ "/auth/realms/master/account/*" ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : false,
|
||||||
|
"publicClient" : false,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : false,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
}, {
|
||||||
|
"id" : "22ed594d-8c21-43f0-a080-c8879a411f94",
|
||||||
|
"name" : "security-admin-console",
|
||||||
|
"baseUrl" : "/auth/admin/master/console/index.html",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "bf9b9f8b-0a85-42da-bc14-befab4305298",
|
||||||
|
"redirectUris" : [ "/auth/admin/master/console/*" ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : false,
|
||||||
|
"publicClient" : true,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : false,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
}, {
|
||||||
|
"id" : "c9c3bd5f-b69d-4640-8b27-45d4f3866a36",
|
||||||
|
"name" : "foo11-realm",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "aba746f8-fafd-4d6d-af65-e0bb669b1afc",
|
||||||
|
"redirectUris" : [ ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : true,
|
||||||
|
"publicClient" : false,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : true,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
} ],
|
||||||
|
"oauthClients" : [ ],
|
||||||
|
"browserSecurityHeaders" : {
|
||||||
|
"xFrameOptions" : "SAMEORIGIN",
|
||||||
|
"contentSecurityPolicy" : "frame-src 'self'"
|
||||||
|
},
|
||||||
|
"socialProviders" : { },
|
||||||
|
"smtpServer" : { },
|
||||||
|
"eventsEnabled" : false,
|
||||||
|
"eventsListeners" : [ ]
|
||||||
|
}, {
|
||||||
|
"id" : "14e6923c-f5fb-44aa-8982-35d4976c56c5",
|
||||||
|
"realm" : "foo11",
|
||||||
|
"notBefore" : 0,
|
||||||
|
"accessTokenLifespan" : 300,
|
||||||
|
"ssoSessionIdleTimeout" : 1800,
|
||||||
|
"ssoSessionMaxLifespan" : 36000,
|
||||||
|
"accessCodeLifespan" : 60,
|
||||||
|
"accessCodeLifespanUserAction" : 300,
|
||||||
|
"enabled" : true,
|
||||||
|
"sslRequired" : "external",
|
||||||
|
"passwordCredentialGrantAllowed" : false,
|
||||||
|
"registrationAllowed" : false,
|
||||||
|
"rememberMe" : false,
|
||||||
|
"verifyEmail" : false,
|
||||||
|
"resetPasswordAllowed" : false,
|
||||||
|
"social" : false,
|
||||||
|
"updateProfileOnInitialSocialLogin" : false,
|
||||||
|
"bruteForceProtected" : false,
|
||||||
|
"maxFailureWaitSeconds" : 900,
|
||||||
|
"minimumQuickLoginWaitSeconds" : 60,
|
||||||
|
"waitIncrementSeconds" : 60,
|
||||||
|
"quickLoginCheckMilliSeconds" : 1000,
|
||||||
|
"maxDeltaTimeSeconds" : 43200,
|
||||||
|
"failureFactor" : 30,
|
||||||
|
"privateKey" : "MIICXQIBAAKBgQC05JPgp3F/lxuKMmf6TNs5YtumvoFL88eQ9UPhYn768CHc/PDNRBu3VN8GxwgbkUEX/I5s+nTWo8bKJAxdDyGRlAYItanJxH5iCe152cuEAY0kkHunDvsgAKx7snUztYJ7kC1b+B8I+9a6D0yXwwAZMHlOvF+QXKIiDzB8Cvww+QIDAQABAoGAIW/G7dXFowH5czgSBDBErXzagR3hpHpxPxg27ehY9GWCvOh8UlTukpq7hvMvSnk1AQwL/5TkF/C6BA9ZwbHUUFZduRFuut/Dsm8FtT5MiwdjmBBbcoQNZ6MlC4meHZBR/cRvu5ABQa2ChR6csMDISSHSh2lliPticfvZWZyKvAECQQDylYgBDeL6/0q+GCS1lO2FIncg/sRVqINZI7Ald+C3+VHtWlvPqbMvUDBKFBQMV4qH+JOUkvVLgXITbZHGAaK5AkEAvuWhpdzbR9CdxMsOeVb6Jg5MJGSbZBNY+e/diqwbnSNtt1VYqrPEeaOwFLm7g7/ODbwsDBh2sw68898zr7DgQQJATaRuk2fObmenlJBFr5irLSGK35SrYn89CxrRFiz4T+oMvttc52p5X3ta+VrTz991B3AYTEV9HV2hFXbMYYPEgQJBAKtmy4l9kHYe3knAeLKCYgChfcR/gPaOWKmxsZ29gt3I3c5rFz3OQ29khclWKwPUyFKUzofdv1ZuuUHO+z2Y9wECQQC/AJmkiMWGp9Ol3gbM7KhLS8CFLxFlPdBav5EqOxPmFUQQvSStUq3zoLpuYJKlXC5D5tbd7pNf5b1XycEtbRXH",
|
||||||
|
"publicKey" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC05JPgp3F/lxuKMmf6TNs5YtumvoFL88eQ9UPhYn768CHc/PDNRBu3VN8GxwgbkUEX/I5s+nTWo8bKJAxdDyGRlAYItanJxH5iCe152cuEAY0kkHunDvsgAKx7snUztYJ7kC1b+B8I+9a6D0yXwwAZMHlOvF+QXKIiDzB8Cvww+QIDAQAB",
|
||||||
|
"certificate" : "MIIBkzCB/QIGAVPnGn2KMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNVBAMTBWZvbzExMB4XDTE2MDQwNTE1NDQ0NloXDTI2MDQwNTE1NDYyNlowEDEOMAwGA1UEAxMFZm9vMTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALTkk+CncX+XG4oyZ/pM2zli26a+gUvzx5D1Q+FifvrwIdz88M1EG7dU3wbHCBuRQRf8jmz6dNajxsokDF0PIZGUBgi1qcnEfmIJ7XnZy4QBjSSQe6cO+yAArHuydTO1gnuQLVv4Hwj71roPTJfDABkweU68X5BcoiIPMHwK/DD5AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAsB4JWLBGFIaPAJAnZ8BMGuVoQhNtRxUD4htX/enKpuiQM3u0Nw4sFotJG8xvnxucJheCB8DpvIcAVmaARqLJ0bvfJ4wbP70cWd3iCvxoiiXtjpSQy/0rOTeGiYcnnwZC+ffpOzTGe4OoPdYymjrmubeIyRrF+ijmH2n2Rn4ELXw=",
|
||||||
|
"codeSecret" : "0af1be0b-2fdb-4037-9e6a-1e3370bf9f15",
|
||||||
|
"roles" : {
|
||||||
|
"application" : {
|
||||||
|
"realm-management" : [ {
|
||||||
|
"id" : "eaaf02b4-a38e-4fca-8689-a4ace644c7d9",
|
||||||
|
"name" : "manage-applications",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "ce48589c-1459-4b75-ac99-45fd9255e562",
|
||||||
|
"name" : "manage-events",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "ac30d420-da49-4ac6-83f8-2a6be5b5435d",
|
||||||
|
"name" : "view-users",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "6f465ced-4722-4059-8300-104a68d5fd98",
|
||||||
|
"name" : "view-realm",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "0f3060f4-2097-4e8b-8852-b8b27be11b6b",
|
||||||
|
"name" : "view-events",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "1ceb312c-a5ae-4199-b567-81bef7d9103f",
|
||||||
|
"name" : "manage-realm",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "d36d799b-0fa1-48eb-8b45-3bfc1eab817e",
|
||||||
|
"name" : "view-applications",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "7d04fc11-2d52-4aca-9f79-e3d1782e4eef",
|
||||||
|
"name" : "manage-clients",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "1c233305-6941-407f-8058-dfdf40f7d87f",
|
||||||
|
"name" : "realm-admin",
|
||||||
|
"composite" : true,
|
||||||
|
"composites" : {
|
||||||
|
"application" : {
|
||||||
|
"realm-management" : [ "manage-applications", "manage-events", "view-users", "view-realm", "view-events", "manage-realm", "view-applications", "manage-clients", "view-clients", "manage-users" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"id" : "29fe8dc9-ec74-42bf-b11a-3592aa205612",
|
||||||
|
"name" : "view-clients",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "ac0059d0-bbe5-4247-ab82-5d408a1e9e19",
|
||||||
|
"name" : "manage-users",
|
||||||
|
"composite" : false
|
||||||
|
} ],
|
||||||
|
"security-admin-console" : [ ],
|
||||||
|
"account" : [ {
|
||||||
|
"id" : "44d8d987-62e4-4235-afd8-c0f7e7c5c280",
|
||||||
|
"name" : "view-profile",
|
||||||
|
"composite" : false
|
||||||
|
}, {
|
||||||
|
"id" : "03c1c19b-1732-488d-afc6-b5962e1d5fcd",
|
||||||
|
"name" : "manage-account",
|
||||||
|
"composite" : false
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requiredCredentials" : [ "password" ],
|
||||||
|
"users" : [ {
|
||||||
|
"id" : "2de2f04e-ff3b-4c22-b98d-6e3689bb2108",
|
||||||
|
"username" : "john11",
|
||||||
|
"enabled" : true,
|
||||||
|
"totp" : false,
|
||||||
|
"emailVerified" : false,
|
||||||
|
"email" : "john11@email.cz",
|
||||||
|
"credentials" : [ {
|
||||||
|
"type" : "password",
|
||||||
|
"hashedSaltedValue" : "2iUgsRh4EU4OV1nucya5UGCtQ34g/dpF8S1fKR77SsC0MrGpb1IKW7VOxGrooaQdxyzwFl48wXy68QFlkk6BcQ==",
|
||||||
|
"salt" : "rkzFU40mN8yVa7agq3SXMA==",
|
||||||
|
"hashIterations" : 1,
|
||||||
|
"temporary" : false
|
||||||
|
} ],
|
||||||
|
"requiredActions" : [ ],
|
||||||
|
"applicationRoles" : {
|
||||||
|
"realm-management" : [ "manage-applications" ],
|
||||||
|
"account" : [ "view-profile", "manage-account" ]
|
||||||
|
}
|
||||||
|
} ],
|
||||||
|
"applicationScopeMappings" : {
|
||||||
|
"realm-management" : [ {
|
||||||
|
"client" : "security-admin-console",
|
||||||
|
"roles" : [ "realm-admin" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"applications" : [ {
|
||||||
|
"id" : "c7a9cf59-feeb-44a4-a467-e008e157efa2",
|
||||||
|
"name" : "realm-management",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "1bceb96f-9abe-4a8a-9d76-5989e87a981e",
|
||||||
|
"redirectUris" : [ ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : true,
|
||||||
|
"publicClient" : false,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : false,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
}, {
|
||||||
|
"id" : "0715aa1a-0b7d-4594-a315-741205441910",
|
||||||
|
"name" : "account",
|
||||||
|
"baseUrl" : "/auth/realms/foo11/account",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "c7378e28-201c-4fd0-8482-ad5ea78adc51",
|
||||||
|
"defaultRoles" : [ "view-profile", "manage-account" ],
|
||||||
|
"redirectUris" : [ "/auth/realms/foo11/account/*" ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : false,
|
||||||
|
"publicClient" : false,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : false,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
}, {
|
||||||
|
"id" : "a9ca4217-74a8-4658-92c8-c2f9ed48a474",
|
||||||
|
"name" : "security-admin-console",
|
||||||
|
"baseUrl" : "/auth/admin/foo11/console/index.html",
|
||||||
|
"surrogateAuthRequired" : false,
|
||||||
|
"enabled" : true,
|
||||||
|
"secret" : "a5fd322f-6d2b-463c-b2af-bbc56f772462",
|
||||||
|
"redirectUris" : [ "/auth/admin/foo11/console/*" ],
|
||||||
|
"webOrigins" : [ ],
|
||||||
|
"claims" : {
|
||||||
|
"name" : true,
|
||||||
|
"username" : true,
|
||||||
|
"profile" : true,
|
||||||
|
"picture" : true,
|
||||||
|
"website" : true,
|
||||||
|
"email" : true,
|
||||||
|
"gender" : true,
|
||||||
|
"locale" : true,
|
||||||
|
"address" : true,
|
||||||
|
"phone" : true
|
||||||
|
},
|
||||||
|
"notBefore" : 0,
|
||||||
|
"bearerOnly" : false,
|
||||||
|
"publicClient" : true,
|
||||||
|
"attributes" : { },
|
||||||
|
"fullScopeAllowed" : false,
|
||||||
|
"nodeReRegistrationTimeout" : 0
|
||||||
|
} ],
|
||||||
|
"oauthClients" : [ ],
|
||||||
|
"browserSecurityHeaders" : {
|
||||||
|
"xFrameOptions" : "SAMEORIGIN",
|
||||||
|
"contentSecurityPolicy" : "frame-src 'self'"
|
||||||
|
},
|
||||||
|
"socialProviders" : { },
|
||||||
|
"smtpServer" : { },
|
||||||
|
"eventsEnabled" : false,
|
||||||
|
"eventsListeners" : [ ]
|
||||||
|
} ]
|
|
@ -51,6 +51,8 @@ import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO: Move to integration-arquillian and make subclass of AbstractExportImportTest
|
||||||
|
*
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class ExportImportTest {
|
public class ExportImportTest {
|
||||||
|
@ -58,14 +60,10 @@ public class ExportImportTest {
|
||||||
private static SystemPropertiesHelper propsHelper = new SystemPropertiesHelper();
|
private static SystemPropertiesHelper propsHelper = new SystemPropertiesHelper();
|
||||||
|
|
||||||
private static final String JPA_CONNECTION_URL = "keycloak.connectionsJpa.url";
|
private static final String JPA_CONNECTION_URL = "keycloak.connectionsJpa.url";
|
||||||
private static final String JPA_DB_SCHEMA = "keycloak.connectionsJpa.databaseSchema";
|
|
||||||
private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.connectionsMongo.clearOnStartup";
|
|
||||||
|
|
||||||
// We want data to be persisted among server restarts
|
// We want data to be persisted among server restarts
|
||||||
private static ExternalResource persistenceSetupRule = new ExternalResource() {
|
private static ExternalResource persistenceSetupRule = new ExternalResource() {
|
||||||
|
|
||||||
private boolean connectionURLSet = false;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void before() throws Throwable {
|
protected void before() throws Throwable {
|
||||||
if (System.getProperty(JPA_CONNECTION_URL) == null) {
|
if (System.getProperty(JPA_CONNECTION_URL) == null) {
|
||||||
|
@ -78,32 +76,13 @@ public class ExportImportTest {
|
||||||
|
|
||||||
String dbDir = baseExportImportDir + "/keycloakDB";
|
String dbDir = baseExportImportDir + "/keycloakDB";
|
||||||
propsHelper.pushProperty(JPA_CONNECTION_URL, "jdbc:h2:file:" + dbDir + ";DB_CLOSE_DELAY=-1");
|
propsHelper.pushProperty(JPA_CONNECTION_URL, "jdbc:h2:file:" + dbDir + ";DB_CLOSE_DELAY=-1");
|
||||||
connectionURLSet = true;
|
|
||||||
}
|
}
|
||||||
propsHelper.pushProperty(JPA_DB_SCHEMA, "update");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void after() {
|
protected void after() {
|
||||||
if (connectionURLSet) {
|
|
||||||
propsHelper.pullProperty(JPA_CONNECTION_URL);
|
propsHelper.pullProperty(JPA_CONNECTION_URL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static ExternalResource outerPersistenceSetupRule = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
System.setProperty(JPA_DB_SCHEMA, "update");
|
|
||||||
propsHelper.pushProperty(MONGO_CLEAR_ON_STARTUP, "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
propsHelper.pullProperty(JPA_DB_SCHEMA);
|
|
||||||
propsHelper.pullProperty(MONGO_CLEAR_ON_STARTUP);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule( new KeycloakRule.KeycloakSetup() {
|
private static KeycloakRule keycloakRule = new KeycloakRule( new KeycloakRule.KeycloakSetup() {
|
||||||
|
@ -130,6 +109,8 @@ public class ExportImportTest {
|
||||||
protected void after() {
|
protected void after() {
|
||||||
super.after();
|
super.after();
|
||||||
|
|
||||||
|
// TODO: Make this subclass of AbstractExportImportTest and use AbstractExportImportTest.clearExportImportProperties
|
||||||
|
|
||||||
// Clear export/import properties after test
|
// Clear export/import properties after test
|
||||||
Properties systemProps = System.getProperties();
|
Properties systemProps = System.getProperties();
|
||||||
Set<String> propsToRemove = new HashSet<String>();
|
Set<String> propsToRemove = new HashSet<String>();
|
||||||
|
@ -153,8 +134,7 @@ public class ExportImportTest {
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static TestRule chain = RuleChain
|
public static TestRule chain = RuleChain
|
||||||
.outerRule(persistenceSetupRule)
|
.outerRule(persistenceSetupRule)
|
||||||
.around(keycloakRule)
|
.around(keycloakRule);
|
||||||
.around(outerPersistenceSetupRule);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDirFullExportImport() throws Throwable {
|
public void testDirFullExportImport() throws Throwable {
|
||||||
|
@ -401,13 +381,12 @@ public class ExportImportTest {
|
||||||
|
|
||||||
private void pushProperty(String name, String value) {
|
private void pushProperty(String name, String value) {
|
||||||
String currentValue = System.getProperty(name);
|
String currentValue = System.getProperty(name);
|
||||||
if (currentValue != null) {
|
|
||||||
previousValues.put(name, currentValue);
|
previousValues.put(name, currentValue);
|
||||||
}
|
|
||||||
System.setProperty(name, value);
|
System.setProperty(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pullProperty(String name) {
|
private void pullProperty(String name) {
|
||||||
|
if (previousValues.containsKey(name)) {
|
||||||
String prevValue = previousValues.get(name);
|
String prevValue = previousValues.get(name);
|
||||||
|
|
||||||
if (prevValue == null) {
|
if (prevValue == null) {
|
||||||
|
@ -416,6 +395,7 @@ public class ExportImportTest {
|
||||||
System.setProperty(name, prevValue);
|
System.setProperty(name, prevValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue