diff --git a/example/main.tf b/example/main.tf index b21b30e6b..fdad833e2 100644 --- a/example/main.tf +++ b/example/main.tf @@ -567,6 +567,11 @@ resource keycloak_attribute_importer_identity_provider_mapper oidc { claim_name = "upn" identity_provider_alias = keycloak_oidc_identity_provider.oidc.alias user_attribute = "email" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_attribute_to_role_identity_provider_mapper oidc { @@ -576,6 +581,11 @@ resource keycloak_attribute_to_role_identity_provider_mapper oidc { identity_provider_alias = keycloak_oidc_identity_provider.oidc.alias claim_value = "value" role = "testRole" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_user_template_importer_identity_provider_mapper oidc { @@ -583,6 +593,11 @@ resource keycloak_user_template_importer_identity_provider_mapper oidc { name = "userTemplate" identity_provider_alias = keycloak_oidc_identity_provider.oidc.alias template = "$${ALIAS}/$${CLAIM.upn}" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_hardcoded_role_identity_provider_mapper oidc { @@ -590,6 +605,11 @@ resource keycloak_hardcoded_role_identity_provider_mapper oidc { name = "hardcodedRole" identity_provider_alias = keycloak_oidc_identity_provider.oidc.alias role = "testrole" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_hardcoded_attribute_identity_provider_mapper oidc { @@ -599,6 +619,11 @@ resource keycloak_hardcoded_attribute_identity_provider_mapper oidc { attribute_name = "attribute" attribute_value = "value" user_session = true + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_saml_identity_provider saml { @@ -613,6 +638,11 @@ resource keycloak_attribute_importer_identity_provider_mapper saml { attribute_name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" identity_provider_alias = keycloak_saml_identity_provider.saml.alias user_attribute = "email" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_attribute_to_role_identity_provider_mapper saml { @@ -622,6 +652,11 @@ resource keycloak_attribute_to_role_identity_provider_mapper saml { identity_provider_alias = keycloak_saml_identity_provider.saml.alias attribute_value = "value" role = "testRole" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_user_template_importer_identity_provider_mapper saml { @@ -629,6 +664,11 @@ resource keycloak_user_template_importer_identity_provider_mapper saml { name = "userTemplate" identity_provider_alias = keycloak_saml_identity_provider.saml.alias template = "$${ALIAS}/$${NAMEID}" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_hardcoded_role_identity_provider_mapper saml { @@ -636,6 +676,11 @@ resource keycloak_hardcoded_role_identity_provider_mapper saml { name = "hardcodedRole" identity_provider_alias = keycloak_saml_identity_provider.saml.alias role = "testrole" + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } resource keycloak_hardcoded_attribute_identity_provider_mapper saml { @@ -645,6 +690,11 @@ resource keycloak_hardcoded_attribute_identity_provider_mapper saml { attribute_name = "attribute" attribute_value = "value" user_session = false + + #KC10 support + extra_config = { + syncMode = "INHERIT" + } } data "keycloak_openid_client" "broker" { diff --git a/example/roles.tf b/example/roles.tf index 0722f7f70..fffb1abcb 100644 --- a/example/roles.tf +++ b/example/roles.tf @@ -160,6 +160,44 @@ resource "keycloak_generic_client_role_mapper" "pet_app_pet_api_admin_role_mappi role_id = keycloak_role.pet_api_admin.id } +// Realm roles + +resource "keycloak_role" "realm_reader" { + realm_id = keycloak_realm.roles_example.id + name = "realm_reader" + description = "Reader realm role" +} + +resource "keycloak_role" "realm_writer" { + realm_id = keycloak_realm.roles_example.id + name = "realm_writer" + description = "Writer realm role" +} + +resource "keycloak_role" "realm_admin" { + realm_id = keycloak_realm.roles_example.id + name = "realm_admin" + description = "Admin realm composite role" + composite_roles = [ + keycloak_role.realm_reader.id, + keycloak_role.realm_writer.id + ] +} + +// Client scope for realm roles mapping + +resource "keycloak_openid_client_scope" "petstore_api_access_scope" { + realm_id = keycloak_realm.roles_example.id + name = "petstore-api-access" + description = "Optional scope offering additional information for petstore api access" +} + +resource "keycloak_generic_client_role_mapper" "petstore_api_access_scope_admin" { + realm_id = keycloak_realm.roles_example.id + client_scope_id = keycloak_openid_client_scope.petstore_api_access_scope.id + role_id = keycloak_role.realm_admin.id +} + // Users and groups resource "keycloak_group" "pet_api_base" { diff --git a/keycloak/identity_provider_mapper.go b/keycloak/identity_provider_mapper.go index f30927a65..eb986958a 100644 --- a/keycloak/identity_provider_mapper.go +++ b/keycloak/identity_provider_mapper.go @@ -1,20 +1,25 @@ package keycloak import ( + "encoding/json" "fmt" "log" + "reflect" + "strconv" + "strings" ) type IdentityProviderMapperConfig struct { - UserAttribute string `json:"user.attribute,omitempty"` - Claim string `json:"claim,omitempty"` - ClaimValue string `json:"claim.value,omitempty"` - HardcodedAttribute string `json:"attribute,omitempty"` - Attribute string `json:"attribute.name,omitempty"` - AttributeValue string `json:"attribute.value,omitempty"` - AttributeFriendlyName string `json:"attribute.friendly.name,omitempty"` - Template string `json:"template,omitempty"` - Role string `json:"role,omitempty"` + UserAttribute string `json:"user.attribute,omitempty"` + Claim string `json:"claim,omitempty"` + ClaimValue string `json:"claim.value,omitempty"` + HardcodedAttribute string `json:"attribute,omitempty"` + Attribute string `json:"attribute.name,omitempty"` + AttributeValue string `json:"attribute.value,omitempty"` + AttributeFriendlyName string `json:"attribute.friendly.name,omitempty"` + Template string `json:"template,omitempty"` + Role string `json:"role,omitempty"` + ExtraConfig map[string]interface{} `json:"-"` } type IdentityProviderMapper struct { @@ -59,3 +64,57 @@ func (keycloakClient *KeycloakClient) UpdateIdentityProviderMapper(identityProvi func (keycloakClient *KeycloakClient) DeleteIdentityProviderMapper(realm, alias, id string) error { return keycloakClient.delete(fmt.Sprintf("/realms/%s/identity-provider/instances/%s/mappers/%s", realm, alias, id), nil) } + +func (f *IdentityProviderMapperConfig) UnmarshalJSON(data []byte) error { + f.ExtraConfig = map[string]interface{}{} + err := json.Unmarshal(data, &f.ExtraConfig) + if err != nil { + return err + } + v := reflect.ValueOf(f).Elem() + for i := 0; i < v.NumField(); i++ { + structField := v.Type().Field(i) + jsonKey := strings.Split(structField.Tag.Get("json"), ",")[0] + if jsonKey != "-" { + value, ok := f.ExtraConfig[jsonKey] + if ok { + field := v.FieldByName(structField.Name) + if field.IsValid() && field.CanSet() { + if field.Kind() == reflect.String { + field.SetString(value.(string)) + } else if field.Kind() == reflect.Bool { + boolVal, err := strconv.ParseBool(value.(string)) + if err == nil { + field.Set(reflect.ValueOf(KeycloakBoolQuoted(boolVal))) + } + } + delete(f.ExtraConfig, jsonKey) + } + } + } + } + return nil +} + +func (f *IdentityProviderMapperConfig) MarshalJSON() ([]byte, error) { + out := map[string]interface{}{} + + for k, v := range f.ExtraConfig { + out[k] = v + } + v := reflect.ValueOf(f).Elem() + for i := 0; i < v.NumField(); i++ { + jsonKey := strings.Split(v.Type().Field(i).Tag.Get("json"), ",")[0] + if jsonKey != "-" { + field := v.Field(i) + if field.IsValid() && field.CanSet() { + if field.Kind() == reflect.String { + out[jsonKey] = field.String() + } else if field.Kind() == reflect.Bool { + out[jsonKey] = KeycloakBoolQuoted(field.Bool()) + } + } + } + } + return json.Marshal(out) +} diff --git a/keycloak/role_scope_mapping.go b/keycloak/role_scope_mapping.go index 4aabd4f33..35506d417 100644 --- a/keycloak/role_scope_mapping.go +++ b/keycloak/role_scope_mapping.go @@ -5,10 +5,19 @@ import ( ) func roleScopeMappingUrl(realmId, clientId string, clientScopeId string, role *Role) string { + if clientId != "" { - return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/clients/%s", realmId, clientId, role.ClientId) - } else { + if role.ClientRole { + return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/clients/%s", realmId, clientId, role.ClientId) + } else { + return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/realm", realmId, clientId) + } + } + + if role.ClientRole { return fmt.Sprintf("/realms/%s/client-scopes/%s/scope-mappings/clients/%s", realmId, clientScopeId, role.ClientId) + } else { + return fmt.Sprintf("/realms/%s/client-scopes/%s/scope-mappings/realm", realmId, clientScopeId) } } diff --git a/provider/generic_keycloak_identity_provider_mapper.go b/provider/generic_keycloak_identity_provider_mapper.go index 83109ec26..b4db8f9ec 100644 --- a/provider/generic_keycloak_identity_provider_mapper.go +++ b/provider/generic_keycloak_identity_provider_mapper.go @@ -2,9 +2,10 @@ package provider import ( "fmt" + "strings" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "strings" ) type identityProviderMapperDataGetterFunc func(data *schema.ResourceData, meta interface{}) (*keycloak.IdentityProviderMapper, error) @@ -35,6 +36,10 @@ func resourceKeycloakIdentityProviderMapper() *schema.Resource { ForceNew: true, Description: "IDP Alias", }, + "extra_config": { + Type: schema.TypeMap, + Optional: true, + }, }, } } diff --git a/provider/resource_keycloak_attribute_importer_identity_provider_mapper.go b/provider/resource_keycloak_attribute_importer_identity_provider_mapper.go index 906c8a5dc..f10f28420 100644 --- a/provider/resource_keycloak_attribute_importer_identity_provider_mapper.go +++ b/provider/resource_keycloak_attribute_importer_identity_provider_mapper.go @@ -2,6 +2,7 @@ package provider import ( "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" ) @@ -42,6 +43,12 @@ func resourceKeycloakAttributeImporterIdentityProviderMapper() *schema.Resource func getAttributeImporterIdentityProviderMapperFromData(data *schema.ResourceData, meta interface{}) (*keycloak.IdentityProviderMapper, error) { keycloakClient := meta.(*keycloak.KeycloakClient) rec, _ := getIdentityProviderMapperFromData(data) + extraConfig := map[string]interface{}{} + if v, ok := data.GetOk("extra_config"); ok { + for key, value := range v.(map[string]interface{}) { + extraConfig[key] = value + } + } identityProvider, err := keycloakClient.GetIdentityProvider(rec.Realm, rec.IdentityProviderAlias) if err != nil { return nil, handleNotFoundError(err, data) @@ -49,6 +56,7 @@ func getAttributeImporterIdentityProviderMapperFromData(data *schema.ResourceDat rec.IdentityProviderMapper = fmt.Sprintf("%s-user-attribute-idp-mapper", identityProvider.ProviderId) rec.Config = &keycloak.IdentityProviderMapperConfig{ UserAttribute: data.Get("user_attribute").(string), + ExtraConfig: extraConfig, } if identityProvider.ProviderId == "saml" { if attr, ok := data.GetOk("attribute_friendly_name"); ok { @@ -75,5 +83,6 @@ func setAttributeImporterIdentityProviderMapperData(data *schema.ResourceData, i data.Set("user_attribute", identityProviderMapper.Config.UserAttribute) data.Set("attribute_friendly_name", identityProviderMapper.Config.AttributeFriendlyName) data.Set("claim_name", identityProviderMapper.Config.Claim) + data.Set("extra_config", identityProviderMapper.Config.ExtraConfig) return nil } diff --git a/provider/resource_keycloak_attribute_importer_identity_provider_mapper_test.go b/provider/resource_keycloak_attribute_importer_identity_provider_mapper_test.go index 1fb8955bb..e18d6ff42 100644 --- a/provider/resource_keycloak_attribute_importer_identity_provider_mapper_test.go +++ b/provider/resource_keycloak_attribute_importer_identity_provider_mapper_test.go @@ -2,11 +2,12 @@ package provider import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "testing" ) func TestAccKeycloakAttributeImporterIdentityProviderMapper_basic(t *testing.T) { @@ -29,6 +30,27 @@ func TestAccKeycloakAttributeImporterIdentityProviderMapper_basic(t *testing.T) }) } +func TestAccKeycloakAttributeImporterIdentityProviderMapper_withExtraConfig(t *testing.T) { + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + userAttribute := "terraform-" + acctest.RandString(10) + claimName := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakAttributeImporterIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakAttributeImporterIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, userAttribute, claimName, syncMode), + Check: testAccCheckKeycloakAttributeImporterIdentityProviderMapperExists("keycloak_attribute_importer_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakAttributeImporterIdentityProviderMapper_createAfterManualDestroy(t *testing.T) { var mapper = &keycloak.IdentityProviderMapper{} @@ -63,6 +85,41 @@ func TestAccKeycloakAttributeImporterIdentityProviderMapper_createAfterManualDes }) } +func TestAccKeycloakAttributeImporterIdentityProviderMapper_withExtraConfig_createAfterManualDestroy(t *testing.T) { + var mapper = &keycloak.IdentityProviderMapper{} + + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + userAttribute := "terraform-" + acctest.RandString(10) + claimName := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakAttributeImporterIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakAttributeImporterIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, userAttribute, claimName, syncMode), + Check: testAccCheckKeycloakAttributeImporterIdentityProviderMapperFetch("keycloak_attribute_importer_identity_provider_mapper.oidc", mapper), + }, + { + PreConfig: func() { + keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) + + err := keycloakClient.DeleteIdentityProviderMapper(mapper.Realm, mapper.IdentityProviderAlias, mapper.Id) + if err != nil { + t.Fatal(err) + } + }, + Config: testKeycloakAttributeImporterIdentityProviderMapper_basic(realmName, alias, mapperName, userAttribute, claimName), + Check: testAccCheckKeycloakAttributeImporterIdentityProviderMapperExists("keycloak_attribute_importer_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakAttributeImporterIdentityProviderMapper_basicUpdateRealm(t *testing.T) { firstRealm := "terraform-" + acctest.RandString(10) secondRealm := "terraform-" + acctest.RandString(10) @@ -229,6 +286,34 @@ resource keycloak_attribute_importer_identity_provider_mapper oidc { `, realm, alias, name, userAttribute, claimName) } +func testKeycloakAttributeImporterIdentityProviderMapper_withExtraConfig(realm, alias, name, userAttribute, claimName, syncMode string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_oidc_identity_provider" "oidc" { + realm = "${keycloak_realm.realm.id}" + alias = "%s" + authorization_url = "https://example.com/auth" + token_url = "https://example.com/token" + client_id = "example_id" + client_secret = "example_token" +} + +resource keycloak_attribute_importer_identity_provider_mapper oidc { + realm = "${keycloak_realm.realm.id}" + name = "%s" + identity_provider_alias = "${keycloak_oidc_identity_provider.oidc.alias}" + user_attribute = "%s" + claim_name = "%s" + extra_config = { + syncMode = "%s" + } +} + `, realm, alias, name, userAttribute, claimName, syncMode) +} + func testKeycloakAttributeImporterIdentityProviderMapper_basicFromInterface(mapper *keycloak.IdentityProviderMapper) string { return fmt.Sprintf(` resource "keycloak_realm" "realm" { diff --git a/provider/resource_keycloak_attribute_to_role_identity_provider_mapper.go b/provider/resource_keycloak_attribute_to_role_identity_provider_mapper.go index aae47949a..7869bff17 100644 --- a/provider/resource_keycloak_attribute_to_role_identity_provider_mapper.go +++ b/provider/resource_keycloak_attribute_to_role_identity_provider_mapper.go @@ -2,6 +2,7 @@ package provider import ( "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" ) @@ -52,13 +53,20 @@ func resourceKeycloakAttributeToRoleIdentityProviderMapper() *schema.Resource { func getAttributeToRoleIdentityProviderMapperFromData(data *schema.ResourceData, meta interface{}) (*keycloak.IdentityProviderMapper, error) { keycloakClient := meta.(*keycloak.KeycloakClient) rec, _ := getIdentityProviderMapperFromData(data) + extraConfig := map[string]interface{}{} + if v, ok := data.GetOk("extra_config"); ok { + for key, value := range v.(map[string]interface{}) { + extraConfig[key] = value + } + } identityProvider, err := keycloakClient.GetIdentityProvider(rec.Realm, rec.IdentityProviderAlias) if err != nil { return nil, handleNotFoundError(err, data) } rec.IdentityProviderMapper = fmt.Sprintf("%s-role-idp-mapper", identityProvider.ProviderId) rec.Config = &keycloak.IdentityProviderMapperConfig{ - Role: data.Get("role").(string), + Role: data.Get("role").(string), + ExtraConfig: extraConfig, } if identityProvider.ProviderId == "saml" { if attr, ok := data.GetOk("attribute_friendly_name"); ok { @@ -95,5 +103,6 @@ func setAttributeToRoleIdentityProviderMapperData(data *schema.ResourceData, ide data.Set("claim_name", identityProviderMapper.Config.Claim) data.Set("claim_value", identityProviderMapper.Config.ClaimValue) data.Set("attribute_friendly_name", identityProviderMapper.Config.AttributeFriendlyName) + data.Set("extra_config", identityProviderMapper.Config.ExtraConfig) return nil } diff --git a/provider/resource_keycloak_attribute_to_role_identity_provider_mapper_test.go b/provider/resource_keycloak_attribute_to_role_identity_provider_mapper_test.go index 4ec296eea..13316f105 100644 --- a/provider/resource_keycloak_attribute_to_role_identity_provider_mapper_test.go +++ b/provider/resource_keycloak_attribute_to_role_identity_provider_mapper_test.go @@ -2,11 +2,12 @@ package provider import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "testing" ) func TestAccKeycloakAttributeToRoleIdentityProviderMapper_basic(t *testing.T) { @@ -30,6 +31,28 @@ func TestAccKeycloakAttributeToRoleIdentityProviderMapper_basic(t *testing.T) { }) } +func TestAccKeycloakAttributeToRoleIdentityProviderMapper_withExtraConfig(t *testing.T) { + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + role := "terraform-" + acctest.RandString(10) + claimName := "terraform-" + acctest.RandString(10) + claimValue := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakAttributeToRoleIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakAttributeToRoleIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, role, claimName, claimValue, syncMode), + Check: testAccCheckKeycloakAttributeToRoleIdentityProviderMapperExists("keycloak_attribute_to_role_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakAttributeToRoleIdentityProviderMapper_createAfterManualDestroy(t *testing.T) { var mapper = &keycloak.IdentityProviderMapper{} @@ -65,6 +88,42 @@ func TestAccKeycloakAttributeToRoleIdentityProviderMapper_createAfterManualDestr }) } +func TestAccKeycloakAttributeToRoleIdentityProviderMapper_withExtraConfig_createAfterManualDestroy(t *testing.T) { + var mapper = &keycloak.IdentityProviderMapper{} + + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + role := "terraform-" + acctest.RandString(10) + claimName := "terraform-" + acctest.RandString(10) + claimValue := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakAttributeToRoleIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakAttributeToRoleIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, role, claimName, claimValue, syncMode), + Check: testAccCheckKeycloakAttributeToRoleIdentityProviderMapperFetch("keycloak_attribute_to_role_identity_provider_mapper.oidc", mapper), + }, + { + PreConfig: func() { + keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) + + err := keycloakClient.DeleteIdentityProviderMapper(mapper.Realm, mapper.IdentityProviderAlias, mapper.Id) + if err != nil { + t.Fatal(err) + } + }, + Config: testKeycloakAttributeToRoleIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, role, claimName, claimValue, syncMode), + Check: testAccCheckKeycloakAttributeToRoleIdentityProviderMapperExists("keycloak_attribute_to_role_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakAttributeToRoleIdentityProviderMapper_basicUpdateRealm(t *testing.T) { firstRealm := "terraform-" + acctest.RandString(10) secondRealm := "terraform-" + acctest.RandString(10) @@ -235,6 +294,35 @@ resource keycloak_attribute_to_role_identity_provider_mapper oidc { `, realm, alias, name, role, claimName, claimValue) } +func testKeycloakAttributeToRoleIdentityProviderMapper_withExtraConfig(realm, alias, name, role, claimName, claimValue, syncMode string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_oidc_identity_provider" "oidc" { + realm = "${keycloak_realm.realm.id}" + alias = "%s" + authorization_url = "https://example.com/auth" + token_url = "https://example.com/token" + client_id = "example_id" + client_secret = "example_token" +} + +resource keycloak_attribute_to_role_identity_provider_mapper oidc { + realm = "${keycloak_realm.realm.id}" + name = "%s" + identity_provider_alias = "${keycloak_oidc_identity_provider.oidc.alias}" + role = "%s" + claim_name = "%s" + claim_value = "%s" + extra_config = { + syncMode = "%s" + } +} + `, realm, alias, name, role, claimName, claimValue, syncMode) +} + func testKeycloakAttributeToRoleIdentityProviderMapper_basicFromInterface(mapper *keycloak.IdentityProviderMapper) string { return fmt.Sprintf(` resource "keycloak_realm" "realm" { diff --git a/provider/resource_keycloak_generic_client_role_mapper_test.go b/provider/resource_keycloak_generic_client_role_mapper_test.go index f299bb752..5574e245a 100644 --- a/provider/resource_keycloak_generic_client_role_mapper_test.go +++ b/provider/resource_keycloak_generic_client_role_mapper_test.go @@ -28,6 +28,42 @@ func TestGenericRoleMapper_basic(t *testing.T) { }) } +func TestGenericRoleMapper_createAfterManualDestroy(t *testing.T) { + var role = &keycloak.Role{} + var childClient = &keycloak.GenericClient{} + + realmName := "terraform-" + acctest.RandString(10) + parentClientName := "client1-" + acctest.RandString(10) + parentRoleName := "role-" + acctest.RandString(10) + childClientName := "client2-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Steps: []resource.TestStep{ + { + Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName), + Check: resource.ComposeTestCheckFunc( + testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"), + testAccCheckKeycloakRoleFetch("keycloak_role.parent-role", role), + testAccCheckKeycloakGenericClientFetch("keycloak_openid_client.child-client", childClient), + ), + }, + { + PreConfig: func() { + keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) + + err := keycloakClient.DeleteRoleScopeMapping(childClient.RealmId, childClient.Id, "", role) + if err != nil { + t.Fatal(err) + } + }, + Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName), + Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"), + }, + }, + }) +} func TestGenericRoleMapper_import(t *testing.T) { realmName := "terraform-" + acctest.RandString(10) parentClientName := "client1-" + acctest.RandString(10) @@ -98,38 +134,54 @@ func TestGenericRoleMapperClientScope_import(t *testing.T) { }) } -func TestGenericRoleMapper_createAfterManualDestroy(t *testing.T) { +func TestGenericRealmLevelRoleMapperClientScope_basic(t *testing.T) { + realmName := "terraform-" + acctest.RandString(10) + roleName := "role-" + acctest.RandString(10) + clientScopeName := "clientscope-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Steps: []resource.TestStep{ + { + Config: testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName), + Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.clientscope-with-realm-role"), + }, + }, + }) +} + +func TestGenericRealmLevelRoleMapperClientScope_createAfterManualDestroy(t *testing.T) { var role = &keycloak.Role{} - var childClient = &keycloak.GenericClient{} + var clientScope = &keycloak.OpenidClientScope{} realmName := "terraform-" + acctest.RandString(10) - parentClientName := "client1-" + acctest.RandString(10) - parentRoleName := "role-" + acctest.RandString(10) - childClientName := "client2-" + acctest.RandString(10) + roleName := "role-" + acctest.RandString(10) + clientScopeName := "clientscope-" + acctest.RandString(10) resource.Test(t, resource.TestCase{ Providers: testAccProviders, PreCheck: func() { testAccPreCheck(t) }, Steps: []resource.TestStep{ { - Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName), + Config: testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName), Check: resource.ComposeTestCheckFunc( - testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"), - testAccCheckKeycloakRoleFetch("keycloak_role.parent-role", role), - testAccCheckKeycloakGenericClientFetch("keycloak_openid_client.child-client", childClient), + testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.clientscope-with-realm-role"), + testAccCheckKeycloakRoleFetch("keycloak_role.role", role), + testAccCheckKeycloakOpenidClientScopeFetch("keycloak_openid_client_scope.clientscope", clientScope), ), }, { PreConfig: func() { keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) - err := keycloakClient.DeleteRoleScopeMapping(childClient.RealmId, childClient.Id, "", role) + err := keycloakClient.DeleteRoleScopeMapping(clientScope.RealmId, "", clientScope.Id, role) if err != nil { t.Fatal(err) } }, - Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName), - Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"), + Config: testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName), + Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.clientscope-with-realm-role"), }, }, }) @@ -235,6 +287,30 @@ resource "keycloak_generic_client_role_mapper" "clientscope-with-client-role" { `, realmName, clientName, roleName, clientScopeName) } +func testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_role" "role" { + realm_id = "${keycloak_realm.realm.id}" + name = "%s" +} + +resource "keycloak_openid_client_scope" "clientscope" { + realm_id = "${keycloak_realm.realm.id}" + name = "%s" +} + +resource "keycloak_generic_client_role_mapper" "clientscope-with-realm-role" { + realm_id = "${keycloak_realm.realm.id}" + client_scope_id = "${keycloak_openid_client_scope.clientscope.id}" + role_id = "${keycloak_role.role.id}" +} + `, realmName, roleName, clientScopeName) +} + func testAccCheckKeycloakScopeMappingExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { _, ok := s.RootModule().Resources[resourceName] diff --git a/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper.go b/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper.go index ce53310dc..4cf1923a3 100644 --- a/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper.go +++ b/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper.go @@ -2,6 +2,7 @@ package provider import ( "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" ) @@ -35,10 +36,17 @@ func resourceKeycloakHardcodedAttributeIdentityProviderMapper() *schema.Resource func getHardcodedAttributeIdentityProviderMapperFromData(data *schema.ResourceData, _ interface{}) (*keycloak.IdentityProviderMapper, error) { rec, _ := getIdentityProviderMapperFromData(data) + extraConfig := map[string]interface{}{} + if v, ok := data.GetOk("extra_config"); ok { + for key, value := range v.(map[string]interface{}) { + extraConfig[key] = value + } + } rec.IdentityProviderMapper = getHardcodedAttributeIdentityProviderMapperType(data.Get("user_session").(bool)) rec.Config = &keycloak.IdentityProviderMapperConfig{ HardcodedAttribute: data.Get("attribute_name").(string), AttributeValue: data.Get("attribute_value").(string), + ExtraConfig: extraConfig, } return rec, nil } @@ -47,6 +55,7 @@ func setHardcodedAttributeIdentityProviderMapperData(data *schema.ResourceData, setIdentityProviderMapperData(data, identityProviderMapper) data.Set("attribute_name", identityProviderMapper.Config.HardcodedAttribute) data.Set("attribute_value", identityProviderMapper.Config.AttributeValue) + data.Set("extra_config", identityProviderMapper.Config.ExtraConfig) mapperType, err := getUserSessionFromHardcodedAttributeIdentityProviderMapperType(identityProviderMapper.IdentityProviderMapper) if err != nil { return err diff --git a/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper_test.go b/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper_test.go index a6fea52f8..9fe7dd233 100644 --- a/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper_test.go +++ b/provider/resource_keycloak_hardcoded_attribute_identity_provider_mapper_test.go @@ -2,11 +2,12 @@ package provider import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "testing" ) func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basic(t *testing.T) { @@ -30,6 +31,28 @@ func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basic(t *testing.T) }) } +func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_withExtraConfig(t *testing.T) { + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + attributeName := "terraform-" + acctest.RandString(10) + attributeValue := "terraform-" + acctest.RandString(10) + userSession := randomBool() + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakHardcodedAttributeIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakHardcodedAttributeIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, attributeName, attributeValue, userSession, syncMode), + Check: testAccCheckKeycloakHardcodedAttributeIdentityProviderMapperExists("keycloak_hardcoded_attribute_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_createAfterManualDestroy(t *testing.T) { var mapper = &keycloak.IdentityProviderMapper{} @@ -65,6 +88,41 @@ func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_createAfterManualDe }) } +func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_withExtraConfig_createAfterManualDestroy(t *testing.T) { + var mapper = &keycloak.IdentityProviderMapper{} + + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + attributeName := "terraform-" + acctest.RandString(10) + attributeValue := "terraform-" + acctest.RandString(10) + userSession := randomBool() + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakHardcodedAttributeIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakHardcodedAttributeIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, attributeName, attributeValue, userSession, syncMode), + Check: testAccCheckKeycloakHardcodedAttributeIdentityProviderMapperFetch("keycloak_hardcoded_attribute_identity_provider_mapper.oidc", mapper), + }, + { + PreConfig: func() { + keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) + + err := keycloakClient.DeleteIdentityProviderMapper(mapper.Realm, mapper.IdentityProviderAlias, mapper.Id) + if err != nil { + t.Fatal(err) + } + }, + Config: testKeycloakHardcodedAttributeIdentityProviderMapper_basic(realmName, alias, mapperName, attributeName, attributeValue, userSession), + Check: testAccCheckKeycloakHardcodedAttributeIdentityProviderMapperExists("keycloak_hardcoded_attribute_identity_provider_mapper.oidc"), + }, + }, + }) +} func TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basicUpdateRealm(t *testing.T) { firstRealm := "terraform-" + acctest.RandString(10) secondRealm := "terraform-" + acctest.RandString(10) @@ -236,6 +294,35 @@ resource keycloak_hardcoded_attribute_identity_provider_mapper oidc { `, realm, alias, name, attributeName, attributeValue, userSession) } +func testKeycloakHardcodedAttributeIdentityProviderMapper_withExtraConfig(realm, alias, name, attributeName, attributeValue string, userSession bool, syncMode string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_oidc_identity_provider" "oidc" { + realm = "${keycloak_realm.realm.id}" + alias = "%s" + authorization_url = "https://example.com/auth" + token_url = "https://example.com/token" + client_id = "example_id" + client_secret = "example_token" +} + +resource keycloak_hardcoded_attribute_identity_provider_mapper oidc { + realm = "${keycloak_realm.realm.id}" + name = "%s" + identity_provider_alias = "${keycloak_oidc_identity_provider.oidc.alias}" + attribute_name = "%s" + attribute_value = "%s" + user_session = %t + extra_config = { + syncMode = "%s" + } +} + `, realm, alias, name, attributeName, attributeValue, userSession, syncMode) +} + func testKeycloakHardcodedAttributeIdentityProviderMapper_basicFromInterface(mapper *keycloak.IdentityProviderMapper, userSession bool) string { return fmt.Sprintf(` resource "keycloak_realm" "realm" { diff --git a/provider/resource_keycloak_hardcoded_role_identity_provider_mapper.go b/provider/resource_keycloak_hardcoded_role_identity_provider_mapper.go index 85ab5ec8b..a20edc6d6 100644 --- a/provider/resource_keycloak_hardcoded_role_identity_provider_mapper.go +++ b/provider/resource_keycloak_hardcoded_role_identity_provider_mapper.go @@ -23,9 +23,16 @@ func resourceKeycloakHardcodedRoleIdentityProviderMapper() *schema.Resource { func getHardcodedRoleIdentityProviderMapperFromData(data *schema.ResourceData, _ interface{}) (*keycloak.IdentityProviderMapper, error) { rec, _ := getIdentityProviderMapperFromData(data) + extraConfig := map[string]interface{}{} + if v, ok := data.GetOk("extra_config"); ok { + for key, value := range v.(map[string]interface{}) { + extraConfig[key] = value + } + } rec.IdentityProviderMapper = "oidc-hardcoded-role-idp-mapper" rec.Config = &keycloak.IdentityProviderMapperConfig{ - Role: data.Get("role").(string), + Role: data.Get("role").(string), + ExtraConfig: extraConfig, } return rec, nil } @@ -33,5 +40,6 @@ func getHardcodedRoleIdentityProviderMapperFromData(data *schema.ResourceData, _ func setHardcodedRoleIdentityProviderMapperData(data *schema.ResourceData, identityProviderMapper *keycloak.IdentityProviderMapper) error { setIdentityProviderMapperData(data, identityProviderMapper) data.Set("role", identityProviderMapper.Config.Role) + data.Set("extra_config", identityProviderMapper.Config.ExtraConfig) return nil } diff --git a/provider/resource_keycloak_hardcoded_role_identity_provider_mapper_test.go b/provider/resource_keycloak_hardcoded_role_identity_provider_mapper_test.go index 75f5893ab..bf2e1bdd9 100644 --- a/provider/resource_keycloak_hardcoded_role_identity_provider_mapper_test.go +++ b/provider/resource_keycloak_hardcoded_role_identity_provider_mapper_test.go @@ -2,11 +2,12 @@ package provider import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "testing" ) func TestAccKeycloakHardcodedRoleIdentityProviderMapper_basic(t *testing.T) { @@ -28,6 +29,26 @@ func TestAccKeycloakHardcodedRoleIdentityProviderMapper_basic(t *testing.T) { }) } +func TestAccKeycloakHardcodedRoleIdentityProviderMapper_withExtraConfig(t *testing.T) { + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + role := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakHardcodedRoleIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakHardcodedRoleIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, role, syncMode), + Check: testAccCheckKeycloakHardcodedRoleIdentityProviderMapperExists("keycloak_hardcoded_role_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakHardcodedRoleIdentityProviderMapper_createAfterManualDestroy(t *testing.T) { var mapper = &keycloak.IdentityProviderMapper{} @@ -61,6 +82,40 @@ func TestAccKeycloakHardcodedRoleIdentityProviderMapper_createAfterManualDestroy }) } +func TestAccKeycloakHardcodedRoleIdentityProviderMapper_withExtraConfig_createAfterManualDestroy(t *testing.T) { + var mapper = &keycloak.IdentityProviderMapper{} + + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + role := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakHardcodedRoleIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakHardcodedRoleIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, role, syncMode), + Check: testAccCheckKeycloakHardcodedRoleIdentityProviderMapperFetch("keycloak_hardcoded_role_identity_provider_mapper.oidc", mapper), + }, + { + PreConfig: func() { + keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) + + err := keycloakClient.DeleteIdentityProviderMapper(mapper.Realm, mapper.IdentityProviderAlias, mapper.Id) + if err != nil { + t.Fatal(err) + } + }, + Config: testKeycloakHardcodedRoleIdentityProviderMapper_basic(realmName, alias, mapperName, role), + Check: testAccCheckKeycloakHardcodedRoleIdentityProviderMapperExists("keycloak_hardcoded_role_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakHardcodedRoleIdentityProviderMapper_basicUpdateRealm(t *testing.T) { firstRealm := "terraform-" + acctest.RandString(10) secondRealm := "terraform-" + acctest.RandString(10) @@ -223,6 +278,33 @@ resource keycloak_hardcoded_role_identity_provider_mapper oidc { `, realm, alias, name, role) } +func testKeycloakHardcodedRoleIdentityProviderMapper_withExtraConfig(realm, alias, name, role, syncMode string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_oidc_identity_provider" "oidc" { + realm = "${keycloak_realm.realm.id}" + alias = "%s" + authorization_url = "https://example.com/auth" + token_url = "https://example.com/token" + client_id = "example_id" + client_secret = "example_token" +} + +resource keycloak_hardcoded_role_identity_provider_mapper oidc { + realm = "${keycloak_realm.realm.id}" + name = "%s" + identity_provider_alias = "${keycloak_oidc_identity_provider.oidc.alias}" + role = "%s" + extra_config = { + syncMode = "%s" + } +} + `, realm, alias, name, role, syncMode) +} + func testKeycloakHardcodedRoleIdentityProviderMapper_basicFromInterface(mapper *keycloak.IdentityProviderMapper) string { return fmt.Sprintf(` resource "keycloak_realm" "realm" { diff --git a/provider/resource_keycloak_user_template_importer_identity_provider_mapper.go b/provider/resource_keycloak_user_template_importer_identity_provider_mapper.go index bf1504df0..047624309 100644 --- a/provider/resource_keycloak_user_template_importer_identity_provider_mapper.go +++ b/provider/resource_keycloak_user_template_importer_identity_provider_mapper.go @@ -2,6 +2,7 @@ package provider import ( "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" ) @@ -25,13 +26,20 @@ func resourceKeycloakUserTemplateImporterIdentityProviderMapper() *schema.Resour func getUserTemplateImporterIdentityProviderMapperFromData(data *schema.ResourceData, meta interface{}) (*keycloak.IdentityProviderMapper, error) { keycloakClient := meta.(*keycloak.KeycloakClient) rec, _ := getIdentityProviderMapperFromData(data) + extraConfig := map[string]interface{}{} + if v, ok := data.GetOk("extra_config"); ok { + for key, value := range v.(map[string]interface{}) { + extraConfig[key] = value + } + } identityProvider, err := keycloakClient.GetIdentityProvider(rec.Realm, rec.IdentityProviderAlias) if err != nil { return nil, handleNotFoundError(err, data) } rec.IdentityProviderMapper = fmt.Sprintf("%s-username-idp-mapper", identityProvider.ProviderId) rec.Config = &keycloak.IdentityProviderMapperConfig{ - Template: data.Get("template").(string), + Template: data.Get("template").(string), + ExtraConfig: extraConfig, } return rec, nil } @@ -39,5 +47,6 @@ func getUserTemplateImporterIdentityProviderMapperFromData(data *schema.Resource func setUserTemplateImporterIdentityProviderMapperData(data *schema.ResourceData, identityProviderMapper *keycloak.IdentityProviderMapper) error { setIdentityProviderMapperData(data, identityProviderMapper) data.Set("template", identityProviderMapper.Config.Template) + data.Set("extra_config", identityProviderMapper.Config.ExtraConfig) return nil } diff --git a/provider/resource_keycloak_user_template_importer_identity_provider_mapper_test.go b/provider/resource_keycloak_user_template_importer_identity_provider_mapper_test.go index 0506894d9..386505ffa 100644 --- a/provider/resource_keycloak_user_template_importer_identity_provider_mapper_test.go +++ b/provider/resource_keycloak_user_template_importer_identity_provider_mapper_test.go @@ -2,11 +2,12 @@ package provider import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "testing" ) func TestAccKeycloakUserTemplateIdentityProviderMapper_basic(t *testing.T) { @@ -28,6 +29,26 @@ func TestAccKeycloakUserTemplateIdentityProviderMapper_basic(t *testing.T) { }) } +func TestAccKeycloakUserTemplateIdentityProviderMapper_withExtraConfig(t *testing.T) { + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + template := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakUserTemplateIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakUserTemplateIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, template, syncMode), + Check: testAccCheckKeycloakUserTemplateIdentityProviderMapperExists("keycloak_user_template_importer_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakUserTemplateIdentityProviderMapper_createAfterManualDestroy(t *testing.T) { var mapper = &keycloak.IdentityProviderMapper{} @@ -61,6 +82,40 @@ func TestAccKeycloakUserTemplateIdentityProviderMapper_createAfterManualDestroy( }) } +func TestAccKeycloakUserTemplateIdentityProviderMapper_withExtraConfig_createAfterManualDestroy(t *testing.T) { + var mapper = &keycloak.IdentityProviderMapper{} + + realmName := "terraform-" + acctest.RandString(10) + mapperName := "terraform-" + acctest.RandString(10) + alias := "terraform-" + acctest.RandString(10) + template := "terraform-" + acctest.RandString(10) + syncMode := "terraform-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckKeycloakUserTemplateIdentityProviderMapperDestroy(), + Steps: []resource.TestStep{ + { + Config: testKeycloakUserTemplateIdentityProviderMapper_withExtraConfig(realmName, alias, mapperName, template, syncMode), + Check: testAccCheckKeycloakUserTemplateIdentityProviderMapperFetch("keycloak_user_template_importer_identity_provider_mapper.oidc", mapper), + }, + { + PreConfig: func() { + keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient) + + err := keycloakClient.DeleteIdentityProviderMapper(mapper.Realm, mapper.IdentityProviderAlias, mapper.Id) + if err != nil { + t.Fatal(err) + } + }, + Config: testKeycloakUserTemplateIdentityProviderMapper_basic(realmName, alias, mapperName, template), + Check: testAccCheckKeycloakUserTemplateIdentityProviderMapperExists("keycloak_user_template_importer_identity_provider_mapper.oidc"), + }, + }, + }) +} + func TestAccKeycloakUserTemplateIdentityProviderMapper_basicUpdateRealm(t *testing.T) { firstRealm := "terraform-" + acctest.RandString(10) secondRealm := "terraform-" + acctest.RandString(10) @@ -223,6 +278,33 @@ resource keycloak_user_template_importer_identity_provider_mapper oidc { `, realm, alias, name, template) } +func testKeycloakUserTemplateIdentityProviderMapper_withExtraConfig(realm, alias, name, template, syncMode string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_oidc_identity_provider" "oidc" { + realm = "${keycloak_realm.realm.id}" + alias = "%s" + authorization_url = "https://example.com/auth" + token_url = "https://example.com/token" + client_id = "example_id" + client_secret = "example_token" +} + +resource keycloak_user_template_importer_identity_provider_mapper oidc { + realm = "${keycloak_realm.realm.id}" + name = "%s" + identity_provider_alias = "${keycloak_oidc_identity_provider.oidc.alias}" + template = "%s" + extra_config = { + syncMode = "%s" + } +} + `, realm, alias, name, template, syncMode) +} + func testKeycloakUserTemplateIdentityProviderMapper_basicFromInterface(mapper *keycloak.IdentityProviderMapper) string { return fmt.Sprintf(` resource "keycloak_realm" "realm" {