Repository: mrparkers/terraform-provider-keycloak
Pull request #103 (2019-04-08 08:25:28)

Add some missing SAML client attributes
This just adds a few SAML client attributes that were missing.


Patch:
diff --git a/docs/resources/keycloak_saml_client.md b/docs/resources/keycloak_saml_client.md
index bee4fc9..374f837 100644
--- a/docs/resources/keycloak_saml_client.md
+++ b/docs/resources/keycloak_saml_client.md
@@ -50,7 +50,12 @@ The following arguments are supported:
 - `master_saml_processing_url` - (Optional) When specified, this URL will be used for all SAML requests.
 - `signing_certificate` - (Optional) If documents or assertions from the client are signed, this certificate will be used to verify the signature.
 - `signing_private_key` - (Optional) If documents or assertions from the client are signed, this private key will be used to verify the signature.
-
+- `idp_initiated_sso_url_name` - (Optional) URL fragment name to reference client when you want to do IDP Initiated SSO.
+- `idp_initiated_sso_relay_state` - (Optional) Relay state you want to send with SAML request when you want to do IDP Initiated SSO.
+- `assertion_consumer_post_url` - (Optional) SAML POST Binding URL for the client's assertion consumer service (login responses).
+- `assertion_consumer_redirect_url` - (Optional) SAML Redirect Binding URL for the client's assertion consumer service (login responses).
+- `logout_service_post_binding_url` - (Optional) SAML POST Binding URL for the client's single logout service.
+- `logout_service_redirect_binding_url` - (Optional) SAML Redirect Binding URL for the client's single logout service.
 
 ### Import
 
diff --git a/keycloak/saml_client.go b/keycloak/saml_client.go
index 0dc080c..be060a1 100644
--- a/keycloak/saml_client.go
+++ b/keycloak/saml_client.go
@@ -11,9 +11,15 @@ type SamlClientAttributes struct {
 	ClientSignatureRequired *string `json:"saml.client.signature"`
 	ForcePostBinding        *string `json:"saml.force.post.binding"`
 	// attributes above are actually booleans, but the Keycloak API expects strings
-	NameIdFormat       string  `json:"saml_name_id_format"`
-	SigningCertificate *string `json:"saml.signing.certificate,omitempty"`
-	SigningPrivateKey  *string `json:"saml.signing.private.key"`
+	NameIdFormat                    string  `json:"saml_name_id_format"`
+	SigningCertificate              *string `json:"saml.signing.certificate,omitempty"`
+	SigningPrivateKey               *string `json:"saml.signing.private.key"`
+	IDPInitiatedSSOURLName          string  `json:"saml_idp_initiated_sso_url_name"`
+	IDPInitiatedSSORelayState       string  `json:"saml_idp_initiated_sso_relay_state"`
+	AssertionConsumerPostURL        string  `json:"saml_assertion_consumer_url_post"`
+	AssertionConsumerRedirectURL    string  `json:"saml_assertion_consumer_url_redirect"`
+	LogoutServicePostBindingURL     string  `json:"saml_single_logout_service_url_post"`
+	LogoutServiceRedirectBindingURL string  `json:"saml_single_logout_service_url_redirect"`
 }
 
 type SamlClient struct {
diff --git a/provider/keycloak_saml_client.go b/provider/keycloak_saml_client.go
index edc4c96..2bf5966 100644
--- a/provider/keycloak_saml_client.go
+++ b/provider/keycloak_saml_client.go
@@ -2,11 +2,12 @@ package provider
 
 import (
 	"fmt"
+	"strconv"
+	"strings"
+
 	"github.com/hashicorp/terraform/helper/schema"
 	"github.com/hashicorp/terraform/helper/validation"
 	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
-	"strconv"
-	"strings"
 )
 
 var (
@@ -114,6 +115,30 @@ func resourceKeycloakSamlClient() *schema.Resource {
 					return old == formatSigningPrivateKey(new)
 				},
 			},
+			"idp_initiated_sso_url_name": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"idp_initiated_sso_relay_state": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"assertion_consumer_post_url": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"assertion_consumer_redirect_url": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"logout_service_post_binding_url": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"logout_service_redirect_binding_url": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
 		},
 	}
 }
