Skip to content

Commit

Permalink
Add keycloak_saml_client datasource (#468)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephane TEYSSIER <stephane.teyssier@wescale.fr>
  • Loading branch information
mrparkers and yesteph authored Jan 23, 2021
1 parent 25ae834 commit 67a5e69
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 0 deletions.
32 changes: 32 additions & 0 deletions docs/data-sources/saml_client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
page_title: "keycloak_saml_client Data Source"
---

# keycloak\_saml\_client Data Source

This data source can be used to fetch properties of a Keycloak client that uses the SAML protocol.

## Example Usage

```hcl
data "keycloak_saml_client" "realm_management" {
realm_id = "my-realm"
client_id = "realm-management"
}
# use the data source
data "keycloak_role" "admin" {
realm_id = "my-realm"
client_id = data.keycloak_saml_client.realm_management.id
name = "realm-admin"
}
```

## Argument Reference

- `realm_id` - (Required) The realm id.
- `client_id` - (Required) The client id (not its unique ID).

## Attributes Reference

See the docs for the `keycloak_saml_client` resource for details on the exported attributes.
168 changes: 168 additions & 0 deletions provider/data_source_keycloak_saml_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package provider

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/mrparkers/terraform-provider-keycloak/keycloak"
)

func dataSourceKeycloakSamlClient() *schema.Resource {
return &schema.Resource{
Read: dataSourceKeycloakSamlClientRead,

Schema: map[string]*schema.Schema{
"client_id": {
Type: schema.TypeString,
Required: true,
},
"realm_id": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"include_authn_statement": {
Type: schema.TypeBool,
Computed: true,
},
"sign_documents": {
Type: schema.TypeBool,
Computed: true,
},
"sign_assertions": {
Type: schema.TypeBool,
Computed: true,
},
"encrypt_assertions": {
Type: schema.TypeBool,
Computed: true,
},
"client_signature_required": {
Type: schema.TypeBool,
Computed: true,
},
"force_post_binding": {
Type: schema.TypeBool,
Computed: true,
},
"front_channel_logout": {
Type: schema.TypeBool,
Computed: true,
},
"force_name_id_format": {
Type: schema.TypeBool,
Computed: true,
},
"signature_algorithm": {
Type: schema.TypeString,
Computed: true,
},
"name_id_format": {
Type: schema.TypeString,
Computed: true,
},
"root_url": {
Type: schema.TypeString,
Computed: true,
},
"valid_redirect_uris": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
Computed: true,
},
"base_url": {
Type: schema.TypeString,
Computed: true,
},
"master_saml_processing_url": {
Type: schema.TypeString,
Computed: true,
},
"encryption_certificate": {
Type: schema.TypeString,
Computed: true,
},
"signing_certificate": {
Type: schema.TypeString,
Computed: true,
},
"signing_private_key": {
Type: schema.TypeString,
Computed: true,
},
"idp_initiated_sso_url_name": {
Type: schema.TypeString,
Computed: true,
},
"idp_initiated_sso_relay_state": {
Type: schema.TypeString,
Computed: true,
},
"assertion_consumer_post_url": {
Type: schema.TypeString,
Computed: true,
},
"assertion_consumer_redirect_url": {
Type: schema.TypeString,
Computed: true,
},
"logout_service_post_binding_url": {
Type: schema.TypeString,
Computed: true,
},
"logout_service_redirect_binding_url": {
Type: schema.TypeString,
Computed: true,
},
"full_scope_allowed": {
Type: schema.TypeBool,
Computed: true,
},
"authentication_flow_binding_overrides": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"browser_id": {
Type: schema.TypeString,
Computed: true,
},
"direct_grant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

func dataSourceKeycloakSamlClientRead(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)

realmId := data.Get("realm_id").(string)
clientId := data.Get("client_id").(string)

client, err := keycloakClient.GetSamlClientByClientId(realmId, clientId)
if err != nil {
return handleNotFoundError(err, data)
}

err = mapToDataFromSamlClient(data, client)
if err != nil {
return err
}

return nil
}
77 changes: 77 additions & 0 deletions provider/data_source_keycloak_saml_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package provider

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"testing"
)

