From 1fc69065f689497c8e4aeb5f01527505539017c0 Mon Sep 17 00:00:00 2001 From: Daniel Quackenbush <25692880+danquack@users.noreply.github.com> Date: Fri, 7 Jan 2022 13:50:19 -0500 Subject: [PATCH 1/7] lookup individual user pool client --- internal/provider/provider.go | 1 + .../user_pool_client_data_source.go | 231 ++++++++++++++++++ .../user_pool_client_data_source_test.go | 45 ++++ .../docs/d/cognito_user_pool_client.markdown | 83 +++++++ 4 files changed, 360 insertions(+) create mode 100644 internal/service/cognitoidp/user_pool_client_data_source.go create mode 100644 internal/service/cognitoidp/user_pool_client_data_source_test.go create mode 100644 website/docs/d/cognito_user_pool_client.markdown diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 25824483417..1afe67a9900 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -402,6 +402,7 @@ func Provider() *schema.Provider { "aws_codestarconnections_connection": codestarconnections.DataSourceConnection(), + "aws_cognito_user_pool_client": cognitoidp.DataSourceUserPoolClient(), "aws_cognito_user_pool_clients": cognitoidp.DataSourceUserPoolClients(), "aws_cognito_user_pool_signing_certificate": cognitoidp.DataSourceUserPoolSigningCertificate(), "aws_cognito_user_pools": cognitoidp.DataSourceUserPools(), diff --git a/internal/service/cognitoidp/user_pool_client_data_source.go b/internal/service/cognitoidp/user_pool_client_data_source.go new file mode 100644 index 00000000000..48b3c851202 --- /dev/null +++ b/internal/service/cognitoidp/user_pool_client_data_source.go @@ -0,0 +1,231 @@ +package cognitoidp + +import ( + "fmt" + "log" + + "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/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/flex" +) + +func DataSourceUserPoolClient() *schema.Resource { + return &schema.Resource{ + Read: dataSourceUserPoolClientRead, + + Schema: map[string]*schema.Schema{ + "access_token_validity": { + Type: schema.TypeInt, + Computed: true, + }, + "allowed_oauth_flows": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "allowed_oauth_flows_user_pool_client": { + Type: schema.TypeBool, + Computed: true, + }, + "allowed_oauth_scopes": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "analytics_configuration": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "application_id": { + Type: schema.TypeString, + Optional: true, + }, + "application_arn": { + Type: schema.TypeString, + Optional: true, + }, + "external_id": { + Type: schema.TypeString, + Optional: true, + }, + "role_arn": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "user_data_shared": { + Type: schema.TypeBool, + Optional: true, + }, + }, + }, + }, + "callback_urls": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "default_redirect_uri": { + Type: schema.TypeString, + Computed: true, + }, + "enable_token_revocation": { + Type: schema.TypeBool, + Computed: true, + }, + "explicit_auth_flows": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "generate_secret": { + Type: schema.TypeBool, + Computed: true, + }, + "id_token_validity": { + Type: schema.TypeInt, + Computed: true, + }, + "logout_urls": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "prevent_user_existence_errors": { + Type: schema.TypeString, + Computed: true, + }, + "read_attributes": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "refresh_token_validity": { + Type: schema.TypeInt, + Computed: true, + }, + "supported_identity_providers": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "token_validity_units": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_token": { + Type: schema.TypeString, + Optional: true, + }, + "id_token": { + Type: schema.TypeString, + Optional: true, + }, + "refresh_token": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "user_pool_id": { + Type: schema.TypeString, + Required: true, + }, + "write_attributes": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func dataSourceUserPoolClientRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).CognitoIDPConn + + clientId := d.Get("client_id").(string) + d.SetId(clientId) + + params := &cognitoidentityprovider.DescribeUserPoolClientInput{ + ClientId: aws.String(clientId), + UserPoolId: aws.String(d.Get("user_pool_id").(string)), + } + + log.Printf("[DEBUG] Reading Cognito User Pool Client: %s", params) + + resp, err := conn.DescribeUserPoolClient(params) + + if err != nil { + if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] Cognito User Pool Client %s is already gone", d.Id()) + d.SetId("") + return nil + } + return err + } + + userPoolClient := resp.UserPoolClient + d.Set("user_pool_id", userPoolClient.UserPoolId) + d.Set("name", userPoolClient.ClientName) + d.Set("explicit_auth_flows", flex.FlattenStringSet(userPoolClient.ExplicitAuthFlows)) + d.Set("read_attributes", flex.FlattenStringSet(userPoolClient.ReadAttributes)) + d.Set("write_attributes", flex.FlattenStringSet(userPoolClient.WriteAttributes)) + d.Set("refresh_token_validity", userPoolClient.RefreshTokenValidity) + d.Set("access_token_validity", userPoolClient.AccessTokenValidity) + d.Set("id_token_validity", userPoolClient.IdTokenValidity) + d.Set("client_secret", userPoolClient.ClientSecret) + d.Set("allowed_oauth_flows", flex.FlattenStringSet(userPoolClient.AllowedOAuthFlows)) + d.Set("allowed_oauth_flows_user_pool_client", userPoolClient.AllowedOAuthFlowsUserPoolClient) + d.Set("allowed_oauth_scopes", flex.FlattenStringSet(userPoolClient.AllowedOAuthScopes)) + d.Set("callback_urls", flex.FlattenStringSet(userPoolClient.CallbackURLs)) + d.Set("default_redirect_uri", userPoolClient.DefaultRedirectURI) + d.Set("logout_urls", flex.FlattenStringSet(userPoolClient.LogoutURLs)) + d.Set("prevent_user_existence_errors", userPoolClient.PreventUserExistenceErrors) + d.Set("supported_identity_providers", flex.FlattenStringSet(userPoolClient.SupportedIdentityProviders)) + d.Set("enable_token_revocation", userPoolClient.EnableTokenRevocation) + + if err := d.Set("analytics_configuration", flattenUserPoolClientAnalyticsConfig(userPoolClient.AnalyticsConfiguration)); err != nil { + return fmt.Errorf("error setting analytics_configuration: %w", err) + } + + if err := d.Set("token_validity_units", flattenUserPoolClientTokenValidityUnitsType(userPoolClient.TokenValidityUnits)); err != nil { + return fmt.Errorf("error setting token_validity_units: %w", err) + } + + return nil +} diff --git a/internal/service/cognitoidp/user_pool_client_data_source_test.go b/internal/service/cognitoidp/user_pool_client_data_source_test.go new file mode 100644 index 00000000000..b5427d95ec5 --- /dev/null +++ b/internal/service/cognitoidp/user_pool_client_data_source_test.go @@ -0,0 +1,45 @@ +package cognitoidp_test + +import ( + "testing" + + "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccCognitoIDPUserPoolClientDataSource_basic(t *testing.T) { + var client cognitoidentityprovider.UserPoolClientType + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "data.aws_cognito_user_pool_client.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIdentityProvider(t) }, + ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckUserPoolClientDestroy, + Steps: []resource.TestStep{ + { + Config: testAccUserPoolClientConfigDataSource_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolClientExists(resourceName, &client), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "explicit_auth_flows.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "explicit_auth_flows.*", "ADMIN_NO_SRP_AUTH"), + resource.TestCheckResourceAttr(resourceName, "token_validity_units.#", "0"), + resource.TestCheckResourceAttr(resourceName, "analytics_configuration.#", "0"), + ), + }, + }, + }) +} + +func testAccUserPoolClientConfigDataSource_basic(rName string) string { + return testAccUserPoolClientConfig_basic(rName) + ` +data "aws_cognito_user_pool_client" "test" { + user_pool_id = aws_cognito_user_pool.test.id + client_id = aws_cognito_user_pool_client.test.id +} +` +} diff --git a/website/docs/d/cognito_user_pool_client.markdown b/website/docs/d/cognito_user_pool_client.markdown new file mode 100644 index 00000000000..bced8329fe0 --- /dev/null +++ b/website/docs/d/cognito_user_pool_client.markdown @@ -0,0 +1,83 @@ +--- +subcategory: "Cognito" +layout: "aws" +page_title: "AWS: aws_cognito_user_pool_client" +description: |- + Provides a Cognito User Pool Client +--- + +# Resource: aws_cognito_user_pool_client + +Provides a Cognito User Pool Client resource. + +## Example Usage + +### Get User Pool Client names + +```terraform +resource "aws_cognito_user_pool" "pool" { + name = "pool" +} + +data "aws_cognito_user_pool_clients" "main" { + user_pool_id = aws_cognito_user_pool.main.id +} + +data "aws_cognito_user_pool_client" "client" { + for_each = data.aws_cognito_user_pool_clients.main.client_ids + client_id = each.value + user_pool_id = aws_cognito_user_pool.pool.id +} + +output "names" { + value = data.aws_cognito_user_pool_client.client.*.name +} +``` + +## Argument Reference + +The following arguments are required: + +* `client_id` - (Required) Client Id of the user pool. +* `user_pool_id` - (Required) User pool the client belongs to. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `access_token_validity` - (Optional) Time limit, between 5 minutes and 1 day, after which the access token is no longer valid and cannot be used. This value will be overridden if you have entered a value in `token_validity_units`. +* `allowed_oauth_flows_user_pool_client` - (Optional) Whether the client is allowed to follow the OAuth protocol when interacting with Cognito user pools. +* `allowed_oauth_flows` - (Optional) List of allowed OAuth flows (code, implicit, client_credentials). +* `allowed_oauth_scopes` - (Optional) List of allowed OAuth scopes (phone, email, openid, profile, and aws.cognito.signin.user.admin). +* `analytics_configuration` - (Optional) Configuration block for Amazon Pinpoint analytics for collecting metrics for this user pool. [Detailed below](#analytics_configuration). +* `callback_urls` - (Optional) List of allowed callback URLs for the identity providers. +* `default_redirect_uri` - (Optional) Default redirect URI. Must be in the list of callback URLs. +* `enable_token_revocation` - (Optional) Enables or disables token revocation. +* `explicit_auth_flows` - (Optional) List of authentication flows (ADMIN_NO_SRP_AUTH, CUSTOM_AUTH_FLOW_ONLY, USER_PASSWORD_AUTH, ALLOW_ADMIN_USER_PASSWORD_AUTH, ALLOW_CUSTOM_AUTH, ALLOW_USER_PASSWORD_AUTH, ALLOW_USER_SRP_AUTH, ALLOW_REFRESH_TOKEN_AUTH). +* `generate_secret` - (Optional) Should an application secret be generated. +* `id_token_validity` - (Optional) Time limit, between 5 minutes and 1 day, after which the ID token is no longer valid and cannot be used. This value will be overridden if you have entered a value in `token_validity_units`. +* `logout_urls` - (Optional) List of allowed logout URLs for the identity providers. +* `prevent_user_existence_errors` - (Optional) Choose which errors and responses are returned by Cognito APIs during authentication, account confirmation, and password recovery when the user does not exist in the user pool. When set to `ENABLED` and the user does not exist, authentication returns an error indicating either the username or password was incorrect, and account confirmation and password recovery return a response indicating a code was sent to a simulated destination. When set to `LEGACY`, those APIs will return a `UserNotFoundException` exception if the user does not exist in the user pool. +* `read_attributes` - (Optional) List of user pool attributes the application client can read from. +* `refresh_token_validity` - (Optional) Time limit in days refresh tokens are valid for. +* `supported_identity_providers` - (Optional) List of provider names for the identity providers that are supported on this client. Uses the `provider_name` attribute of `aws_cognito_identity_provider` resource(s), or the equivalent string(s). +* `token_validity_units` - (Optional) Configuration block for units in which the validity times are represented in. [Detailed below](#token_validity_units). +* `write_attributes` - (Optional) List of user pool attributes the application client can write to. + +### analytics_configuration + +Either `application_arn` or `application_id` is required. + +* `application_arn` - (Optional) Application ARN for an Amazon Pinpoint application. Conflicts with `external_id` and `role_arn`. +* `application_id` - (Optional) Application ID for an Amazon Pinpoint application. +* `external_id` - (Optional) ID for the Analytics Configuration. Conflicts with `application_arn`. +* `role_arn` - (Optional) ARN of an IAM role that authorizes Amazon Cognito to publish events to Amazon Pinpoint analytics. Conflicts with `application_arn`. +* `user_data_shared` (Optional) If set to `true`, Amazon Cognito will include user data in the events it publishes to Amazon Pinpoint analytics. + +### token_validity_units + +Valid values for the following arguments are: `seconds`, `minutes`, `hours` or `days`. + +* `access_token` - (Optional) Time unit in for the value in `access_token_validity`, defaults to `hours`. +* `id_token` - (Optional) Time unit in for the value in `id_token_validity`, defaults to `hours`. +* `refresh_token` - (Optional) Time unit in for the value in `refresh_token_validity`, defaults to `days`. From 3aa0348665d787db1fd23d1f91654946f1877619 Mon Sep 17 00:00:00 2001 From: Daniel Quackenbush <25692880+danquack@users.noreply.github.com> Date: Fri, 7 Jan 2022 14:04:51 -0500 Subject: [PATCH 2/7] :memo: changelog --- .changelog/22477.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/22477.txt diff --git a/.changelog/22477.txt b/.changelog/22477.txt new file mode 100644 index 00000000000..4b4e97de885 --- /dev/null +++ b/.changelog/22477.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +data-source/aws_cognito_user_pool_client +``` From 0322e5573fb8f3cb6bcd9d9d1938b0d6d243905a Mon Sep 17 00:00:00 2001 From: Daniel Quackenbush <25692880+danquack@users.noreply.github.com> Date: Fri, 7 Jan 2022 14:09:59 -0500 Subject: [PATCH 3/7] terrafmt --- .../service/cognitoidp/user_pool_client_data_source_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/cognitoidp/user_pool_client_data_source_test.go b/internal/service/cognitoidp/user_pool_client_data_source_test.go index b5427d95ec5..c29830bbfdf 100644 --- a/internal/service/cognitoidp/user_pool_client_data_source_test.go +++ b/internal/service/cognitoidp/user_pool_client_data_source_test.go @@ -38,8 +38,8 @@ func TestAccCognitoIDPUserPoolClientDataSource_basic(t *testing.T) { func testAccUserPoolClientConfigDataSource_basic(rName string) string { return testAccUserPoolClientConfig_basic(rName) + ` data "aws_cognito_user_pool_client" "test" { - user_pool_id = aws_cognito_user_pool.test.id - client_id = aws_cognito_user_pool_client.test.id + user_pool_id = aws_cognito_user_pool.test.id + client_id = aws_cognito_user_pool_client.test.id } ` } From c0372cd8bc5cd3a77371bd29d16c01a0137bbfaf Mon Sep 17 00:00:00 2001 From: Daniel Quackenbush <25692880+danquack@users.noreply.github.com> Date: Fri, 7 Jan 2022 14:10:54 -0500 Subject: [PATCH 4/7] fix doc --- website/docs/d/cognito_user_pool_client.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/d/cognito_user_pool_client.markdown b/website/docs/d/cognito_user_pool_client.markdown index bced8329fe0..583cd1ecf58 100644 --- a/website/docs/d/cognito_user_pool_client.markdown +++ b/website/docs/d/cognito_user_pool_client.markdown @@ -6,7 +6,7 @@ description: |- Provides a Cognito User Pool Client --- -# Resource: aws_cognito_user_pool_client +# Data Source: aws_cognito_user_pool_client Provides a Cognito User Pool Client resource. From 43b7ec65b923a6d37f6ffc20b1260ee68c9cac5c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 9 Jan 2022 15:05:57 -0500 Subject: [PATCH 5/7] Correct CHANGELOG entry. --- .changelog/22477.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changelog/22477.txt b/.changelog/22477.txt index 4b4e97de885..0f94b4ecdfb 100644 --- a/.changelog/22477.txt +++ b/.changelog/22477.txt @@ -1,3 +1,3 @@ -```release-note:enhancement -data-source/aws_cognito_user_pool_client +```release-note:new-data-source +aws_cognito_user_pool_client ``` From 9f16ce9b4bfd2a0d394fd61f283c4ffaab5febc6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 9 Jan 2022 15:10:50 -0500 Subject: [PATCH 6/7] Mark additional attributes as `Computed`. --- .../cognitoidp/user_pool_client_data_source.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/internal/service/cognitoidp/user_pool_client_data_source.go b/internal/service/cognitoidp/user_pool_client_data_source.go index 48b3c851202..f2fdf8747a8 100644 --- a/internal/service/cognitoidp/user_pool_client_data_source.go +++ b/internal/service/cognitoidp/user_pool_client_data_source.go @@ -46,24 +46,23 @@ func DataSourceUserPoolClient() *schema.Resource { Schema: map[string]*schema.Schema{ "application_id": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "application_arn": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "external_id": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "role_arn": { Type: schema.TypeString, - Optional: true, Computed: true, }, "user_data_shared": { Type: schema.TypeBool, - Optional: true, + Computed: true, }, }, }, @@ -124,7 +123,7 @@ func DataSourceUserPoolClient() *schema.Resource { }, "read_attributes": { Type: schema.TypeSet, - Optional: true, + Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -147,15 +146,15 @@ func DataSourceUserPoolClient() *schema.Resource { Schema: map[string]*schema.Schema{ "access_token": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "id_token": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "refresh_token": { Type: schema.TypeString, - Optional: true, + Computed: true, }, }, }, From 8703068c4831b2a9bb9aff37275efa2e2a4ab9f2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 9 Jan 2022 15:17:49 -0500 Subject: [PATCH 7/7] Better error handling --- .../service/cognitoidp/user_pool_client_data_source.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/internal/service/cognitoidp/user_pool_client_data_source.go b/internal/service/cognitoidp/user_pool_client_data_source.go index f2fdf8747a8..065bef78806 100644 --- a/internal/service/cognitoidp/user_pool_client_data_source.go +++ b/internal/service/cognitoidp/user_pool_client_data_source.go @@ -6,7 +6,6 @@ import ( "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/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/flex" @@ -190,12 +189,7 @@ func dataSourceUserPoolClientRead(d *schema.ResourceData, meta interface{}) erro resp, err := conn.DescribeUserPoolClient(params) if err != nil { - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeResourceNotFoundException, "") { - log.Printf("[WARN] Cognito User Pool Client %s is already gone", d.Id()) - d.SetId("") - return nil - } - return err + return fmt.Errorf("error reading Cognito User Pool Client (%s): %w", clientId, err) } userPoolClient := resp.UserPoolClient