Skip to content

Commit

Permalink
PR fixes: refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
rtim75 committed Dec 14, 2021
1 parent 3b2d087 commit 7ac1886
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 63 deletions.
102 changes: 40 additions & 62 deletions internal/service/cognitoidp/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
Expand Down Expand Up @@ -39,14 +40,15 @@ func ResourceUser() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"creation_date": {
Type: schema.TypeString,
Computed: true,
},
"desired_delivery_mediums": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{
cognitoidentityprovider.DeliveryMediumTypeSms,
cognitoidentityprovider.DeliveryMediumTypeEmail,
}, false),
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(cognitoidentityprovider.DeliveryMediumType_Values(), false),
},
Optional: true,
},
Expand All @@ -59,13 +61,14 @@ func ResourceUser() *schema.Resource {
Type: schema.TypeBool,
Optional: true,
},
"message_action": {
"last_modified_date": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
cognitoidentityprovider.MessageActionTypeResend,
cognitoidentityprovider.MessageActionTypeSuppress,
}, false),
Computed: true,
},
"message_action": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice(cognitoidentityprovider.MessageActionType_Values(), false),
},
"mfa_preference": {
Type: schema.TypeList,
Expand Down Expand Up @@ -161,14 +164,14 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {

if v, ok := d.GetOk("attributes"); ok {
attributes := v.(map[string]interface{})
params.UserAttributes = expandUserAttributes(attributes)
params.UserAttributes = expandAttribute(attributes)
}

if v, ok := d.GetOk("validation_data"); ok {
attributes := v.(map[string]interface{})
// aws sdk uses the same type for both validation data and user attributes
// https://docs.aws.amazon.com/sdk-for-go/api/service/cognitoidentityprovider/#AdminCreateUserInput
params.ValidationData = expandUserAttributes(attributes)
params.ValidationData = expandAttribute(attributes)
}

if v, ok := d.GetOk("temporary_password"); ok {
Expand All @@ -177,15 +180,10 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {

resp, err := conn.AdminCreateUser(params)
if err != nil {
if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeUsernameExistsException, "An account with the email already exists") {
log.Println("[ERROR] User alias already exists. To override the alias set `force_alias_creation` attribute to `true`.")
} else if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidParameterException, "No email provided but desired delivery medium was Email") {
log.Println("[ERROR] No email provided but desired delivery medium was `EMAIL`.")
}
return fmt.Errorf("Error creating Cognito User: %s", err)
return fmt.Errorf("Error creating Cognito User (%s): %w", d.Id(), err)
}

d.SetId(fmt.Sprintf("%s/%s", *params.UserPoolId, *resp.User.Username))
d.SetId(fmt.Sprintf("%s/%s", aws.StringValue(params.UserPoolId), aws.StringValue(resp.User.Username)))

if v := d.Get("enabled"); !v.(bool) {
disableParams := &cognitoidentityprovider.AdminDisableUserInput{
Expand All @@ -195,7 +193,7 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {

_, err := conn.AdminDisableUser(disableParams)
if err != nil {
return fmt.Errorf("Error disabling Cognito User: %s", err)
return fmt.Errorf("Error disabling Cognito User (%s): %w", d.Id(), err)
}
}

Expand All @@ -209,7 +207,7 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {

_, err := conn.AdminSetUserPassword(setPasswordParams)
if err != nil {
return fmt.Errorf("Error setting Cognito User's password: %s", err)
return fmt.Errorf("Error setting Cognito User's password (%s): %w", d.Id(), err)
}
}

Expand All @@ -228,34 +226,28 @@ func resourceUserRead(d *schema.ResourceData, meta interface{}) error {

user, err := conn.AdminGetUser(params)
if err != nil {
if tfawserr.ErrMessageContains(err, "UserNotFoundException", "") {
if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeUserNotFoundException) {
log.Printf("[WARN] Cognito User %s not found, removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("Error reading Cognito User: %s", err)
return fmt.Errorf("Error reading Cognito User (%s): %w", d.Id(), err)
}

if err := d.Set("attributes", flattenUserAttributes(user.UserAttributes)); err != nil {
return fmt.Errorf("failed setting user attributes: %w", err)
}

if err := d.Set("status", user.UserStatus); err != nil {
return fmt.Errorf("failed setting user status: %w", err)
}

if err := d.Set("sub", flattenUserSub(user.UserAttributes)); err != nil {
return fmt.Errorf("failed setting user sub: %w", err)
}

if err := d.Set("enabled", user.Enabled); err != nil {
return fmt.Errorf("failed setting user enabled status: %w", err)
return fmt.Errorf("failed setting user attributes (%s): %w", d.Id(), err)
}

if err := d.Set("mfa_preference", flattenUserMfaPreference(user.MFAOptions, user.UserMFASettingList, user.PreferredMfaSetting)); err != nil {
return fmt.Errorf("failed setting user mfa_preference: %w", err)
return fmt.Errorf("failed setting user mfa_preference (%s): %w", d.Id(), err)
}

d.Set("status", user.UserStatus)
d.Set("enabled", user.Enabled)
d.Set("creation_date", user.UserCreateDate.Format(time.RFC3339))
d.Set("last_modified_date", user.UserLastModifiedDate.Format(time.RFC3339))
d.Set("sub", retrieveUserSub(user.UserAttributes))

return nil
}

Expand All @@ -273,16 +265,11 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {
params := &cognitoidentityprovider.AdminUpdateUserAttributesInput{
Username: aws.String(d.Get("username").(string)),
UserPoolId: aws.String(d.Get("user_pool_id").(string)),
UserAttributes: expandUserAttributes(upd),
UserAttributes: expandAttribute(upd),
}
_, err := conn.AdminUpdateUserAttributes(params)
if err != nil {
if tfawserr.ErrMessageContains(err, "UserNotFoundException", "") {
log.Printf("[WARN] Cognito User %s is already gone", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("Error updating Cognito User Attributes: %s", err)
return fmt.Errorf("Error updating Cognito User Attributes (%s): %w", d.Id(), err)
}
}
if len(del) > 0 {
Expand All @@ -293,12 +280,7 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {
}
_, err := conn.AdminDeleteUserAttributes(params)
if err != nil {
if tfawserr.ErrMessageContains(err, "UserNotFoundException", "") {
log.Printf("[WARN] Cognito User %s is already gone", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("Error updating Cognito User Attributes: %s", err)
return fmt.Errorf("Error updating Cognito User Attributes (%s): %w", d.Id(), err)
}
}
}
Expand All @@ -313,7 +295,7 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {
}
_, err := conn.AdminEnableUser(enableParams)
if err != nil {
return fmt.Errorf("Error enabling Cognito User: %s", err)
return fmt.Errorf("Error enabling Cognito User (%s): %w", d.Id(), err)
}
} else {
disableParams := &cognitoidentityprovider.AdminDisableUserInput{
Expand All @@ -322,7 +304,7 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {
}
_, err := conn.AdminDisableUser(disableParams)
if err != nil {
return fmt.Errorf("Error disabling Cognito User: %s", err)
return fmt.Errorf("Error disabling Cognito User (%s): %w", d.Id(), err)
}
}
}
Expand All @@ -340,7 +322,7 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {

_, err := conn.AdminSetUserPassword(setPasswordParams)
if err != nil {
return fmt.Errorf("Error changing Cognito User's password: %s", err)
return fmt.Errorf("Error changing Cognito User's temporary password (%s): %w", d.Id(), err)
}
} else {
d.Set("temporary_password", nil)
Expand All @@ -360,7 +342,7 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {

_, err := conn.AdminSetUserPassword(setPasswordParams)
if err != nil {
return fmt.Errorf("Error changing Cognito User's password: %s", err)
return fmt.Errorf("Error changing Cognito User's password (%s): %w", d.Id(), err)
}
} else {
d.Set("password", nil)
Expand All @@ -382,7 +364,7 @@ func resourceUserDelete(d *schema.ResourceData, meta interface{}) error {

_, err := conn.AdminDeleteUser(params)
if err != nil {
return fmt.Errorf("Error deleting Cognito User: %s", err)
return fmt.Errorf("Error deleting Cognito User (%s): %w", d.Id(), err)
}

return nil
Expand All @@ -400,7 +382,7 @@ func resourceUserImport(d *schema.ResourceData, meta interface{}) ([]*schema.Res
return []*schema.ResourceData{d}, nil
}

func expandUserAttributes(tfMap map[string]interface{}) []*cognitoidentityprovider.AttributeType {
func expandAttribute(tfMap map[string]interface{}) []*cognitoidentityprovider.AttributeType {
if len(tfMap) == 0 {
return nil
}
Expand Down Expand Up @@ -498,7 +480,7 @@ func expandUserDesiredDeliveryMediums(tfSet *schema.Set) []*string {
return apiList
}

func flattenUserSub(apiList []*cognitoidentityprovider.AttributeType) string {
func retrieveUserSub(apiList []*cognitoidentityprovider.AttributeType) string {
for _, attr := range apiList {
if aws.StringValue(attr.Name) == "sub" {
return aws.StringValue(attr.Value)
Expand Down Expand Up @@ -543,10 +525,6 @@ func flattenUserMfaPreference(mfaOptions []*cognitoidentityprovider.MFAOptionTyp
return []interface{}{preference}
}

func userAttributeHash(attr interface{}) int {
return schema.HashString(attr.(map[string]interface{})["name"])
}

func UserAttributeKeyMatchesStandardAttribute(input string) bool {
if len(input) == 0 {
return false
Expand Down
2 changes: 2 additions & 0 deletions internal/service/cognitoidp/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ func TestAccCognitoUser_basic(t *testing.T) {
Config: testAccUserConfigBasic(rUserPoolName, rUserName),
Check: resource.ComposeTestCheckFunc(
testAccCheckUserExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "creation_date"),
resource.TestCheckResourceAttrSet(resourceName, "last_modified_date"),
resource.TestCheckResourceAttrSet(resourceName, "sub"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "status", cognitoidentityprovider.UserStatusTypeForceChangePassword),
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/cognito_user.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Provides a Cognito User Resource.
## Example Usage

### Basic configuration

```terraform
resource "aws_cognito_user_pool" "example" {
name = "MyExamplePool"
Expand Down Expand Up @@ -70,7 +71,7 @@ The following arguments are required:

The following arguments are optional:

* `attributes` - (Optional) An array of name-value pairs that contain user attributes and attribute values to be set for the user to be created.
* `attributes` - (Optional) A map that contains user attributes and attribute values to be set for the user to be created.
* `client_metadata` - (Optional) A map of custom key-value pairs that you can provide as input for any custom workflows that user creation triggers. Amazon Cognito does not store the `client_metadata` value. This data is available only to Lambda triggers that are assigned to a user pool to support custom workflows. If your user pool configuration does not include triggers, the ClientMetadata parameter serves no purpose. For more information, see [Customizing User Pool Workflows with Lambda Triggers](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html).
* `desired_delivery_mediums` - (Optional) A list of mediums to the welcome message will be sent through. Allowed values are `EMAIL` and `SMS`. If it's provided, make sure you have also specified `email` attribute for the `EMAIL` medium and `phone_number` for the `SMS`. More than one value can be specified. Amazon Cognito does not store the `desired_delivery_mediums` value. Defaults to `["SMS"]`.
* `enabled` - (Optional) Specifies whether the user should be enabled after creation. The welcome message will be sent regardless of the `enabled` value. The behavior can be changed with `message_action` argument. Defaults to `true`.
Expand Down

0 comments on commit 7ac1886

Please sign in to comment.