keycloak-aplcache

Changes

Details

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 34fc32a..1ca78d5 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 @@
             <column name="PROVIDER_ID" type="VARCHAR(36)" defaultValue="basic-flow">
                 <constraints nullable="false"/>
             </column>
+            <column name="TOP_LEVEL" type="BOOLEAN" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
+            <column name="BUILT_IN" type="BOOLEAN" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
         </addColumn>
         <addColumn tableName="AUTHENTICATION_EXECUTION">
             <column name="AUTH_FLOW_ID" type="VARCHAR(36)">
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 7bf810c..7568e04 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 8d4fbc7..93e7cc3 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 5ebc0a5..da41b3c 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 8b641c1..6f25efb 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 cfc4f89..5084ab9 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 @@
 
     <table class="table table-striped table-bordered">
         <thead>
-        <!--
         <tr>
-            <th class="kc-table-actions" colspan="5">
-                <div class="form-inline">
-                    <div class="form-group">
-                        <div class="input-group">
-                            <input type="text" placeholder="Search..." data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}">
-                            <div class="input-group-addon">
-                                <i class="fa fa-search" type="submit"></i>
-                            </div>
-                        </div>
-                    </div>
+            <th colspan="5" class="kc-table-actions">
+                <div class="dropdown pull-left">
+                    <select class="form-control" ng-model="flow"
+                            ng-options="flow.alias for flow in flows"
+                            data-ng-change="setupForm()">
+                    </select>
                 </div>
             </th>
         </tr>
-        -->
         <tr data-ng-hide="executions.length == 0">
             <th colspan="2">Auth Type</th>
             <th colspan="{{flowmax}}">Requirement</th>
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 d5c54bd..c9e2cbb 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 @@
 <ul class="nav nav-tabs">
-    <li ng-class="{active: path[3] == 'flows'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/authentication/flows">Authenticators</a></li>
+    <li ng-class="{active: path[3] == 'flows'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/authentication/flows">Flows</a></li>
     <li ng-class="{active: path[3] == 'required-actions'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/authentication/required-actions">Required Actions</a></li>
     <li ng-class="{active: path[3] == 'password-policy'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/authentication/password-policy">Password Policy</a></li>
 </ul>
\ 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 db5970a..4f83d63 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 0db9560..06d312a 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<AuthenticationExecutionEntity> executions = new ArrayList<AuthenticationExecutionEntity>();
     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 dc7a44a..dee5d4f 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 45f3c09..0435873 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/entities/AuthenticationFlowEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java
index 2db9722..622ef19 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<AuthenticationExecutionEntity> executions = new ArrayList<AuthenticationExecutionEntity>();
     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/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 5ccf6c1..1891f4c 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/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 cb5cab9..a56d5f2 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<MongoRealmEntity> 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<MongoRealmEntity> 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<MongoRealmEntity> 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 d77772e..0d208c7 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 8474239..a81b74c 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 cd23b1e..4755810 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 c527ea4..90657fe 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 ffbf214..f20b3eb 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 af779b9..f67fbea 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 95e75e9..3e8d191 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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @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<ProviderConfigProperty> 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 c8716f7..28d6239 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 a78baaa..fa221c3 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<AuthenticationFlowModel> getFlows() {
+        List<AuthenticationFlowModel> 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<String>());
             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)