Skip to content

Commit

Permalink
refactor UI customization settings; add test coverage and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
anGie44 committed Feb 25, 2021
1 parent 658eb93 commit dc397fb
Show file tree
Hide file tree
Showing 12 changed files with 1,033 additions and 966 deletions.
8 changes: 2 additions & 6 deletions .changelog/8114.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
```release-note:enhancement
resource/aws_cognito_user_pool: Add `ui_customization` argument
```

```release-note:enhancement
resource/aws_cognito_user_pool_client: Add `ui_customization` argument
```release-note:new-resource
aws_cognito_user_pool_ui_customization
```
13 changes: 5 additions & 8 deletions aws/internal/service/cognitoidentityprovider/finder/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ package finder
import (
"reflect"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
)

// CognitoUserPoolUICustomization returns the UI Customization corresponding to the UserPoolId and ClientId, if provided.
// CognitoUserPoolUICustomization returns the UI Customization corresponding to the UserPoolId and ClientId.
// Returns nil if no UI Customization is found.
func CognitoUserPoolUICustomization(conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolId, clientId *string) (*cognitoidentityprovider.UICustomizationType, error) {
func CognitoUserPoolUICustomization(conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolId, clientId string) (*cognitoidentityprovider.UICustomizationType, error) {
input := &cognitoidentityprovider.GetUICustomizationInput{
UserPoolId: userPoolId,
}

if clientId != nil {
input.ClientId = clientId
ClientId: aws.String(clientId),
UserPoolId: aws.String(userPoolId),
}

output, err := conn.GetUICustomization(input)
Expand All @@ -29,7 +27,6 @@ func CognitoUserPoolUICustomization(conn *cognitoidentityprovider.CognitoIdentit

// The GetUICustomization API operation will return an empty struct
// if nothing is present rather than nil or an error, so we equate that with nil
// to prevent non-empty plans of an empty ui_customization block
if reflect.DeepEqual(output.UICustomization, &cognitoidentityprovider.UICustomizationType{}) {
return nil, nil
}
Expand Down
3 changes: 2 additions & 1 deletion aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,13 +519,14 @@ func Provider() *schema.Provider {
"aws_cognito_identity_pool": resourceAwsCognitoIdentityPool(),
"aws_cognito_identity_pool_roles_attachment": resourceAwsCognitoIdentityPoolRolesAttachment(),
"aws_cognito_identity_provider": resourceAwsCognitoIdentityProvider(),
"aws_cognito_resource_server": resourceAwsCognitoResourceServer(),
"aws_cognito_user_group": resourceAwsCognitoUserGroup(),
"aws_cognito_user_pool": resourceAwsCognitoUserPool(),
"aws_cognito_user_pool_client": resourceAwsCognitoUserPoolClient(),
"aws_cognito_user_pool_domain": resourceAwsCognitoUserPoolDomain(),
"aws_cognito_user_pool_ui_customization": resourceAwsCognitoUserPoolUICustomization(),
"aws_cloudhsm_v2_cluster": resourceAwsCloudHsmV2Cluster(),
"aws_cloudhsm_v2_hsm": resourceAwsCloudHsmV2Hsm(),
"aws_cognito_resource_server": resourceAwsCognitoResourceServer(),
"aws_cloudwatch_composite_alarm": resourceAwsCloudWatchCompositeAlarm(),
"aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(),
"aws_cloudwatch_dashboard": resourceAwsCloudWatchDashboard(),
Expand Down
132 changes: 0 additions & 132 deletions aws/resource_aws_cognito_user_pool.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package aws

import (
"context"
"encoding/base64"
"fmt"
"log"
"regexp"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cognitoidentityprovider/finder"
)

func resourceAwsCognitoUserPool() *schema.Resource {
Expand Down Expand Up @@ -567,41 +562,7 @@ func resourceAwsCognitoUserPool() *schema.Resource {
},
},
},

"ui_customization": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"css": {
Type: schema.TypeString,
Optional: true,
},
"css_version": {
Type: schema.TypeString,
Computed: true,
},
"image_file": {
Type: schema.TypeString,
Optional: true,
},
"image_url": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},

CustomizeDiff: customdiff.Sequence(
// A "ui_customization" cannot be removed from a Cognito User Pool resource;
// thus, resource recreation is triggered on configuration block removal
customdiff.ForceNewIfChange("ui_customization", func(_ context.Context, old, new, meta interface{}) bool {
return len(old.([]interface{})) == 1 && len(new.([]interface{})) == 0
}),
),
}
}

Expand Down Expand Up @@ -973,25 +934,6 @@ func resourceAwsCognitoUserPoolRead(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("error setting software_token_mfa_configuration: %w", err)
}

// Retrieve UICustomization iff the User Pool is associated with a Domain
if resp.UserPool.Domain != nil {
uiCustomization, err := finder.CognitoUserPoolUICustomization(conn, resp.UserPool.Id, nil)

if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) {
log.Printf("[WARN] Cognito User Pool (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error getting Cognito User Pool (%s) UI customization: %w", d.Id(), err)
}

if err := d.Set("ui_customization", flattenCognitoUserPoolUICustomization(d, uiCustomization)); err != nil {
return fmt.Errorf("error setting ui_customization: %w", err)
}
}

return nil
}

Expand Down Expand Up @@ -1252,26 +1194,6 @@ func resourceAwsCognitoUserPoolUpdate(d *schema.ResourceData, meta interface{})
}
}

if d.HasChange("ui_customization") {
if v, ok := d.GetOk("ui_customization"); ok {
input, err := expandCognitoUserPoolUICustomizationInput(v.([]interface{}))

if err != nil {
return fmt.Errorf("error updating Cognito User pool (%s) UI customization: %w", d.Id(), err)
}

if input != nil {
input.UserPoolId = aws.String(d.Id())

_, err := conn.SetUICustomization(input)

if err != nil {
return fmt.Errorf("error updating Cognito User pool (%s) UI customization: %w", d.Id(), err)
}
}
}
}

return resourceAwsCognitoUserPoolRead(d, meta)
}

Expand Down Expand Up @@ -1390,33 +1312,6 @@ func expandCognitoUserPoolAccountRecoverySettingConfig(config map[string]interfa
return configs
}

func expandCognitoUserPoolUICustomizationInput(l []interface{}) (*cognitoidentityprovider.SetUICustomizationInput, error) {
if len(l) == 0 || l[0] == nil {
return nil, nil
}

tfMap, ok := l[0].(map[string]interface{})
if !ok {
return nil, nil
}

input := &cognitoidentityprovider.SetUICustomizationInput{}

if v, ok := tfMap["css"].(string); ok && v != "" {
input.CSS = aws.String(v)
}

if v, ok := tfMap["image_file"].(string); ok && v != "" {
imgFile, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil, err
}
input.ImageFile = imgFile
}

return input, nil
}

func flattenCognitoUserPoolAccountRecoverySettingConfig(config *cognitoidentityprovider.AccountRecoverySettingType) []interface{} {
if config == nil {
return nil
Expand All @@ -1438,30 +1333,3 @@ func flattenCognitoUserPoolAccountRecoverySettingConfig(config *cognitoidentityp

return []interface{}{settings}
}

func flattenCognitoUserPoolUICustomization(d *schema.ResourceData, ui *cognitoidentityprovider.UICustomizationType) []interface{} {
if ui == nil {
return nil
}

m := map[string]interface{}{
"css": aws.StringValue(ui.CSS),
"css_version": aws.StringValue(ui.CSSVersion),
"image_url": aws.StringValue(ui.ImageUrl),
}

if ui.ImageUrl != nil {
// repopulate image_file content from state, if available,
// else, the value will be overwritten
if v, ok := d.GetOk("ui_customization"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
tfMap, ok := v.([]interface{})[0].(map[string]interface{})
if ok {
if imgFile, ok := tfMap["image_file"].(string); ok {
m["image_file"] = imgFile
}
}
}
}

return []interface{}{m}
}
101 changes: 0 additions & 101 deletions aws/resource_aws_cognito_user_pool_client.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package aws

import (
"context"
"fmt"
"log"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cognitoidentityprovider/finder"
)

func resourceAwsCognitoUserPoolClient() *schema.Resource {
Expand Down Expand Up @@ -149,7 +145,6 @@ func resourceAwsCognitoUserPoolClient() *schema.Resource {
Type: schema.TypeString,
},
},

"analytics_configuration": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -188,41 +183,7 @@ func resourceAwsCognitoUserPoolClient() *schema.Resource {
},
},
},

"ui_customization": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"css": {
Type: schema.TypeString,
Optional: true,
},
"css_version": {
Type: schema.TypeString,
Computed: true,
},
"image_file": {
Type: schema.TypeString,
Optional: true,
},
"image_url": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},

CustomizeDiff: customdiff.Sequence(
// A "ui_customization" cannot be removed from a Cognito User Pool Client resource;
// thus, resource recreation is triggered on configuration block removal.
customdiff.ForceNewIfChange("ui_customization", func(_ context.Context, old, new, meta interface{}) bool {
return len(old.([]interface{})) == 1 && len(new.([]interface{})) == 0
}),
),
}
}

Expand Down Expand Up @@ -300,25 +261,6 @@ func resourceAwsCognitoUserPoolClientCreate(d *schema.ResourceData, meta interfa

d.SetId(aws.StringValue(resp.UserPoolClient.ClientId))

if v, ok := d.GetOk("ui_customization"); ok {
input, err := expandCognitoUserPoolUICustomizationInput(v.([]interface{}))

if err != nil {
return fmt.Errorf("error setting Cognito User Pool Client (%s) UI customization: %w", d.Id(), err)
}

if input != nil {
input.ClientId = aws.String(d.Id())
input.UserPoolId = aws.String(d.Get("user_pool_id").(string))

_, err := conn.SetUICustomization(input)

if err != nil {
return fmt.Errorf("error setting Cognito User Pool Client (%s) UI customization: %w", d.Id(), err)
}
}
}

return resourceAwsCognitoUserPoolClientRead(d, meta)
}

Expand Down Expand Up @@ -364,28 +306,6 @@ func resourceAwsCognitoUserPoolClientRead(d *schema.ResourceData, meta interface
return fmt.Errorf("error setting analytics_configuration: %s", err)
}

// Retrieve UICustomization of the User Pool the Client belongs to;
// expect to receive an InvalidParameterException if there is no associated Domain
uiCustomization, err := finder.CognitoUserPoolUICustomization(conn, resp.UserPoolClient.UserPoolId, aws.String(d.Id()))

if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) {
log.Printf("[WARN] Cognito User Pool Client (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidParameterException, "There has to be an existing domain associated with this user pool") {
return nil
}

if err != nil {
return fmt.Errorf("error getting Cognito User Pool Client (%s) UI customization: %w", d.Id(), err)
}

if err := d.Set("ui_customization", flattenCognitoUserPoolUICustomization(d, uiCustomization)); err != nil {
return fmt.Errorf("error setting ui_customization: %w", err)
}

return nil
}

Expand Down Expand Up @@ -460,27 +380,6 @@ func resourceAwsCognitoUserPoolClientUpdate(d *schema.ResourceData, meta interfa
return fmt.Errorf("Error updating Cognito User Pool Client: %s", err)
}

if d.HasChange("ui_customization") {
if v, ok := d.GetOk("ui_customization"); ok {
input, err := expandCognitoUserPoolUICustomizationInput(v.([]interface{}))

if err != nil {
return fmt.Errorf("error updating Cognito User Pool Client (%s) UI customization: %w", d.Id(), err)
}

if input != nil {
input.ClientId = aws.String(d.Id())
input.UserPoolId = aws.String(d.Get("user_pool_id").(string))

_, err := conn.SetUICustomization(input)

if err != nil {
return fmt.Errorf("error updating Cognito User Pool Client (%s) UI customization: %w", d.Id(), err)
}
}
}
}

return resourceAwsCognitoUserPoolClientRead(d, meta)
}

Expand Down
Loading

0 comments on commit dc397fb

Please sign in to comment.