From 3ba94566289711f4351146e5e5dda67d24f0c3ec Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 13 Jan 2025 22:55:25 +0100 Subject: [PATCH] fix: allow definition of multivalued user profile attributes In order to replicate the existing userprofile configuration, we need to support the multivalued attribute. We now support the `multi_valued = bool` attribute. Example: ```hcl attribute { name = "myAttr" multi_valued = true validator { name = "options" config = { options = jsonencode(["opt1", "opt2", "opt3"]) } } annotations = { foo = jsonencode({ "key" : "val" }) } } ``` Fixes #1064 Signed-off-by: Thomas Darimont --- docs/resources/realm_user_profile.md | 2 ++ keycloak/realm_user_profile.go | 1 + provider/resource_keycloak_realm_user_profile.go | 13 +++++++++++++ .../resource_keycloak_realm_user_profile_test.go | 1 + 4 files changed, 17 insertions(+) diff --git a/docs/resources/realm_user_profile.md b/docs/resources/realm_user_profile.md index 956bc55b..26a8aec8 100644 --- a/docs/resources/realm_user_profile.md +++ b/docs/resources/realm_user_profile.md @@ -28,6 +28,7 @@ resource "keycloak_realm_user_profile" "userprofile" { display_name = "Field 1" group = "group1" + multi_valued = false enabled_when_scope = ["offline_access"] required_for_roles = ["user"] @@ -98,6 +99,7 @@ resource "keycloak_realm_user_profile" "userprofile" { - `name` - (Required) The name of the attribute. - `display_name` - (Optional) The display name of the attribute. +- `multi_valued` - (Optional) If the attribute supports multiple values. Defaults to `false`. - `group` - (Optional) The group that the attribute belong to. - `enabled_when_scope` - (Optional) A list of scopes. The attribute will only be enabled when these scopes are requested by clients. - `required_for_roles` - (Optional) A list of roles for which the attribute will be required. diff --git a/keycloak/realm_user_profile.go b/keycloak/realm_user_profile.go index 55a8e3ee..582ef2b0 100644 --- a/keycloak/realm_user_profile.go +++ b/keycloak/realm_user_profile.go @@ -27,6 +27,7 @@ type RealmUserProfileAttribute struct { DisplayName string `json:"displayName,omitempty"` Group string `json:"group,omitempty"` Name string `json:"name"` + MultiValued bool `json:"multivalued,omitempty"` Permissions *RealmUserProfilePermissions `json:"permissions,omitempty"` Required *RealmUserProfileRequired `json:"required,omitempty"` Selector *RealmUserProfileSelector `json:"selector,omitempty"` diff --git a/provider/resource_keycloak_realm_user_profile.go b/provider/resource_keycloak_realm_user_profile.go index e121f3ae..cd863d34 100644 --- a/provider/resource_keycloak_realm_user_profile.go +++ b/provider/resource_keycloak_realm_user_profile.go @@ -46,6 +46,11 @@ func resourceKeycloakRealmUserProfile() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "multi_valued": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "group": { Type: schema.TypeString, Optional: true, @@ -153,6 +158,12 @@ func getRealmUserProfileAttributeFromData(m map[string]interface{}) *keycloak.Re Group: m["group"].(string), } + if v, ok := m["multivalued"].(bool); ok { + attribute.MultiValued = v + } else { + attribute.MultiValued = false + } + if v, ok := m["permissions"]; ok && len(v.([]interface{})) > 0 { permissions := keycloak.RealmUserProfilePermissions{ Edit: make([]string, 0), @@ -329,6 +340,8 @@ func getRealmUserProfileAttributeData(attr *keycloak.RealmUserProfileAttribute) attributeData["name"] = attr.Name attributeData["display_name"] = attr.DisplayName + attributeData["multi_valued"] = attr.MultiValued + attributeData["group"] = attr.Group if attr.Selector != nil && len(attr.Selector.Scopes) != 0 { attributeData["enabled_when_scope"] = attr.Selector.Scopes diff --git a/provider/resource_keycloak_realm_user_profile_test.go b/provider/resource_keycloak_realm_user_profile_test.go index 7c18d3dd..06257d51 100644 --- a/provider/resource_keycloak_realm_user_profile_test.go +++ b/provider/resource_keycloak_realm_user_profile_test.go @@ -106,6 +106,7 @@ func TestAccKeycloakRealmUserProfile_basicFull(t *testing.T) { { Name: "attribute2", DisplayName: "attribute 2", + MultiValued: false, Group: "group", Selector: &keycloak.RealmUserProfileSelector{Scopes: []string{"roles"}}, Required: &keycloak.RealmUserProfileRequired{