Fix NPEs during realm import (#10962)

Closes #10961
This commit is contained in:
Andrea Peruffo 2022-03-29 20:48:37 +01:00 committed by GitHub
parent 2b996b12a1
commit da5db5a813
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 24 deletions

View file

@ -729,44 +729,57 @@ public class RepresentationToModel {
// assume this is an old version being imported // assume this is an old version being imported
DefaultAuthenticationFlows.migrateFlows(newRealm); DefaultAuthenticationFlows.migrateFlows(newRealm);
} else { } else {
for (AuthenticatorConfigRepresentation configRep : rep.getAuthenticatorConfig()) { if (rep.getAuthenticatorConfig() != null) {
if (configRep.getAlias() == null) { for (AuthenticatorConfigRepresentation configRep : rep.getAuthenticatorConfig()) {
// this can happen only during import json files from keycloak 3.4.0 and older if (configRep.getAlias() == null) {
throw new IllegalStateException("Provided realm contains authenticator config with null alias. " // this can happen only during import json files from keycloak 3.4.0 and older
+ "It should be resolved by adding alias to the authenticator config before exporting the realm."); throw new IllegalStateException("Provided realm contains authenticator config with null alias. "
+ "It should be resolved by adding alias to the authenticator config before exporting the realm.");
}
AuthenticatorConfigModel model = toModel(configRep);
newRealm.addAuthenticatorConfig(model);
} }
AuthenticatorConfigModel model = toModel(configRep);
newRealm.addAuthenticatorConfig(model);
} }
for (AuthenticationFlowRepresentation flowRep : rep.getAuthenticationFlows()) { if (rep.getAuthenticationFlows() != null) {
AuthenticationFlowModel model = toModel(flowRep); for (AuthenticationFlowRepresentation flowRep : rep.getAuthenticationFlows()) {
// make sure new id is generated for new AuthenticationFlowModel instance AuthenticationFlowModel model = toModel(flowRep);
String previousId = model.getId(); // make sure new id is generated for new AuthenticationFlowModel instance
model.setId(null); String previousId = model.getId();
model = newRealm.addAuthenticationFlow(model); model.setId(null);
// store the mapped ids so that clients can reference the correct flow when importing the authenticationFlowBindingOverrides model = newRealm.addAuthenticationFlow(model);
mappedFlows.put(previousId, model.getId()); // store the mapped ids so that clients can reference the correct flow when importing the authenticationFlowBindingOverrides
} mappedFlows.put(previousId, model.getId());
for (AuthenticationFlowRepresentation flowRep : rep.getAuthenticationFlows()) { }
AuthenticationFlowModel model = newRealm.getFlowByAlias(flowRep.getAlias()); for (AuthenticationFlowRepresentation flowRep : rep.getAuthenticationFlows()) {
for (AuthenticationExecutionExportRepresentation exeRep : flowRep.getAuthenticationExecutions()) { AuthenticationFlowModel model = newRealm.getFlowByAlias(flowRep.getAlias());
AuthenticationExecutionModel execution = toModel(newRealm, model, exeRep); for (AuthenticationExecutionExportRepresentation exeRep : flowRep.getAuthenticationExecutions()) {
newRealm.addAuthenticatorExecution(execution); AuthenticationExecutionModel execution = toModel(newRealm, model, exeRep);
newRealm.addAuthenticatorExecution(execution);
}
} }
} }
} }
if (rep.getBrowserFlow() == null) { if (rep.getBrowserFlow() == null) {
newRealm.setBrowserFlow(newRealm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW)); AuthenticationFlowModel defaultFlow = newRealm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
if (defaultFlow != null) {
newRealm.setBrowserFlow(defaultFlow);
}
} else { } else {
newRealm.setBrowserFlow(newRealm.getFlowByAlias(rep.getBrowserFlow())); newRealm.setBrowserFlow(newRealm.getFlowByAlias(rep.getBrowserFlow()));
} }
if (rep.getRegistrationFlow() == null) { if (rep.getRegistrationFlow() == null) {
newRealm.setRegistrationFlow(newRealm.getFlowByAlias(DefaultAuthenticationFlows.REGISTRATION_FLOW)); AuthenticationFlowModel defaultFlow = newRealm.getFlowByAlias(DefaultAuthenticationFlows.REGISTRATION_FLOW);
if (defaultFlow != null) {
newRealm.setRegistrationFlow(defaultFlow);
}
} else { } else {
newRealm.setRegistrationFlow(newRealm.getFlowByAlias(rep.getRegistrationFlow())); newRealm.setRegistrationFlow(newRealm.getFlowByAlias(rep.getRegistrationFlow()));
} }
if (rep.getDirectGrantFlow() == null) { if (rep.getDirectGrantFlow() == null) {
newRealm.setDirectGrantFlow(newRealm.getFlowByAlias(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW)); AuthenticationFlowModel defaultFlow = newRealm.getFlowByAlias(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW);
if (defaultFlow != null) {
newRealm.setDirectGrantFlow(defaultFlow);
}
} else { } else {
newRealm.setDirectGrantFlow(newRealm.getFlowByAlias(rep.getDirectGrantFlow())); newRealm.setDirectGrantFlow(newRealm.getFlowByAlias(rep.getDirectGrantFlow()));
} }

View file

@ -238,6 +238,12 @@ public class ExportImportTest extends AbstractKeycloakTest {
addTestRealmToTestRealmReps("import-without-clients"); addTestRealmToTestRealmReps("import-without-clients");
} }
@Test
public void testImportWithNullAuthenticatorConfigAndNoDefaultBrowserFlow() {
importRealmFromFile("/import/testrealm-authenticator-config-null.json");
Assert.assertTrue("Imported realm hasn't been found!", isRealmPresent("cez"));
}
@Test @Test
public void testImportIgnoreExistingMissingClientId() { public void testImportIgnoreExistingMissingClientId() {
TestingExportImportResource resource = testingClient.testing().exportImport(); TestingExportImportResource resource = testingClient.testing().exportImport();

View file

@ -0,0 +1,25 @@
{
"authenticationFlows": [
{
"alias": "browser",
"authenticationExecutions": [
{
"authenticator": "auth-spnego",
"authenticatorFlow": false,
"priority": 20,
"requirement": "ALTERNATIVE",
"userSetupAllowed": false
}
],
"builtIn": true,
"description": "browser based authentification2",
"id": "3e6ccf87-5473-4eb0-8cbb-28f6b9e6f4d6",
"providerId": "basic-flow",
"topLevel": true
}
],
"displayName": "CEZ",
"enabled": true,
"id": "cez",
"realm": "cez"
}