diff --git a/core/src/main/java/org/keycloak/representations/idm/AuthenticationExecutionRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/AuthenticationExecutionRepresentation.java
new file mode 100755
index 0000000000..8ca78d4e2c
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/AuthenticationExecutionRepresentation.java
@@ -0,0 +1,87 @@
+package org.keycloak.representations.idm;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+* @author Bill Burke
+* @version $Revision: 1 $
+*/
+public class AuthenticationExecutionRepresentation implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String authenticatorConfig;
+ private String authenticator;
+ private String flowId;
+ private boolean autheticatorFlow;
+ private String requirement;
+ private boolean userSetupAllowed;
+ private int priority;
+
+ public String getAuthenticatorConfig() {
+ return authenticatorConfig;
+ }
+
+ public void setAuthenticatorConfig(String authenticatorConfig) {
+ this.authenticatorConfig = authenticatorConfig;
+ }
+
+ public String getAuthenticator() {
+ return authenticator;
+ }
+
+ public void setAuthenticator(String authenticator) {
+ this.authenticator = authenticator;
+ }
+
+ public String getRequirement() {
+ return requirement;
+ }
+
+ public void setRequirement(String requirement) {
+ this.requirement = requirement;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ public boolean isUserSetupAllowed() {
+ return userSetupAllowed;
+ }
+
+ public void setUserSetupAllowed(boolean userSetupAllowed) {
+ this.userSetupAllowed = userSetupAllowed;
+ }
+
+ /**
+ * If this execution is a flow, this is the flowId pointing to an AuthenticationFlowModel
+ *
+ * @return
+ */
+ public String getFlowId() {
+ return flowId;
+ }
+
+ public void setFlowId(String flowId) {
+ this.flowId = flowId;
+ }
+
+ /**
+ * Is the referenced authenticator a flow?
+ *
+ * @return
+ */
+ public boolean isAutheticatorFlow() {
+ return autheticatorFlow;
+ }
+
+ public void setAutheticatorFlow(boolean autheticatorFlow) {
+ this.autheticatorFlow = autheticatorFlow;
+ }
+
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/AuthenticationFlowRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/AuthenticationFlowRepresentation.java
new file mode 100755
index 0000000000..a6ad705fae
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/AuthenticationFlowRepresentation.java
@@ -0,0 +1,76 @@
+package org.keycloak.representations.idm;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class AuthenticationFlowRepresentation implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String id;
+ private String alias;
+ private String description;
+ private String providerId;
+ private boolean topLevel;
+ private boolean builtIn;
+ protected List authenticationExecutions;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public void setAlias(String alias) {
+ this.alias = alias;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getProviderId() {
+ return providerId;
+ }
+
+ public void setProviderId(String providerId) {
+ this.providerId = providerId;
+ }
+
+ public boolean isTopLevel() {
+ return topLevel;
+ }
+
+ public void setTopLevel(boolean topLevel) {
+ this.topLevel = topLevel;
+ }
+
+ public boolean isBuiltIn() {
+ return builtIn;
+ }
+
+ public void setBuiltIn(boolean builtIn) {
+ this.builtIn = builtIn;
+ }
+
+ public List getAuthenticationExecutions() {
+ return authenticationExecutions;
+ }
+
+ public void setAuthenticationExecutions(List authenticationExecutions) {
+ this.authenticationExecutions = authenticationExecutions;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/AuthenticatorConfigRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/AuthenticatorConfigRepresentation.java
new file mode 100755
index 0000000000..e3f48e09f7
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/AuthenticatorConfigRepresentation.java
@@ -0,0 +1,44 @@
+package org.keycloak.representations.idm;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* @author Bill Burke
+* @version $Revision: 1 $
+*/
+public class AuthenticatorConfigRepresentation implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String id;
+ private String alias;
+ private Map config = new HashMap();
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public void setAlias(String alias) {
+ this.alias = alias;
+ }
+
+
+
+ public Map getConfig() {
+ return config;
+ }
+
+ public void setConfig(Map config) {
+ this.config = config;
+ }
+}
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 dabc8dbf6d..25ff0a34c4 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -76,6 +76,8 @@ public class RealmRepresentation {
protected Boolean internationalizationEnabled;
protected Set supportedLocales;
protected String defaultLocale;
+ protected List authenticationFlows;
+ protected List authenticatorConfig;
@Deprecated
protected Boolean social;
@@ -626,5 +628,19 @@ public class RealmRepresentation {
identityProviderMappers.add(rep);
}
+ public List getAuthenticationFlows() {
+ return authenticationFlows;
+ }
+ public void setAuthenticationFlows(List authenticationFlows) {
+ this.authenticationFlows = authenticationFlows;
+ }
+
+ public List getAuthenticatorConfig() {
+ return authenticatorConfig;
+ }
+
+ public void setAuthenticatorConfig(List authenticatorConfig) {
+ this.authenticatorConfig = authenticatorConfig;
+ }
}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java b/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java
index dee5d4f3d8..d3f5622078 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java
@@ -20,9 +20,8 @@ public class DefaultAuthenticationFlows {
public static final String LOGIN_FORMS_FLOW = "forms";
public static void addFlows(RealmModel realm) {
- browserFlow(realm);
- registrationFlow(realm);
-
+ if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm);
+ if (realm.getFlowByAlias(REGISTRATION_FLOW) == null) registrationFlow(realm);
}
public static void registrationFlow(RealmModel realm) {
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 27a05396ff..19c4e81594 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
@@ -1,5 +1,8 @@
package org.keycloak.models.utils;
+import org.keycloak.models.AuthenticationExecutionModel;
+import org.keycloak.models.AuthenticationFlowModel;
+import org.keycloak.models.AuthenticatorConfigModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel;
@@ -17,6 +20,9 @@ import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
+import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
@@ -183,10 +189,30 @@ public class ModelToRepresentation {
rep.setInternationalizationEnabled(realm.isInternationalizationEnabled());
rep.getSupportedLocales().addAll(realm.getSupportedLocales());
rep.setDefaultLocale(realm.getDefaultLocale());
-
+ if (internal) {
+ exportAuthenticationFlows(realm, rep);
+ }
return rep;
}
+ public static void exportAuthenticationFlows(RealmModel realm, RealmRepresentation rep) {
+ rep.setAuthenticationFlows(new LinkedList());
+ rep.setAuthenticatorConfig(new LinkedList());
+ for (AuthenticationFlowModel model : realm.getAuthenticationFlows()) {
+ AuthenticationFlowRepresentation flowRep = toRepresentation(model);
+ flowRep.setAuthenticationExecutions(new LinkedList());
+ for (AuthenticationExecutionModel execution : realm.getAuthenticationExecutions(model.getId())) {
+ flowRep.getAuthenticationExecutions().add(toRepresentation(execution));
+ }
+ rep.getAuthenticationFlows().add(flowRep);
+ }
+ for (AuthenticatorConfigModel model : realm.getAuthenticatorConfigs()) {
+ rep.getAuthenticatorConfig().add(toRepresentation(model));
+ }
+
+ }
+
+
public static RealmEventsConfigRepresentation toEventsConfigReprensetation(RealmModel realm) {
RealmEventsConfigRepresentation rep = new RealmEventsConfigRepresentation();
rep.setEventsEnabled(realm.isEventsEnabled());
@@ -404,4 +430,37 @@ public class ModelToRepresentation {
return consentRep;
}
+ public static AuthenticationFlowRepresentation toRepresentation(AuthenticationFlowModel model) {
+ AuthenticationFlowRepresentation rep = new AuthenticationFlowRepresentation();
+ rep.setBuiltIn(model.isBuiltIn());
+ rep.setTopLevel(model.isTopLevel());
+ rep.setProviderId(model.getProviderId());
+ rep.setId(model.getId());
+ rep.setAlias(model.getAlias());
+ rep.setDescription(model.getDescription());
+ return rep;
+
+ }
+
+ public static AuthenticationExecutionRepresentation toRepresentation(AuthenticationExecutionModel model) {
+ AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation();
+ rep.setAuthenticatorConfig(model.getAuthenticatorConfig());
+ rep.setAuthenticator(model.getAuthenticator());
+ rep.setAutheticatorFlow(model.isAutheticatorFlow());
+ rep.setFlowId(model.getFlowId());
+ rep.setPriority(model.getPriority());
+ rep.setUserSetupAllowed(model.isUserSetupAllowed());
+ rep.setRequirement(model.getRequirement().name());
+ return rep;
+ }
+
+ public static AuthenticatorConfigRepresentation toRepresentation(AuthenticatorConfigModel model) {
+ AuthenticatorConfigRepresentation rep = new AuthenticatorConfigRepresentation();
+ rep.setId(model.getId());
+ rep.setAlias(model.getAlias());
+ rep.setConfig(model.getConfig());
+ return rep;
+ }
+
+
}
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 2b7195ad6f..e0a328e87f 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
@@ -4,6 +4,9 @@ import net.iharder.Base64;
import org.jboss.logging.Logger;
import org.keycloak.enums.SslRequired;
import org.keycloak.migration.MigrationProvider;
+import org.keycloak.models.AuthenticationExecutionModel;
+import org.keycloak.models.AuthenticationFlowModel;
+import org.keycloak.models.AuthenticatorConfigModel;
import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClientModel;
@@ -23,6 +26,9 @@ import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
@@ -288,6 +294,30 @@ public class RepresentationToModel {
if(rep.getDefaultLocale() != null){
newRealm.setDefaultLocale(rep.getDefaultLocale());
}
+
+ importAuthenticationFlows(newRealm, rep);
+ }
+
+ public static void importAuthenticationFlows(RealmModel newRealm, RealmRepresentation rep) {
+ if (rep.getAuthenticationFlows() == null) {
+ // assume this is an old version being imported
+ DefaultAuthenticationFlows.addFlows(newRealm);
+ } else {
+ for (AuthenticationFlowRepresentation flowRep : rep.getAuthenticationFlows()) {
+ AuthenticationFlowModel model = toModel(flowRep);
+ model = newRealm.addAuthenticationFlow(model);
+ for (AuthenticationExecutionRepresentation exeRep : flowRep.getAuthenticationExecutions()) {
+ AuthenticationExecutionModel execution = toModel(exeRep);
+ execution.setParentFlow(model.getId());
+ newRealm.addAuthenticatorExecution(execution);
+ }
+ }
+ for (AuthenticatorConfigRepresentation configRep : rep.getAuthenticatorConfig()) {
+ AuthenticatorConfigModel model = toModel(configRep);
+ newRealm.addAuthenticatorConfig(model);
+ }
+ }
+
}
private static void convertDeprecatedSocialProviders(RealmRepresentation rep) {
@@ -921,7 +951,7 @@ public class RepresentationToModel {
}
}
}
- public static IdentityProviderModel toModel(IdentityProviderRepresentation representation) {
+ public static IdentityProviderModel toModel(IdentityProviderRepresentation representation) {
IdentityProviderModel identityProviderModel = new IdentityProviderModel();
identityProviderModel.setInternalId(representation.getInternalId());
@@ -1009,4 +1039,37 @@ public class RepresentationToModel {
return consentModel;
}
+ public static AuthenticationFlowModel toModel(AuthenticationFlowRepresentation rep) {
+ AuthenticationFlowModel model = new AuthenticationFlowModel();
+ model.setBuiltIn(rep.isBuiltIn());
+ model.setTopLevel(rep.isTopLevel());
+ model.setProviderId(rep.getProviderId());
+ model.setId(rep.getId());
+ model.setAlias(rep.getAlias());
+ model.setDescription(rep.getDescription());
+ return model;
+
+ }
+
+ public static AuthenticationExecutionModel toModel(AuthenticationExecutionRepresentation rep) {
+ AuthenticationExecutionModel model = new AuthenticationExecutionModel();
+ model.setAuthenticatorConfig(rep.getAuthenticatorConfig());
+ model.setAuthenticator(rep.getAuthenticator());
+ model.setAutheticatorFlow(rep.isAutheticatorFlow());
+ model.setFlowId(rep.getFlowId());
+ model.setPriority(rep.getPriority());
+ model.setUserSetupAllowed(rep.isUserSetupAllowed());
+ model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement()));
+ return model;
+ }
+
+ public static AuthenticatorConfigModel toModel(AuthenticatorConfigRepresentation rep) {
+ AuthenticatorConfigModel model = new AuthenticatorConfigModel();
+ model.setId(rep.getId());
+ model.setAlias(rep.getAlias());
+ model.setConfig(rep.getConfig());
+ return model;
+ }
+
+
}
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
index 04358734f3..086541e7e7 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
@@ -1278,7 +1278,8 @@ public class RealmAdapter implements RealmModel {
@Override
public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) {
AuthenticationFlowEntity entity = new AuthenticationFlowEntity();
- entity.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ entity.setId(id);
entity.setAlias(model.getAlias());
entity.setDescription(model.getDescription());
entity.setProviderId(model.getProviderId());
@@ -1339,7 +1340,8 @@ public class RealmAdapter implements RealmModel {
@Override
public AuthenticationExecutionModel addAuthenticatorExecution(AuthenticationExecutionModel model) {
AuthenticationExecutionEntity entity = new AuthenticationExecutionEntity();
- entity.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ entity.setId(id);
entity.setAuthenticator(model.getAuthenticator());
entity.setPriority(model.getPriority());
entity.setRequirement(model.getRequirement());
@@ -1399,7 +1401,8 @@ public class RealmAdapter implements RealmModel {
@Override
public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) {
AuthenticatorConfigEntity auth = new AuthenticatorConfigEntity();
- auth.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ auth.setId(id);
auth.setAlias(model.getAlias());
auth.setConfig(model.getConfig());
realm.getAuthenticatorConfigs().add(auth);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 1891f4cb0d..eb83947884 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -1579,7 +1579,8 @@ public class RealmAdapter implements RealmModel {
@Override
public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) {
AuthenticationFlowEntity entity = new AuthenticationFlowEntity();
- entity.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ entity.setId(id);
entity.setAlias(model.getAlias());
entity.setDescription(model.getDescription());
entity.setProviderId(model.getProviderId());
@@ -1633,7 +1634,8 @@ public class RealmAdapter implements RealmModel {
@Override
public AuthenticationExecutionModel addAuthenticatorExecution(AuthenticationExecutionModel model) {
AuthenticationExecutionEntity entity = new AuthenticationExecutionEntity();
- entity.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ entity.setId(id);
entity.setAuthenticator(model.getAuthenticator());
entity.setPriority(model.getPriority());
entity.setFlowId(model.getFlowId());
@@ -1678,7 +1680,8 @@ public class RealmAdapter implements RealmModel {
@Override
public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) {
AuthenticatorConfigEntity auth = new AuthenticatorConfigEntity();
- auth.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ auth.setId(id);
auth.setAlias(model.getAlias());
auth.setRealm(realm);
auth.setConfig(model.getConfig());
@@ -1742,7 +1745,8 @@ public class RealmAdapter implements RealmModel {
@Override
public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) {
RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
- auth.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ auth.setId(id);
auth.setAlias(model.getAlias());
auth.setName(model.getName());
auth.setRealm(realm);
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index a56d5f2be2..a3ebacedc1 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -1352,7 +1352,8 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
@Override
public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) {
AuthenticationFlowEntity entity = new AuthenticationFlowEntity();
- entity.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ entity.setId(id);
entity.setAlias(model.getAlias());
entity.setDescription(model.getDescription());
entity.setProviderId(model.getProviderId());
@@ -1414,7 +1415,8 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
@Override
public AuthenticationExecutionModel addAuthenticatorExecution(AuthenticationExecutionModel model) {
AuthenticationExecutionEntity entity = new AuthenticationExecutionEntity();
- entity.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ entity.setId(id);
entity.setAuthenticator(model.getAuthenticator());
entity.setPriority(model.getPriority());
entity.setRequirement(model.getRequirement());
@@ -1478,7 +1480,8 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
@Override
public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) {
AuthenticatorConfigEntity auth = new AuthenticatorConfigEntity();
- auth.setId(KeycloakModelUtils.generateId());
+ String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
+ auth.setId(id);
auth.setAlias(model.getAlias());
auth.setConfig(model.getConfig());
realm.getAuthenticatorConfigs().add(auth);