@@ -148,7 +173,13 @@ func mapToSamlClientFromData(data *schema.ResourceData) *keycloak.SamlClient {
 	}
 
 	samlAttributes := &keycloak.SamlClientAttributes{
-		NameIdFormat: data.Get("name_id_format").(string),
+		NameIdFormat:                    data.Get("name_id_format").(string),
+		IDPInitiatedSSOURLName:          data.Get("idp_initiated_sso_url_name").(string),
+		IDPInitiatedSSORelayState:       data.Get("idp_initiated_sso_relay_state").(string),
+		AssertionConsumerPostURL:        data.Get("assertion_consumer_post_url").(string),
+		AssertionConsumerRedirectURL:    data.Get("assertion_consumer_redirect_url").(string),
+		LogoutServicePostBindingURL:     data.Get("logout_service_post_binding_url").(string),
+		LogoutServiceRedirectBindingURL: data.Get("logout_service_redirect_binding_url").(string),
 	}
 
 	if signingCertificate, ok := data.GetOkExists("signing_certificate"); ok {
@@ -271,6 +302,12 @@ func mapToDataFromSamlClient(data *schema.ResourceData, client *keycloak.SamlCli
 	data.Set("base_url", client.BaseUrl)
 	data.Set("master_saml_processing_url", client.MasterSamlProcessingUrl)
 	data.Set("name_id_format", client.Attributes.NameIdFormat)
+	data.Set("idp_initiated_sso_url_name", client.Attributes.IDPInitiatedSSOURLName)
+	data.Set("idp_initiated_sso_relay_state", client.Attributes.IDPInitiatedSSORelayState)
+	data.Set("assertion_consumer_post_url", client.Attributes.AssertionConsumerPostURL)
+	data.Set("assertion_consumer_redirect_url", client.Attributes.AssertionConsumerRedirectURL)
+	data.Set("logout_service_post_binding_url", client.Attributes.LogoutServicePostBindingURL)
+	data.Set("logout_service_redirect_binding_url", client.Attributes.LogoutServiceRedirectBindingURL)
 
 	return nil
 }


Test patch:
diff --git a/provider/keycloak_saml_client_test.go b/provider/keycloak_saml_client_test.go
index ec253b4..a966fb0 100644
--- a/provider/keycloak_saml_client_test.go
+++ b/provider/keycloak_saml_client_test.go
@@ -2,13 +2,14 @@ package provider
 
 import (
 	"fmt"
+	"strconv"
+	"strings"
+	"testing"
+
 	"github.com/hashicorp/terraform/helper/acctest"
 	"github.com/hashicorp/terraform/helper/resource"
 	"github.com/hashicorp/terraform/terraform"
 	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
-	"strconv"
-	"strings"
-	"testing"
 )
 
 func TestAccKeycloakSamlClient_basic(t *testing.T) {
@@ -152,14 +153,20 @@ func TestAccKeycloakSamlClient_updateInPlace(t *testing.T) {
 		MasterSamlProcessingUrl: acctest.RandString(20),
 
 		Attributes: &keycloak.SamlClientAttributes{
-			IncludeAuthnStatement:   randomBoolAsStringPointer(),
-			SignDocuments:           randomBoolAsStringPointer(),
-			SignAssertions:          randomBoolAsStringPointer(),
-			ClientSignatureRequired: &clientSignatureRequired,
-			ForcePostBinding:        randomBoolAsStringPointer(),
-			NameIdFormat:            randomStringInSlice(keycloakSamlClientNameIdFormats),
-			SigningCertificate:      &signingCertificateBefore,
-			SigningPrivateKey:       &signingPrivateKeyBefore,
+			IncludeAuthnStatement:           randomBoolAsStringPointer(),
+			SignDocuments:                   randomBoolAsStringPointer(),
+			SignAssertions:                  randomBoolAsStringPointer(),
+			ClientSignatureRequired:         &clientSignatureRequired,
+			ForcePostBinding:                randomBoolAsStringPointer(),
+			NameIdFormat:                    randomStringInSlice(keycloakSamlClientNameIdFormats),
+			SigningCertificate:              &signingCertificateBefore,
+			SigningPrivateKey:               &signingPrivateKeyBefore,
+			IDPInitiatedSSOURLName:          acctest.RandString(20),
+			IDPInitiatedSSORelayState:       acctest.RandString(20),
+			AssertionConsumerPostURL:        acctest.RandString(20),
+			AssertionConsumerRedirectURL:    acctest.RandString(20),
+			LogoutServicePostBindingURL:     acctest.RandString(20),
+			LogoutServiceRedirectBindingURL: acctest.RandString(20),
 		},
 	}
 
@@ -181,14 +188,20 @@ func TestAccKeycloakSamlClient_updateInPlace(t *testing.T) {
 		MasterSamlProcessingUrl: acctest.RandString(20),
 
 		Attributes: &keycloak.SamlClientAttributes{
-			IncludeAuthnStatement:   randomBoolAsStringPointer(),
-			SignDocuments:           randomBoolAsStringPointer(),
-			SignAssertions:          randomBoolAsStringPointer(),
-			ClientSignatureRequired: &clientSignatureRequired,
-			ForcePostBinding:        randomBoolAsStringPointer(),
-			NameIdFormat:            randomStringInSlice(keycloakSamlClientNameIdFormats),
-			SigningCertificate:      &signingCertificateAfter,
-			SigningPrivateKey:       &signingPrivateKeyAfter,
+			IncludeAuthnStatement:           randomBoolAsStringPointer(),
+			SignDocuments:                   randomBoolAsStringPointer(),
+			SignAssertions:                  randomBoolAsStringPointer(),
+			ClientSignatureRequired:         &clientSignatureRequired,
+			ForcePostBinding:                randomBoolAsStringPointer(),
+			NameIdFormat:                    randomStringInSlice(keycloakSamlClientNameIdFormats),
+			SigningCertificate:              &signingCertificateAfter,
+			SigningPrivateKey:               &signingPrivateKeyAfter,
+			IDPInitiatedSSOURLName:          acctest.RandString(20),
+			IDPInitiatedSSORelayState:       acctest.RandString(20),
+			AssertionConsumerPostURL:        acctest.RandString(20),
+			AssertionConsumerRedirectURL:    acctest.RandString(20),
+			LogoutServicePostBindingURL:     acctest.RandString(20),
+			LogoutServiceRedirectBindingURL: acctest.RandString(20),
 		},
 	}
 
@@ -484,8 +497,39 @@ resource "keycloak_saml_client" "saml_client" {
 
 	signing_certificate        = "%s"
 	signing_private_key        = "%s"
-}
-	`, client.RealmId, client.ClientId, client.Name, client.Description, client.Enabled, *client.Attributes.IncludeAuthnStatement, *client.Attributes.SignDocuments, *client.Attributes.SignAssertions, *client.Attributes.ClientSignatureRequired, *client.Attributes.ForcePostBinding, client.FrontChannelLogout, client.Attributes.NameIdFormat, client.RootUrl, arrayOfStringsForTerraformResource(client.ValidRedirectUris), client.BaseUrl, client.MasterSamlProcessingUrl, *client.Attributes.SigningCertificate, *client.Attributes.SigningPrivateKey)
+
+	idp_initiated_sso_url_name    = "%s"
+	idp_initiated_sso_relay_state = "%s"
+
+	assertion_consumer_post_url         = "%s"
+	assertion_consumer_redirect_url     = "%s"
+	logout_service_post_binding_url     = "%s"
+	logout_service_redirect_binding_url = "%s"
+}
+	`, client.RealmId,
+		client.ClientId,
+		client.Name,
+		client.Description,
+		client.Enabled,
+		*client.Attributes.IncludeAuthnStatement,
+		*client.Attributes.SignDocuments,
+		*client.Attributes.SignAssertions,
+		*client.Attributes.ClientSignatureRequired,
+		*client.Attributes.ForcePostBinding,
+		client.FrontChannelLogout,
+		client.Attributes.NameIdFormat,
+		client.RootUrl,
+		arrayOfStringsForTerraformResource(client.ValidRedirectUris),
+		client.BaseUrl, client.MasterSamlProcessingUrl,
+		*client.Attributes.SigningCertificate,
+		*client.Attributes.SigningPrivateKey,
+		client.Attributes.IDPInitiatedSSOURLName,
+		client.Attributes.IDPInitiatedSSORelayState,
+		client.Attributes.AssertionConsumerPostURL,
+		client.Attributes.AssertionConsumerRedirectURL,
+		client.Attributes.LogoutServicePostBindingURL,
+		client.Attributes.LogoutServiceRedirectBindingURL,
+	)
 }
 
 func testKeycloakSamlClient_signingCertificateAndKey(realm, clientId string) string {