terraform-provider-keycloak icon indicating copy to clipboard operation
terraform-provider-keycloak copied to clipboard

[Feature] Add support for User Profile

Open acolombier opened this issue 3 years ago • 4 comments

Feature request

Starting from version 15, Keycloak has now support for custom user profile.

I was wondering if there was any plan to get this feature available soon? Here is an example of implementation (note that the feature can already be enabled in the realm using attributes)

Option 1 - Single block which defines every attributes

resource keycloak_realm myrealm {
    ...
    user_profile {
        field {
            name = "field"
            display_name = "Field"
            group = "group"

            roles {
                "user"
            }

            scopes {
                "openid"
            }

            permissions {
                view = ["admin", "user"]
                edit = ["admin", "user"]
            }

            validations {
                length {
                    max = 255
                }
                
                person_name_prohibited_characters {}

                pattern {
                    pattern = "^[a-z]+$"
                    error_message = "Nope"
                }
            }
        }
        group {
            name = "group"
            display_name = "Group"
            description = "A group"
            
        }
    }
}

Pros: Easy to implement, order is explicit Cons: Quickly growing realm resource, must specify every field (cannot reuse default one)

Option 2 - Resources for attributes and group

data keycloak_realm_user_profile_attribute a_field {
    name = "email"
}

resource keycloak_realm_user_profile_attribute an_other_field {
    name = "field"
    display_name = "field"
    group = "group"

    roles {
        "user"
    }

    scopes {
        "openid"
    }

    permissions {
        view = ["admin", "user"]
        edit = ["admin", "user"]
    }

    validations {
        length {
            max = 255
        }
        
        person_name_prohibited_characters {}

        pattern {
            pattern = "^[a-z]+$"
            error_message = "Nope"
        }
    }

    depends_on = [
        data.keycloak_realm_user_profile_attribute.a_field
    ]
}

data keycloak_realm_user_profile_group a_group {
    name = "group_one"
}

resource keycloak_realm_user_profile_group an_other_group {
    name = "group"
    display_name = "Group"
    description = "A group"

    depends_on = [
        data.keycloak_realm_user_profile_group.a_group
    ]
}

Pros: Clean split, can reuse existing config Cons: Harder to implement


In case there is no existing plan, and you happy with either of my options, I would be happy to try and submit a PR in the coming days! :rocket:

acolombier avatar Jan 06 '22 10:01 acolombier

Hi, I needed that too, see #658

maximepiton avatar Feb 21 '22 15:02 maximepiton

@maximepiton @mrparkers I think this issue is resolved (🙏 thanks to #658 indeed) and can be closed. Doc. ref. https://registry.terraform.io/providers/mrparkers/keycloak/latest/docs/resources/realm_user_profile

Or are we missing something here ? cc @acolombier

MrBuBBLs avatar Jun 29 '22 13:06 MrBuBBLs

Hi dear @acolombier,

Thanks for the issue since I was seriously looking for a place to ask these question about keycloak_realm_user_profile resource. First I quote your first message:

Cons: Quickly growing realm resource, must specify every field (cannot reuse default one)

Questions

Q1

Cannot we just define extra fields/attributes and tell keycloak to add our custom attributes to the existing ones when we have a terrafrom code like this and a keycloak instance.

Q2

Why my keycloak won't show me the custom attributes as i defined them? You can take a look at this.

I truly appreciate any kind of help.

kasir-barati avatar Apr 01 '23 23:04 kasir-barati

I found the answer with a bit of patience and reading the doc. Of course google was not useful at all even for showing me the official documentation. I used lovely Tor to find it. BTW here is what I understood and what I did regarding testing it and making sure that it is the way I should do it:

Information

When you create an attribute, no permission is set to the attribute. Effectively, the attribute won’t be accessible by either users or administrators. Once you create the attribute, make sure to set the permissions accordingly to that the attribute is only visible by the target audience. (Ref)

What I did

  1. I activate the user profile and allow registration
  2. I created a new attribute with a name, display name, and required always for anyone
  3. I checked registration page, the newly created attribute was not there
  4. I set the permission for edit and view for both admin and user
  5. I checked the registration page and it was there

Here is my final terraform code:

resource "keycloak_realm_user_profile" "you-say-user-profile" {
  realm_id = keycloak_realm.you-say-realm.id

  attribute {
    name         = "firstName"
    display_name = "$${firstName}"

    permissions {
      view = ["admin", "user"]
      edit = ["admin", "user"]
    }

    validator {
      name   = "person-name-prohibited-characters"
      config = {}
    }
    validator {
      name = "length"
      config = {
        "min" : 2,
        "max" : 255
      }
    }
  }

  attribute {
    name         = "lastName"
    display_name = "$${lastName}"

    permissions {
      view = ["admin", "user"]
      edit = ["admin", "user"]
    }

    validator {
      name   = "person-name-prohibited-characters"
      config = {}
    }
    validator {
      name = "length"
      config = {
        "min" : 2,
        "max" : 255
      }
    }
  }

  attribute {
    name         = "occupation"
    display_name = "$${occupation}"

    permissions {
      view = ["admin", "user"]
      edit = ["admin", "user"]
    }

    validator {
      name = "pattern"
      config = {
        pattern       = "^[a-zA-Z0-9_][a-zA-Z0-9_ ]*[a-zA-Z0-9_]$"
        error-message = "Please use only characters and space between words, And do not start or end your occupation with white space"
      }
    }
  }

  attribute {
    name         = "location"
    display_name = "$${location}"
    validator {
      name = "pattern"
      config = {
        pattern       = "^[a-zA-Z\u0080-\u024F]+(?:. |-| |')*([1-9a-zA-Z\u0080-\u024F]+(?:. |-| |'))*[a-zA-Z\u0080-\u024F]*$"
        error-message = "Please enter a valid city name followed by the country name. e.x. Tokyo, Japan"
      }
    }
  }
}

More info in my you-say repo

kasir-barati avatar Apr 02 '23 13:04 kasir-barati