diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml index 34fc32a927..1ca78d5513 100755 --- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml +++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml @@ -17,6 +17,12 @@ + + + + + + diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js index 7bf810c7c0..7568e04cef 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js @@ -1041,6 +1041,9 @@ module.config([ '$routeProvider', function($routeProvider) { resolve : { realm : function(RealmLoader) { return RealmLoader(); + }, + flows : function(AuthenticationFlowsLoader) { + return AuthenticationFlowsLoader(); } }, controller : 'AuthenticationFlowsCtrl' diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js index 8d4fbc79d4..93e7cc3b8e 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js @@ -1566,10 +1566,14 @@ module.controller('IdentityProviderMapperCreateCtrl', function($scope, realm, id }); -module.controller('AuthenticationFlowsCtrl', function($scope, realm, AuthenticationExecutions, Notifications, Dialog, $location) { +module.controller('AuthenticationFlowsCtrl', function($scope, realm, flows, AuthenticationExecutions, Notifications, Dialog, $location) { $scope.realm = realm; + $scope.flows = flows; + if (flows.length > 0) { + $scope.flow = flows[0]; + } var setupForm = function() { - AuthenticationExecutions.query({realm: realm.realm, alias: 'browser'}, function(data) { + AuthenticationExecutions.query({realm: realm.realm, alias: $scope.flow.alias}, function(data) { $scope.executions = data; $scope.flowmax = 0; for (var i = 0; i < $scope.executions.length; i++ ) { @@ -1591,13 +1595,13 @@ module.controller('AuthenticationFlowsCtrl', function($scope, realm, Authenticat $scope.updateExecution = function(execution) { var copy = angular.copy(execution); delete copy.empties; - AuthenticationExecutions.update({realm: realm.realm, alias: 'browser'}, copy, function() { + AuthenticationExecutions.update({realm: realm.realm, alias: $scope.flow.alias}, copy, function() { Notifications.success("Auth requirement updated"); setupForm(); }); }; - + $scope.setupForm = setupForm; setupForm(); diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js index 5ebc0a53f6..da41b3c05a 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js @@ -340,3 +340,13 @@ module.factory('IdentityProviderMapperLoader', function(Loader, IdentityProvider }); }); +module.factory('AuthenticationFlowsLoader', function(Loader, AuthenticationFlows, $route, $q) { + return Loader.query(AuthenticationFlows, function() { + return { + realm : $route.current.params.realm + } + }); +}); + + + diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js index 8b641c1b3c..6f25efb012 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js @@ -1079,7 +1079,7 @@ module.factory('IdentityProviderMapper', function($resource) { }); module.factory('AuthenticationExecutions', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/authentication/flow/:alias/executions', { + return $resource(authUrl + '/admin/realms/:realm/authentication/flows/:alias/executions', { realm : '@realm', alias : '@alias' }, { @@ -1089,4 +1089,10 @@ module.factory('AuthenticationExecutions', function($resource) { }); }); +module.factory('AuthenticationFlows', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/authentication/flows', { + realm : '@realm' + }); +}); + diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/authentication-flows.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/authentication-flows.html index cfc4f89fe3..5084ab93fe 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/authentication-flows.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/authentication-flows.html @@ -5,22 +5,16 @@ - diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-authentication.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-authentication.html index d5c54bde04..c9e2cbb770 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-authentication.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-authentication.html @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/model/api/src/main/java/org/keycloak/models/AuthenticationFlowModel.java b/model/api/src/main/java/org/keycloak/models/AuthenticationFlowModel.java index db5970ada2..4f83d63809 100755 --- a/model/api/src/main/java/org/keycloak/models/AuthenticationFlowModel.java +++ b/model/api/src/main/java/org/keycloak/models/AuthenticationFlowModel.java @@ -13,6 +13,8 @@ public class AuthenticationFlowModel implements Serializable { private String alias; private String description; private String providerId; + private boolean topLevel; + private boolean builtIn; public String getId() { return id; @@ -45,4 +47,20 @@ public class AuthenticationFlowModel implements Serializable { 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; + } } diff --git a/model/api/src/main/java/org/keycloak/models/entities/AuthenticationFlowEntity.java b/model/api/src/main/java/org/keycloak/models/entities/AuthenticationFlowEntity.java index 0db9560ea1..06d312aee0 100755 --- a/model/api/src/main/java/org/keycloak/models/entities/AuthenticationFlowEntity.java +++ b/model/api/src/main/java/org/keycloak/models/entities/AuthenticationFlowEntity.java @@ -13,6 +13,8 @@ public class AuthenticationFlowEntity { protected String alias; protected String description; protected String providerId; + private boolean topLevel; + private boolean builtIn; List executions = new ArrayList(); public String getId() { @@ -54,4 +56,20 @@ public class AuthenticationFlowEntity { 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; + } } 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 dc7a44ae85..dee5d4f3d8 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 @@ -30,12 +30,16 @@ public class DefaultAuthenticationFlows { registrationFlow.setAlias(REGISTRATION_FLOW); registrationFlow.setDescription("registration flow"); registrationFlow.setProviderId("basic-flow"); + registrationFlow.setTopLevel(true); + registrationFlow.setBuiltIn(true); registrationFlow = realm.addAuthenticationFlow(registrationFlow); AuthenticationFlowModel registrationFormFlow = new AuthenticationFlowModel(); registrationFormFlow.setAlias(REGISTRATION_FORM_FLOW); registrationFormFlow.setDescription("registration form"); registrationFormFlow.setProviderId("form-flow"); + registrationFormFlow.setTopLevel(false); + registrationFormFlow.setBuiltIn(true); registrationFormFlow = realm.addAuthenticationFlow(registrationFormFlow); AuthenticationExecutionModel execution; @@ -103,6 +107,8 @@ public class DefaultAuthenticationFlows { browser.setAlias(BROWSER_FLOW); browser.setDescription("browser based authentication"); browser.setProviderId("basic-flow"); + browser.setTopLevel(true); + browser.setBuiltIn(true); browser = realm.addAuthenticationFlow(browser); AuthenticationExecutionModel execution = new AuthenticationExecutionModel(); execution.setParentFlow(browser.getId()); @@ -123,6 +129,8 @@ public class DefaultAuthenticationFlows { AuthenticationFlowModel forms = new AuthenticationFlowModel(); + forms.setTopLevel(false); + forms.setBuiltIn(true); forms.setAlias(LOGIN_FORMS_FLOW); forms.setDescription("Username, password, otp and other auth forms."); forms.setProviderId("basic-flow"); 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 45f3c095f0..04358734f3 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 @@ -1234,6 +1234,8 @@ public class RealmAdapter implements RealmModel { model.setAlias(entity.getAlias()); model.setDescription(entity.getDescription()); model.setProviderId(entity.getProviderId()); + model.setBuiltIn(entity.isBuiltIn()); + model.setTopLevel(entity.isTopLevel()); return model; } @@ -1268,6 +1270,8 @@ public class RealmAdapter implements RealmModel { toUpdate.setAlias(model.getAlias()); toUpdate.setDescription(model.getDescription()); toUpdate.setProviderId(model.getProviderId()); + toUpdate.setBuiltIn(model.isBuiltIn()); + toUpdate.setTopLevel(model.isTopLevel()); } @@ -1278,6 +1282,8 @@ public class RealmAdapter implements RealmModel { entity.setAlias(model.getAlias()); entity.setDescription(model.getDescription()); entity.setProviderId(model.getProviderId()); + entity.setBuiltIn(model.isBuiltIn()); + entity.setTopLevel(model.isTopLevel()); realm.getAuthenticationFlows().add(entity); model.setId(entity.getId()); return model; 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 5ccf6c1f0f..1891f4cb0d 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 @@ -1544,6 +1544,8 @@ public class RealmAdapter implements RealmModel { model.setAlias(entity.getAlias()); model.setProviderId(entity.getProviderId()); model.setDescription(entity.getDescription()); + model.setBuiltIn(entity.isBuiltIn()); + model.setTopLevel(entity.isTopLevel()); return model; } @@ -1569,6 +1571,8 @@ public class RealmAdapter implements RealmModel { entity.setAlias(model.getAlias()); entity.setDescription(model.getDescription()); entity.setProviderId(model.getProviderId()); + entity.setBuiltIn(model.isBuiltIn()); + entity.setTopLevel(model.isTopLevel()); } @@ -1579,6 +1583,8 @@ public class RealmAdapter implements RealmModel { entity.setAlias(model.getAlias()); entity.setDescription(model.getDescription()); entity.setProviderId(model.getProviderId()); + entity.setBuiltIn(model.isBuiltIn()); + entity.setTopLevel(model.isTopLevel()); entity.setRealm(realm); realm.getAuthenticationFlows().add(entity); em.persist(entity); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java index 2db9722973..622ef196b3 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java @@ -42,6 +42,13 @@ public class AuthenticationFlowEntity { @Column(name="DESCRIPTION") protected String description; + @Column(name="TOP_LEVEL") + protected boolean topLevel; + + @Column(name="BUILT_IN") + protected boolean builtIn; + + @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "parentFlow") Collection executions = new ArrayList(); public String getId() { @@ -91,4 +98,20 @@ public class AuthenticationFlowEntity { 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; + } } 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 cb5cab9c68..a56d5f2be2 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 @@ -1308,6 +1308,8 @@ public class RealmAdapter extends AbstractMongoAdapter impleme model.setId(entity.getId()); model.setAlias(entity.getAlias()); model.setDescription(entity.getDescription()); + model.setBuiltIn(entity.isBuiltIn()); + model.setTopLevel(entity.isTopLevel()); return model; } @@ -1342,6 +1344,8 @@ public class RealmAdapter extends AbstractMongoAdapter impleme toUpdate.setAlias(model.getAlias()); toUpdate.setDescription(model.getDescription()); toUpdate.setProviderId(model.getProviderId()); + toUpdate.setBuiltIn(model.isBuiltIn()); + toUpdate.setTopLevel(model.isTopLevel()); updateMongoEntity(); } @@ -1352,6 +1356,8 @@ public class RealmAdapter extends AbstractMongoAdapter impleme entity.setAlias(model.getAlias()); entity.setDescription(model.getDescription()); entity.setProviderId(model.getProviderId()); + entity.setBuiltIn(model.isBuiltIn()); + entity.setTopLevel(model.isTopLevel()); getMongoEntity().getAuthenticationFlows().add(entity); model.setId(entity.getId()); updateMongoEntity(); diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationFlow.java b/services/src/main/java/org/keycloak/authentication/AuthenticationFlow.java index d77772e719..0d208c7c47 100755 --- a/services/src/main/java/org/keycloak/authentication/AuthenticationFlow.java +++ b/services/src/main/java/org/keycloak/authentication/AuthenticationFlow.java @@ -7,6 +7,9 @@ import javax.ws.rs.core.Response; * @version $Revision: 1 $ */ public interface AuthenticationFlow { + String BASIC_FLOW = "basic-flow"; + String FORM_FLOW = "form-flow"; + Response processAction(String actionExecution); Response processFlow(); } diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java index 847423957e..a81b74c4c4 100755 --- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java +++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java @@ -7,7 +7,6 @@ import org.keycloak.authentication.authenticators.AbstractFormAuthenticator; import org.keycloak.events.Details; import org.keycloak.events.Errors; import org.keycloak.events.EventBuilder; -import org.keycloak.events.EventType; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticatorConfigModel; @@ -466,11 +465,11 @@ public class AuthenticationProcessor { logger.error("Unknown flow to execute with"); throw new AuthException(Error.INTERNAL_ERROR); } - if (flow.getProviderId() == null || flow.getProviderId().equals("basic-flow")) { + if (flow.getProviderId() == null || flow.getProviderId().equals(AuthenticationFlow.BASIC_FLOW)) { DefaultAuthenticationFlow flowExecution = new DefaultAuthenticationFlow(this, flow); return flowExecution; - } else if (flow.getProviderId().equals("form-flow")) { + } else if (flow.getProviderId().equals(AuthenticationFlow.FORM_FLOW)) { FormAuthenticationFlow flowExecution = new FormAuthenticationFlow(this, execution); return flowExecution; } diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java b/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java index cd23b1ef63..47558102f8 100755 --- a/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java @@ -73,7 +73,7 @@ public class SpnegoAuthenticatorFactory implements AuthenticatorFactory { @Override public String getDisplayType() { - return "SPNEGO"; + return "Kerberos"; } @Override diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationPage.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationPage.java index c527ea4687..90657fe6e3 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationPage.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationPage.java @@ -51,9 +51,13 @@ public class RegistrationPage implements FormAuthenticator, FormAuthenticatorFac return false; } + private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = { + AuthenticationExecutionModel.Requirement.REQUIRED, + AuthenticationExecutionModel.Requirement.DISABLED + }; @Override public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { - return new AuthenticationExecutionModel.Requirement[0]; + return REQUIREMENT_CHOICES; } @Override diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java index ffbf214f28..f20b3ebdd2 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java @@ -114,9 +114,13 @@ public class RegistrationPassword implements FormAction, FormActionFactory { return false; } + private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = { + AuthenticationExecutionModel.Requirement.REQUIRED, + AuthenticationExecutionModel.Requirement.DISABLED + }; @Override public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { - return new AuthenticationExecutionModel.Requirement[0]; + return REQUIREMENT_CHOICES; } @Override diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java index af779b9c5c..f67fbeae86 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java @@ -120,11 +120,14 @@ public class RegistrationProfile implements FormAction, FormActionFactory { return false; } + private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = { + AuthenticationExecutionModel.Requirement.REQUIRED, + AuthenticationExecutionModel.Requirement.DISABLED + }; @Override public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { - return new AuthenticationExecutionModel.Requirement[0]; + return REQUIREMENT_CHOICES; } - @Override public FormAction create(KeycloakSession session) { return this; diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationRecaptcha.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationRecaptcha.java index 95e75e9112..3e8d19102a 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationRecaptcha.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationRecaptcha.java @@ -23,6 +23,8 @@ import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.FormMessage; +import org.keycloak.provider.ConfiguredProvider; +import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.services.messages.Messages; import org.keycloak.services.validation.Validation; import org.keycloak.util.JsonSerialization; @@ -38,7 +40,7 @@ import java.util.Map; * @author Bill Burke * @version $Revision: 1 $ */ -public class RegistrationRecaptcha implements FormAction, FormActionFactory { +public class RegistrationRecaptcha implements FormAction, FormActionFactory, ConfiguredProvider { public static final String G_RECAPTCHA_RESPONSE = "g-recaptcha-response"; public static final String RECAPTCHA_REFERENCE_CATEGORY = "recaptcha"; protected static Logger logger = Logger.getLogger(RegistrationRecaptcha.class); @@ -60,11 +62,14 @@ public class RegistrationRecaptcha implements FormAction, FormActionFactory { return true; } + private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = { + AuthenticationExecutionModel.Requirement.REQUIRED, + AuthenticationExecutionModel.Requirement.DISABLED + }; @Override public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { - return new AuthenticationExecutionModel.Requirement[0]; + return REQUIREMENT_CHOICES; } - @Override public void buildPage(FormContext context, LoginFormsProvider form) { AuthenticatorConfigModel captchaConfig = context.getAuthenticatorConfig(); @@ -174,4 +179,14 @@ public class RegistrationRecaptcha implements FormAction, FormActionFactory { public String getId() { return PROVIDER_ID; } + + @Override + public String getHelpText() { + return null; + } + + @Override + public List getConfigProperties() { + return null; + } } diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java index c8716f70d4..28d62392fb 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java @@ -158,11 +158,14 @@ public class RegistrationUserCreation implements FormAction, FormActionFactory { return false; } + private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = { + AuthenticationExecutionModel.Requirement.REQUIRED, + AuthenticationExecutionModel.Requirement.DISABLED + }; @Override public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { - return new AuthenticationExecutionModel.Requirement[0]; + return REQUIREMENT_CHOICES; } - @Override public FormAction create(KeycloakSession session) { return this; diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java index a78baaa657..fa221c386c 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java @@ -3,9 +3,14 @@ package org.keycloak.services.resources.admin; import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; +import org.keycloak.authentication.AuthenticationFlow; import org.keycloak.authentication.Authenticator; import org.keycloak.authentication.AuthenticatorFactory; import org.keycloak.authentication.AuthenticatorUtil; +import org.keycloak.authentication.ConfigurableAuthenticatorFactory; +import org.keycloak.authentication.DefaultAuthenticationFlow; +import org.keycloak.authentication.FormAction; +import org.keycloak.authentication.FormActionFactory; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.KeycloakSession; @@ -104,7 +109,21 @@ public class AuthenticationManagementResource { } } - @Path("/flow/{flowAlias}/executions") + @Path("/flows") + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + public List getFlows() { + List flows = new LinkedList<>(); + for (AuthenticationFlowModel flow : realm.getAuthenticationFlows()) { + if (flow.isTopLevel()) { + flows.add(flow); + } + } + return flows; + } + + @Path("/flows/{flowAlias}/executions") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) @@ -124,11 +143,15 @@ public class AuthenticationManagementResource { rep.setRequirementChoices(new LinkedList()); if (execution.isAutheticatorFlow()) { AuthenticationFlowModel flowRef = realm.getAuthenticationFlowById(execution.getFlowId()); + if (AuthenticationFlow.BASIC_FLOW.equals(flowRef.getProviderId())) { + rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.ALTERNATIVE.name()); + rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.REQUIRED.name()); + rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name()); + } else if (AuthenticationFlow.FORM_FLOW.equals(flowRef.getProviderId())) { + rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.REQUIRED.name()); + rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name()); + } rep.setReferenceType(flowRef.getAlias()); - rep.setExecution(execution.getId()); - rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.ALTERNATIVE.name()); - rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.REQUIRED.name()); - rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name()); rep.setConfigurable(false); rep.setExecution(execution.getId()); rep.setRequirement(execution.getRequirement().name()); @@ -137,9 +160,11 @@ public class AuthenticationManagementResource { if (!flow.getId().equals(execution.getParentFlow())) { rep.setSubFlow(true); } - AuthenticatorFactory factory = (AuthenticatorFactory)session.getKeycloakSessionFactory().getProviderFactory(Authenticator.class, execution.getAuthenticator()); - if (factory.getReferenceCategory() == null) continue; - rep.setReferenceType(factory.getReferenceCategory()); + ConfigurableAuthenticatorFactory factory = (AuthenticatorFactory)session.getKeycloakSessionFactory().getProviderFactory(Authenticator.class, execution.getAuthenticator()); + if (factory == null) { + factory = (FormActionFactory)session.getKeycloakSessionFactory().getProviderFactory(FormAction.class, execution.getAuthenticator()); + } + rep.setReferenceType(factory.getDisplayType()); rep.setConfigurable(factory.isConfigurable()); for (AuthenticationExecutionModel.Requirement choice : factory.getRequirementChoices()) { rep.getRequirementChoices().add(choice.name()); @@ -154,7 +179,7 @@ public class AuthenticationManagementResource { return Response.ok(result).build(); } - @Path("/flow/{flowAlias}/executions") + @Path("/flows/{flowAlias}/executions") @PUT @NoCache @Consumes(MediaType.APPLICATION_JSON)
Auth Type Requirement