diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index 5b59c23ee5..c1c53b32f0 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -90,6 +90,7 @@ public class RealmRepresentation { protected String browserFlow; protected String registrationFlow; protected String directGrantFlow; + protected String resetCredentialsFlow; protected String clientAuthenticationFlow; @Deprecated @@ -737,6 +738,14 @@ public class RealmRepresentation { this.directGrantFlow = directGrantFlow; } + public String getResetCredentialsFlow() { + return resetCredentialsFlow; + } + + public void setResetCredentialsFlow(String resetCredentialsFlow) { + this.resetCredentialsFlow = resetCredentialsFlow; + } + public String getClientAuthenticationFlow() { return clientAuthenticationFlow; } diff --git a/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_5_0.java b/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_5_0.java index 95a5224880..cbe0eb7e40 100755 --- a/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_5_0.java +++ b/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_5_0.java @@ -31,13 +31,19 @@ public class MigrateTo1_5_0 { realm.setBrowserFlow(realm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW)); realm.setRegistrationFlow(realm.getFlowByAlias(DefaultAuthenticationFlows.REGISTRATION_FLOW)); realm.setDirectGrantFlow(realm.getFlowByAlias(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW)); - realm.setResetCredentialsFlow(realm.getFlowByAlias(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW)); + + AuthenticationFlowModel resetFlow = realm.getFlowByAlias(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW); + if (resetFlow == null) { + DefaultAuthenticationFlows.resetCredentialsFlow(realm); + } else { + realm.setResetCredentialsFlow(resetFlow); + } AuthenticationFlowModel clientAuthFlow = realm.getFlowByAlias(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW); if (clientAuthFlow == null) { DefaultAuthenticationFlows.clientAuthFlow(realm); } else { - realm.setClientAuthenticationFlow(realm.getFlowByAlias(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW)); + realm.setClientAuthenticationFlow(clientAuthFlow); } for (ClientModel client : realm.getClients()) { diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index f2d4f1ebe1..bf2360e6a2 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -163,6 +163,7 @@ public class ModelToRepresentation { if (realm.getBrowserFlow() != null) rep.setBrowserFlow(realm.getBrowserFlow().getAlias()); if (realm.getRegistrationFlow() != null) rep.setRegistrationFlow(realm.getRegistrationFlow().getAlias()); if (realm.getDirectGrantFlow() != null) rep.setDirectGrantFlow(realm.getDirectGrantFlow().getAlias()); + if (realm.getResetCredentialsFlow() != null) rep.setResetCredentialsFlow(realm.getResetCredentialsFlow().getAlias()); if (realm.getClientAuthenticationFlow() != null) rep.setClientAuthenticationFlow(realm.getClientAuthenticationFlow().getAlias()); List defaultRoles = realm.getDefaultRoles(); diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 4faff0194e..811655b4b6 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -359,8 +359,25 @@ public class RepresentationToModel { } else { newRealm.setDirectGrantFlow(newRealm.getFlowByAlias(rep.getDirectGrantFlow())); } + + // reset credentials + client flow needs to be more defensive as they were added later (in 1.5 ) + if (rep.getResetCredentialsFlow() == null) { + AuthenticationFlowModel resetFlow = newRealm.getFlowByAlias(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW); + if (resetFlow == null) { + DefaultAuthenticationFlows.resetCredentialsFlow(newRealm); + } else { + newRealm.setResetCredentialsFlow(resetFlow); + } + } else { + newRealm.setResetCredentialsFlow(newRealm.getFlowByAlias(rep.getResetCredentialsFlow())); + } if (rep.getClientAuthenticationFlow() == null) { - newRealm.setClientAuthenticationFlow(newRealm.getFlowByAlias(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW)); + AuthenticationFlowModel clientFlow = newRealm.getFlowByAlias(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW); + if (clientFlow == null) { + DefaultAuthenticationFlows.clientAuthFlow(newRealm); + } else { + newRealm.setClientAuthenticationFlow(clientFlow); + } } else { newRealm.setClientAuthenticationFlow(newRealm.getFlowByAlias(rep.getClientAuthenticationFlow())); } @@ -571,6 +588,9 @@ public class RepresentationToModel { if (rep.getDirectGrantFlow() != null) { realm.setDirectGrantFlow(realm.getFlowByAlias(rep.getDirectGrantFlow())); } + if (rep.getResetCredentialsFlow() != null) { + realm.setResetCredentialsFlow(realm.getFlowByAlias(rep.getResetCredentialsFlow())); + } if (rep.getClientAuthenticationFlow() != null) { realm.setClientAuthenticationFlow(realm.getFlowByAlias(rep.getClientAuthenticationFlow())); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java index 558ff39a8b..2f33e4397d 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java @@ -7,6 +7,8 @@ import org.junit.runners.MethodSorters; import org.keycloak.constants.KerberosConstants; import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper; import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory; +import org.keycloak.models.AuthenticationExecutionModel; +import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.ClientModel; import org.keycloak.models.Constants; import org.keycloak.models.FederatedIdentityModel; @@ -23,6 +25,7 @@ import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; +import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper; @@ -275,6 +278,17 @@ public class ImportTest extends AbstractModelTest { UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy"); Assert.assertNull(factory.getInstance(session, null).getUserByUsername(realm, "wburke")); + // Test builtin authentication flows + AuthenticationFlowModel clientFlow = realm.getClientAuthenticationFlow(); + Assert.assertEquals(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW, clientFlow.getAlias()); + Assert.assertNotNull(realm.getAuthenticationFlowById(clientFlow.getId())); + Assert.assertTrue(realm.getAuthenticationExecutions(clientFlow.getId()).size() > 0); + + AuthenticationFlowModel resetFlow = realm.getResetCredentialsFlow(); + Assert.assertEquals(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW, resetFlow.getAlias()); + Assert.assertNotNull(realm.getAuthenticationFlowById(resetFlow.getId())); + Assert.assertTrue(realm.getAuthenticationExecutions(resetFlow.getId()).size() > 0); + // Test protocol mappers. Default application has all the builtin protocol mappers. OtherApp just gss credential Assert.assertNotNull(application.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "username")); Assert.assertNotNull(application.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "email"));