From d78f0bef565f0be04c87f1c6c7fa0e91cfdda705 Mon Sep 17 00:00:00 2001 From: Stephan Scheying Date: Thu, 10 Aug 2023 17:15:54 +0200 Subject: [PATCH] feat: Add required_actions attribute to keycloak_user --- docs/resources/user.md | 1 + keycloak/user.go | 20 ++++++++++--------- ...loak_openid_client_service_account_user.go | 6 ++++++ provider/data_source_keycloak_user.go | 6 ++++++ provider/resource_keycloak_user.go | 17 +++++++++++++++- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/docs/resources/user.md b/docs/resources/user.md index de5da2a56..a5601cb0d 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -62,6 +62,7 @@ resource "keycloak_user" "user_with_initial_password" { - `first_name` - (Optional) The user's first name. - `last_name` - (Optional) The user's last name. - `attributes` - (Optional) A map representing attributes for the user. In order to add multivalue attributes, use `##` to seperate the values. Max length for each value is 255 chars +- `required_actions` - (Optional) A list of required user actions. - `federated_identity` - (Optional) When specified, the user will be linked to a federated identity provider. Refer to the [federated user example](https://github.com/mrparkers/terraform-provider-keycloak/blob/master/example/federated_user_example.tf) for more details. - `identity_provider` - (Required) The name of the identity provider - `user_id` - (Required) The ID of the user defined in the identity provider diff --git a/keycloak/user.go b/keycloak/user.go index 021a40d59..434bd5c2f 100644 --- a/keycloak/user.go +++ b/keycloak/user.go @@ -25,6 +25,7 @@ type User struct { Enabled bool `json:"enabled"` Attributes map[string][]string `json:"attributes"` FederatedIdentities FederatedIdentities `json:"federatedIdentities"` + RequiredActions []string `json:"requiredActions"` } type PasswordCredentials struct { @@ -35,15 +36,16 @@ type PasswordCredentials struct { func (keycloakClient *KeycloakClient) NewUser(ctx context.Context, user *User) error { newUser := User{ - Id: user.Id, - RealmId: user.RealmId, - Username: user.Username, - Email: user.Email, - EmailVerified: user.EmailVerified, - FirstName: user.FirstName, - LastName: user.LastName, - Enabled: user.Enabled, - Attributes: user.Attributes, + Id: user.Id, + RealmId: user.RealmId, + Username: user.Username, + Email: user.Email, + EmailVerified: user.EmailVerified, + FirstName: user.FirstName, + LastName: user.LastName, + Enabled: user.Enabled, + Attributes: user.Attributes, + RequiredActions: user.RequiredActions, } _, location, err := keycloakClient.post(ctx, fmt.Sprintf("/realms/%s/users", user.RealmId), newUser) if err != nil { diff --git a/provider/data_source_keycloak_openid_client_service_account_user.go b/provider/data_source_keycloak_openid_client_service_account_user.go index a4ba204a1..35fa3c2a3 100644 --- a/provider/data_source_keycloak_openid_client_service_account_user.go +++ b/provider/data_source_keycloak_openid_client_service_account_user.go @@ -2,6 +2,7 @@ package provider import ( "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" @@ -47,6 +48,11 @@ func dataSourceKeycloakOpenidClientServiceAccountUser() *schema.Resource { Type: schema.TypeMap, Computed: true, }, + "required_actions": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, "federated_identity": { Type: schema.TypeList, Computed: true, diff --git a/provider/data_source_keycloak_user.go b/provider/data_source_keycloak_user.go index 8c081adba..7e9f4884d 100644 --- a/provider/data_source_keycloak_user.go +++ b/provider/data_source_keycloak_user.go @@ -2,6 +2,7 @@ package provider import ( "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" @@ -39,6 +40,11 @@ func dataSourceKeycloakUser() *schema.Resource { Type: schema.TypeMap, Computed: true, }, + "required_actions": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, "federated_identity": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, diff --git a/provider/resource_keycloak_user.go b/provider/resource_keycloak_user.go index 90790c674..da04cd264 100644 --- a/provider/resource_keycloak_user.go +++ b/provider/resource_keycloak_user.go @@ -4,10 +4,11 @@ import ( "context" "errors" "fmt" + "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "strings" ) const MULTIVALUE_ATTRIBUTE_SEPARATOR = "##" @@ -63,6 +64,11 @@ func resourceKeycloakUser() *schema.Resource { Type: schema.TypeMap, Optional: true, }, + "required_actions": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + }, "federated_identity": { Type: schema.TypeSet, Optional: true, @@ -118,6 +124,13 @@ func onlyDiffOnCreate(_, _, _ string, d *schema.ResourceData) bool { func mapFromDataToUser(data *schema.ResourceData) *keycloak.User { attributes := map[string][]string{} + var requiredActions []string + + if v, ok := data.GetOk("required_actions"); ok { + for _, requiredAction := range v.(*schema.Set).List() { + requiredActions = append(requiredActions, requiredAction.(string)) + } + } if v, ok := data.GetOk("attributes"); ok { for key, value := range v.(map[string]interface{}) { attributes[key] = strings.Split(value.(string), MULTIVALUE_ATTRIBUTE_SEPARATOR) @@ -141,6 +154,7 @@ func mapFromDataToUser(data *schema.ResourceData) *keycloak.User { Enabled: data.Get("enabled").(bool), Attributes: attributes, FederatedIdentities: *federatedIdentities, + RequiredActions: requiredActions, } } @@ -182,6 +196,7 @@ func mapFromUserToData(data *schema.ResourceData, user *keycloak.User) { data.Set("enabled", user.Enabled) data.Set("attributes", attributes) data.Set("federated_identity", federatedIdentities) + data.Set("required_actions", user.RequiredActions) } func resourceKeycloakUserCreate(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {