Repository: mrparkers/terraform-provider-keycloak
Pull request #140 (2019-08-02 12:31:52)

added support for setting flow Bindings on Realm


Patch:
diff --git a/keycloak/realm.go b/keycloak/realm.go
index 73f85bc..e5a4528 100644
--- a/keycloak/realm.go
+++ b/keycloak/realm.go
@@ -69,6 +69,14 @@ type Realm struct {
 	Attributes Attributes `json:"attributes,omitempty"`
 
 	PasswordPolicy string `json:"passwordPolicy"`
+
+	//flow bindings
+	BrowserFlow              string `json:"browserFlow,omitempty"`
+	RegistrationFlow         string `json:"registrationFlow,omitempty"`
+	DirectGrantFlow          string `json:"directGrantFlow,omitempty"`
+	ResetCredentialsFlow     string `json:"resetCredentialsFlow,omitempty"`
+	ClientAuthenticationFlow string `json:"clientAuthenticationFlow,omitempty"`
+	DockerAuthenticationFlow string `json:"dockerAuthenticationFlow,omitempty"`
 }
 
 type Attributes struct {
@@ -109,7 +117,6 @@ func (keycloakClient *KeycloakClient) GetRealm(id string) (*Realm, error) {
 	if err != nil {
 		return nil, err
 	}
-
 	return &realm, nil
 }
 
diff --git a/provider/resource_keycloak_realm.go b/provider/resource_keycloak_realm.go
index c2777e9..bc512f9 100644
--- a/provider/resource_keycloak_realm.go
+++ b/provider/resource_keycloak_realm.go
@@ -315,6 +315,44 @@ func resourceKeycloakRealm() *schema.Resource {
 				Description: "String that represents the passwordPolicies that are in place. Each policy is separated with \" and \". Supported policies can be found in the server-info providers page. example: \"upperCase(1) and length(8) and forceExpiredPasswordChange(365) and notUsername(undefined)\"",
 				Optional:    true,
 			},
+
+			//flow bindings
+			"browser_flow": {
+				Type:        schema.TypeString,
+				Description: "Which flow should be used for BrowserFlow",
+				Optional:    true,
+				Default:     "browser",
+			},
+			"registration_flow": {
+				Type:        schema.TypeString,
+				Description: "Which flow should be used for RegistrationFlow",
+				Optional:    true,
+				Default:     "registration",
+			},
+			"direct_grant_flow": {
+				Type:        schema.TypeString,
+				Description: "Which flow should be used for DirectGrantFlow",
+				Optional:    true,
+				Default:     "direct grant",
+			},
+			"reset_credentials_flow": {
+				Type:        schema.TypeString,
+				Description: "Which flow should be used for ResetCredentialsFlow",
+				Optional:    true,
+				Default:     "registration",
+			},
+			"client_authentication_flow": {
+				Type:        schema.TypeString,
+				Description: "Which flow should be used for ClientAuthenticationFlow",
+				Optional:    true,
+				Default:     "clients",
+			},
+			"docker_authentication_flow": {
+				Type:        schema.TypeString,
+				Description: "Which flow should be used for DockerAuthenticationFlow",
+				Optional:    true,
+				Default:     "docker auth",
+			},
 		},
 	}
 }
@@ -543,6 +581,32 @@ func getRealmFromData(data *schema.ResourceData) (*keycloak.Realm, error) {
 	if passwordPolicy, ok := data.GetOk("password_policy"); ok {
 		realm.PasswordPolicy = passwordPolicy.(string)
 	}
+
+	//Flow Bindings
+	if flow, ok := data.GetOk("browser_flow"); ok {
+		realm.BrowserFlow = flow.(string)
+	}
+
+	if flow, ok := data.GetOk("registration_flow"); ok {
+		realm.RegistrationFlow = flow.(string)
+	}
+
+	if flow, ok := data.GetOk("direct_grant_flow"); ok {
+		realm.DirectGrantFlow = flow.(string)
+	}
+
+	if flow, ok := data.GetOk("reset_credentials_flow"); ok {
+		realm.ResetCredentialsFlow = flow.(string)
+	}
+
+	if flow, ok := data.GetOk("client_authentication_flow"); ok {
+		realm.ClientAuthenticationFlow = flow.(string)
+	}
+
+	if flow, ok := data.GetOk("docker_authentication_flow"); ok {
+		realm.DockerAuthenticationFlow = flow.(string)
+	}
+
 	return realm, nil
 }
 
