Skip to content

Commit

Permalink
Merge pull request #23765 from kamilturek/f-aws-cognito-user-in-group
Browse files Browse the repository at this point in the history
r/aws_cognito_user_in_group - new resource
  • Loading branch information
ewbankkit committed Mar 21, 2022
2 parents be5c3d4 + 040921a commit c52b3aa
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .changelog/23765.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_cognito_user_in_group
```
3 changes: 2 additions & 1 deletion internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1081,8 +1081,9 @@ func Provider() *schema.Provider {

"aws_cognito_identity_provider": cognitoidp.ResourceIdentityProvider(),
"aws_cognito_resource_server": cognitoidp.ResourceResourceServer(),
"aws_cognito_user_group": cognitoidp.ResourceUserGroup(),
"aws_cognito_user": cognitoidp.ResourceUser(),
"aws_cognito_user_group": cognitoidp.ResourceUserGroup(),
"aws_cognito_user_in_group": cognitoidp.ResourceUserInGroup(),
"aws_cognito_user_pool": cognitoidp.ResourceUserPool(),
"aws_cognito_user_pool_client": cognitoidp.ResourceUserPoolClient(),
"aws_cognito_user_pool_domain": cognitoidp.ResourceUserPoolDomain(),
Expand Down
40 changes: 40 additions & 0 deletions internal/service/cognitoidp/find.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cognitoidp

import (
"fmt"
"reflect"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -33,3 +34,42 @@ func FindCognitoUserPoolUICustomization(conn *cognitoidentityprovider.CognitoIde

return output.UICustomization, nil
}

// FindCognitoUserInGroup checks whether the specified user is present in the specified group. Returns boolean value accordingly.
func FindCognitoUserInGroup(conn *cognitoidentityprovider.CognitoIdentityProvider, groupName, userPoolId, username string) (bool, error) {
input := &cognitoidentityprovider.AdminListGroupsForUserInput{
UserPoolId: aws.String(userPoolId),
Username: aws.String(username),
}

found := false

err := conn.AdminListGroupsForUserPages(input, func(page *cognitoidentityprovider.AdminListGroupsForUserOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, group := range page.Groups {
if group == nil {
continue
}

if aws.StringValue(group.GroupName) == groupName {
found = true
break
}
}

if found {
return false
}

return !lastPage
})

if err != nil {
return false, fmt.Errorf("error reading groups for user: %w", err)
}

return found, nil
}
111 changes: 111 additions & 0 deletions internal/service/cognitoidp/user_in_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package cognitoidp

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
"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/hashicorp/terraform-provider-aws/internal/conns"
)

func ResourceUserInGroup() *schema.Resource {
return &schema.Resource{
Create: resourceUserInGroupCreate,
Read: resourceUserInGroupRead,
Delete: resourceUserInGroupDelete,
Schema: map[string]*schema.Schema{
"group_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validUserGroupName,
},
"user_pool_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validUserPoolID,
},
"username": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 128),
},
},
}
}

func resourceUserInGroupCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).CognitoIDPConn

input := &cognitoidentityprovider.AdminAddUserToGroupInput{}

if v, ok := d.GetOk("group_name"); ok {
input.GroupName = aws.String(v.(string))
}

if v, ok := d.GetOk("user_pool_id"); ok {
input.UserPoolId = aws.String(v.(string))
}

if v, ok := d.GetOk("username"); ok {
input.Username = aws.String(v.(string))
}

_, err := conn.AdminAddUserToGroup(input)

if err != nil {
return fmt.Errorf("error adding user to group: %w", err)
}

//lintignore:R015 // Allow legacy unstable ID usage in managed resource
d.SetId(resource.UniqueId())

return resourceUserInGroupRead(d, meta)
}

func resourceUserInGroupRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).CognitoIDPConn

groupName := d.Get("group_name").(string)
userPoolId := d.Get("user_pool_id").(string)
username := d.Get("username").(string)

found, err := FindCognitoUserInGroup(conn, groupName, userPoolId, username)

if err != nil {
return err
}

if !found {
d.SetId("")
}

return nil
}

func resourceUserInGroupDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).CognitoIDPConn

groupName := d.Get("group_name").(string)
userPoolID := d.Get("user_pool_id").(string)
username := d.Get("username").(string)

input := &cognitoidentityprovider.AdminRemoveUserFromGroupInput{
GroupName: aws.String(groupName),
UserPoolId: aws.String(userPoolID),
Username: aws.String(username),
}

_, err := conn.AdminRemoveUserFromGroup(input)

if err != nil {
return fmt.Errorf("error removing user from group: %w", err)
}

return nil
}
152 changes: 152 additions & 0 deletions internal/service/cognitoidp/user_in_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package cognitoidp_test

import (
"errors"
"fmt"
"testing"

"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfcognitoidp "github.com/hashicorp/terraform-provider-aws/internal/service/cognitoidp"
)

func TestAccCognitoUserInGroup_basic(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_cognito_user_in_group.test"
userPoolResourceName := "aws_cognito_user_pool.test"
userGroupResourceName := "aws_cognito_user_group.test"
userResourceName := "aws_cognito_user.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckUserInGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccConfigUserInGroup_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckUserInGroupExists(resourceName),
resource.TestCheckResourceAttrPair(resourceName, "user_pool_id", userPoolResourceName, "id"),
resource.TestCheckResourceAttrPair(resourceName, "group_name", userGroupResourceName, "name"),
resource.TestCheckResourceAttrPair(resourceName, "username", userResourceName, "username"),
),
},
},
})
}

func TestAccCognitoUserInGroup_disappears(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_cognito_user_in_group.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckUserInGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccConfigUserInGroup_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckUserInGroupExists(resourceName),
acctest.CheckResourceDisappears(acctest.Provider, tfcognitoidp.ResourceUserInGroup(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccConfigUserInGroup_basic(rName string) string {
return fmt.Sprintf(`
resource "aws_cognito_user_pool" "test" {
name = %[1]q
password_policy {
temporary_password_validity_days = 7
minimum_length = 6
require_uppercase = false
require_symbols = false
require_numbers = false
}
}
resource "aws_cognito_user" "test" {
user_pool_id = aws_cognito_user_pool.test.id
username = %[1]q
}
resource "aws_cognito_user_group" "test" {
user_pool_id = aws_cognito_user_pool.test.id
name = %[1]q
}
resource "aws_cognito_user_in_group" "test" {
user_pool_id = aws_cognito_user_pool.test.id
group_name = aws_cognito_user_group.test.name
username = aws_cognito_user.test.username
}
`, rName)
}

func testAccCheckUserInGroupExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("resource not found: %s", resourceName)
}

conn := acctest.Provider.Meta().(*conns.AWSClient).CognitoIDPConn

groupName := rs.Primary.Attributes["group_name"]
userPoolId := rs.Primary.Attributes["user_pool_id"]
username := rs.Primary.Attributes["username"]

found, err := tfcognitoidp.FindCognitoUserInGroup(conn, groupName, userPoolId, username)

if err != nil {
return err
}

if !found {
return errors.New("user in group not found")
}

return nil
}
}

func testAccCheckUserInGroupDestroy(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).CognitoIDPConn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_cognito_user_in_group" {
continue
}

groupName := rs.Primary.Attributes["group_name"]
userPoolId := rs.Primary.Attributes["user_pool_id"]
username := rs.Primary.Attributes["username"]

found, err := tfcognitoidp.FindCognitoUserInGroup(conn, groupName, userPoolId, username)

if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) {
continue
}

if err != nil {
return err
}

if found {
return fmt.Errorf("user in group still exists (%s)", rs.Primary.ID)
}
}

return nil
}
55 changes: 55 additions & 0 deletions website/docs/r/cognito_user_in_group.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
subcategory: "Cognito"
layout: "aws"
page_title: "AWS: aws_cognito_user_in_group"
description: |-
Adds the specified user to the specified group.
---

# Resource: aws_cognito_user_in_group

Adds the specified user to the specified group.

## Example Usage

```terraform
resource "aws_cognito_user_pool" "example" {
name = "example"
password_policy {
temporary_password_validity_days = 7
minimum_length = 6
require_uppercase = false
require_symbols = false
require_numbers = false
}
}
resource "aws_cognito_user" "example" {
user_pool_id = aws_cognito_user_pool.test.id
username = "example"
}
resource "aws_cognito_user_group" "example" {
user_pool_id = aws_cognito_user_pool.test.id
name = "example"
}
resource "aws_cognito_user_in_group" "example" {
user_pool_id = aws_cognito_user_pool.example.id
group_name = aws_cognito_user_group.example.name
username = aws_cognito_user.example.username
}
```

## Argument Reference

The following arguments are required:

* `user_pool_id` - (Required) The user pool ID of the user and group.
* `group_name` - (Required) The name of the group to which the user is to be added.
* `username` - (Required) The username of the user to be added to the group.

## Attributes Reference

No additional attributes are exported.

0 comments on commit c52b3aa

Please sign in to comment.