Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/data-sources/saml_client_installation_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ resource "aws_iam_saml_provider" "default" {

- `id` - (Computed) The hash of the value.
- `value` - (Computed) The returned document needed for SAML installation.
- `zip_files` - (Computed) A map of files if the returned document is a zip file. (ex: provider `mod-auth-mellon`)
50 changes: 50 additions & 0 deletions provider/data_source_keycloak_saml_client_installation_provider.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package provider

import (
"archive/zip"
"bytes"
"context"
"crypto/sha1"
"encoding/base64"
"errors"
"fmt"
"io"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/keycloak/terraform-provider-keycloak/keycloak"
Expand All @@ -29,6 +35,13 @@ func dataSourceKeycloakSamlClientInstallationProvider() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"zip_files": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}
Expand All @@ -55,5 +68,42 @@ func dataSourceKeycloakSamlClientInstallationProviderRead(ctx context.Context, d
data.Set("provider_id", providerId)
data.Set("value", string(value))

zipFiles, err := readZipFiles(value)
if err != nil {
return diag.FromErr(err)
}
data.Set("zip_files", zipFiles)

return nil
}

func readZipFiles(content []byte) (map[string]string, error) {
zipReader, err := zip.NewReader(bytes.NewReader(content), int64(len(content)))
if err != nil {
if errors.Is(err, zip.ErrFormat) {
return nil, nil
}

return nil, fmt.Errorf("error reading zip files: %w", err)
}

files := make(map[string]string, len(zipReader.File))
for _, file := range zipReader.File {
fileReader, err := file.Open()
if err != nil {
return nil, fmt.Errorf("error opening zip file for reading: %w", err)
}
fileContent, err := io.ReadAll(fileReader)
if err != nil {
return nil, fmt.Errorf("error reading zip file content: %w", err)
}
files[file.FileInfo().Name()] = string(fileContent)

err = fileReader.Close()
if err != nil {
return nil, fmt.Errorf("error closing zip file content: %w", err)
}
}

return files, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,64 @@ func TestAccKeycloakDataSourceSamlClientInstallationProvider_basic(t *testing.T)
clientId := acctest.RandomWithPrefix("tf-acc")

resourceName := "keycloak_saml_client.saml_client"
dataSourceName := "data.keycloak_saml_client_installation_provider.saml_sp_descriptor"
dataSourceName := "data.keycloak_saml_client_installation_provider.descriptor"

resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviderFactories,
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: testAccCheckKeycloakSamlClientDestroy(),
Steps: []resource.TestStep{
{
Config: testDataSourceKeycloakSamlClientInstallationProvider_basic(clientId),
Config: testDataSourceKeycloakSamlClientInstallationProvider(clientId, "saml-sp-descriptor"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "realm_id", resourceName, "realm_id"),
resource.TestCheckResourceAttrPair(dataSourceName, "client_id", resourceName, "id"),
resource.TestCheckResourceAttr(dataSourceName, "provider_id", "saml-sp-descriptor"),
testAccCheckDataKeycloakSamlClientInstallationProvider(dataSourceName),
resource.TestCheckResourceAttr(dataSourceName, "zip_files.%", "0"),
testAccCheckDataKeycloakSamlClientInstallationProvider_isXML(dataSourceName, "value"),
),
},
},
})
}

func testAccCheckDataKeycloakSamlClientInstallationProvider(resourceName string) resource.TestCheckFunc {
func TestAccKeycloakDataSourceSamlClientInstallationProvider_zip(t *testing.T) {
t.Parallel()
clientId := acctest.RandomWithPrefix("tf-acc")

resourceName := "keycloak_saml_client.saml_client"
dataSourceName := "data.keycloak_saml_client_installation_provider.descriptor"

resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviderFactories,
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: testAccCheckKeycloakSamlClientDestroy(),
Steps: []resource.TestStep{
{
Config: testDataSourceKeycloakSamlClientInstallationProvider(clientId, "mod-auth-mellon"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "realm_id", resourceName, "realm_id"),
resource.TestCheckResourceAttrPair(dataSourceName, "client_id", resourceName, "id"),
resource.TestCheckResourceAttr(dataSourceName, "provider_id", "mod-auth-mellon"),
resource.TestCheckResourceAttr(dataSourceName, "zip_files.%", "4"),
testAccCheckDataKeycloakSamlClientInstallationProvider_isXML(dataSourceName, "zip_files.idp-metadata.xml"),
testAccCheckDataKeycloakSamlClientInstallationProvider_isXML(dataSourceName, "zip_files.sp-metadata.xml"),
resource.TestCheckResourceAttrSet(dataSourceName, "zip_files.client-cert.pem"),
resource.TestCheckResourceAttrSet(dataSourceName, "zip_files.client-private-key.pem"),
),
},
},
})
}

func testAccCheckDataKeycloakSamlClientInstallationProvider_isXML(resourceName string, attributeName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("resource not found: %s", resourceName)
}

value := rs.Primary.Attributes["value"]
value := rs.Primary.Attributes[attributeName]

err := xml.Unmarshal([]byte(value), new(interface{}))
if err != nil {
Expand All @@ -53,7 +83,7 @@ func testAccCheckDataKeycloakSamlClientInstallationProvider(resourceName string)
}
}

func testDataSourceKeycloakSamlClientInstallationProvider_basic(clientId string) string {
func testDataSourceKeycloakSamlClientInstallationProvider(clientId string, providerId string) string {
return fmt.Sprintf(`
data "keycloak_realm" "realm" {
realm = "%s"
Expand All @@ -64,10 +94,10 @@ resource "keycloak_saml_client" "saml_client" {
realm_id = data.keycloak_realm.realm.id
}

data "keycloak_saml_client_installation_provider" "saml_sp_descriptor" {
data "keycloak_saml_client_installation_provider" "descriptor" {
realm_id = data.keycloak_realm.realm.id
client_id = keycloak_saml_client.saml_client.id
provider_id = "saml-sp-descriptor"
provider_id = "%s"
}
`, testAccRealm.Realm, clientId)
`, testAccRealm.Realm, clientId, providerId)
}
Loading