@@ -658,6 +722,14 @@ func setRealmData(data *schema.ResourceData, realm *keycloak.Realm) {
 	}
 
 	data.Set("password_policy", realm.PasswordPolicy)
+
+	//Flow Bindings
+	data.Set("browser_flow", realm.BrowserFlow)
+	data.Set("registration_flow", realm.RegistrationFlow)
+	data.Set("direct_grant_flow", realm.DirectGrantFlow)
+	data.Set("reset_credentials_flow", realm.ResetCredentialsFlow)
+	data.Set("client_authentication_flow", realm.ClientAuthenticationFlow)
+	data.Set("docker_authentication_flow", realm.DockerAuthenticationFlow)
 }
 
 func resourceKeycloakRealmCreate(data *schema.ResourceData, meta interface{}) error {


Test patch:
diff --git a/provider/resource_keycloak_realm_test.go b/provider/resource_keycloak_realm_test.go
index 6d1dba6..65774d4 100644
--- a/provider/resource_keycloak_realm_test.go
+++ b/provider/resource_keycloak_realm_test.go
@@ -478,6 +478,32 @@ func TestAccKeycloakRealm_passwordPolicy(t *testing.T) {
 	})
 }
 
+func TestAccKeycloakRealm_browserFlow(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	realmDisplayName := "terraform-" + acctest.RandString(10)
+	newBrowserFlow := "registration"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccCheckKeycloakRealmDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakRealm_basic(realmName, realmDisplayName),
+				Check:  testAccCheckKeycloakRealmBrowserFlow("keycloak_realm.realm", "browser"),
+			},
+			{
+				Config: testKeycloakRealm_browserFlow(realmName, realmDisplayName, newBrowserFlow),
+				Check:  testAccCheckKeycloakRealmBrowserFlow("keycloak_realm.realm", newBrowserFlow),
+			},
+			{
+				Config: testKeycloakRealm_basic(realmName, realmDisplayName),
+				Check:  testAccCheckKeycloakRealmBrowserFlow("keycloak_realm.realm", "browser"),
+			},
+		},
+	})
+}
+
 func TestAccKeycloakRealm_passwordPolicyInvalid(t *testing.T) {
 	realmName := "terraform-" + acctest.RandString(10)
 	realmDisplayName := "terraform-" + acctest.RandString(10)
@@ -734,6 +760,21 @@ func testAccCheckKeycloakRealmPasswordPolicy(resourceName, passwordPolicy string
 	}
 }
 
+func testAccCheckKeycloakRealmBrowserFlow(resourceName, browserFlow string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		realm, err := getRealmFromState(s, resourceName)
+		if err != nil {
+			return err
+		}
+
+		if realm.BrowserFlow != browserFlow {
+			return fmt.Errorf("expected realm %s to have browserFlow binding %s, but was %s", realm.Realm, browserFlow, realm.BrowserFlow)
+		}
+
+		return nil
+	}
+}
+
 func testKeycloakRealm_basic(realm, realmDisplayName string) string {
 	return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
@@ -998,3 +1039,14 @@ resource "keycloak_realm" "realm" {
 }
 	`, realm, realmDisplayName, passwordPolicy)
 }
+
+func testKeycloakRealm_browserFlow(realm, realmDisplayName, browserFlow string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm        = "%s"
+	enabled      = true
+	display_name = "%s"
+	browser_flow = "%s"
+}
+	`, realm, realmDisplayName, browserFlow)
+}