func TestAccKeycloakDataSourceSamlClient_basic(t *testing.T) {
clientId := acctest.RandomWithPrefix("tf-acc-test")
dataSourceName := "data.keycloak_saml_client.test"
resourceName := "keycloak_saml_client.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccKeycloakSamlClientConfig(clientId),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "client_id", resourceName, "client_id"),
resource.TestCheckResourceAttrPair(dataSourceName, "realm_id", resourceName, "realm_id"),
resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"),
resource.TestCheckResourceAttrPair(dataSourceName, "enabled", resourceName, "enabled"),
resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"),
resource.TestCheckResourceAttrPair(dataSourceName, "include_authn_statement", resourceName, "include_authn_statement"),
resource.TestCheckResourceAttrPair(dataSourceName, "sign_documents", resourceName, "sign_documents"),
resource.TestCheckResourceAttrPair(dataSourceName, "sign_assertions", resourceName, "sign_assertions"),
resource.TestCheckResourceAttrPair(dataSourceName, "encrypt_assertions", resourceName, "encrypt_assertions"),
resource.TestCheckResourceAttrPair(dataSourceName, "client_signature_required", resourceName, "client_signature_required"),
resource.TestCheckResourceAttrPair(dataSourceName, "force_post_binding", resourceName, "force_post_binding"),
resource.TestCheckResourceAttrPair(dataSourceName, "front_channel_logout", resourceName, "front_channel_logout"),
resource.TestCheckResourceAttrPair(dataSourceName, "force_name_id_format", resourceName, "force_name_id_format"),
resource.TestCheckResourceAttrPair(dataSourceName, "signature_algorithm", resourceName, "signature_algorithm"),
resource.TestCheckResourceAttrPair(dataSourceName, "name_id_format", resourceName, "name_id_format"),
resource.TestCheckResourceAttrPair(dataSourceName, "root_url", resourceName, "root_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "valid_redirect_uris", resourceName, "valid_redirect_uris"),
resource.TestCheckResourceAttrPair(dataSourceName, "base_url", resourceName, "base_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "master_saml_processing_url", resourceName, "master_saml_processing_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "encryption_certificate", resourceName, "encryption_certificate"),
resource.TestCheckResourceAttrPair(dataSourceName, "signing_certificate", resourceName, "signing_certificate"),
resource.TestCheckResourceAttrPair(dataSourceName, "signing_private_key", resourceName, "signing_private_key"),
resource.TestCheckResourceAttrPair(dataSourceName, "idp_initiated_sso_url_name", resourceName, "idp_initiated_sso_url_name"),
resource.TestCheckResourceAttrPair(dataSourceName, "idp_initiated_sso_relay_state", resourceName, "idp_initiated_sso_relay_state"),
resource.TestCheckResourceAttrPair(dataSourceName, "assertion_consumer_post_url", resourceName, "assertion_consumer_post_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "assertion_consumer_redirect_url", resourceName, "assertion_consumer_redirect_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "logout_service_post_binding_url", resourceName, "logout_service_post_binding_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "logout_service_redirect_binding_url", resourceName, "logout_service_redirect_binding_url"),
resource.TestCheckResourceAttrPair(dataSourceName, "full_scope_allowed", resourceName, "full_scope_allowed"),
),
},
},
})
}

func testAccKeycloakSamlClientConfig(clientId string) string {
return fmt.Sprintf(`
data "keycloak_realm" "realm" {
realm = "%s"
}
resource keycloak_saml_client test {
client_id = "%s"
realm_id = data.keycloak_realm.realm.id
}
data keycloak_saml_client test {
client_id = keycloak_saml_client.test.client_id
realm_id = data.keycloak_realm.realm.id
depends_on = [
keycloak_saml_client.test
]
}
`, testAccRealm.Realm, clientId)
}
1 change: 1 addition & 0 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func KeycloakProvider(client *keycloak.KeycloakClient) *schema.Provider {
"keycloak_role": dataSourceKeycloakRole(),
"keycloak_user": dataSourceKeycloakUser(),
"keycloak_saml_client_installation_provider": dataSourceKeycloakSamlClientInstallationProvider(),
"keycloak_saml_client": dataSourceKeycloakSamlClient(),
"keycloak_authentication_execution": dataSourceKeycloakAuthenticationExecution(),
},
ResourcesMap: map[string]*schema.Resource{
Expand Down

0 comments on commit 67a5e69

Please sign in to comment.