Skip to content
This repository has been archived by the owner on Mar 8, 2022. It is now read-only.

DXCDT-20: Client data source #511

Merged
merged 7 commits into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions auth0/data_source_auth0_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package auth0

import (
"errors"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"gopkg.in/auth0.v5"
"gopkg.in/auth0.v5/management"
)

func newDataClient() *schema.Resource {
clientSchema := datasourceSchemaFromResourceSchema(newClient().Schema)
delete(clientSchema, "client_secret_rotation_trigger")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're currently excluding the client_secret_rotation_trigger property when building from the client resource schema. This was proposed in #363 and I'm assuming that the exclusion is still valid but need to verify that no other properties should also be excluded.


addOptionalFieldsToSchema(clientSchema, "name", "client_id")

return &schema.Resource{
Read: readDataClient,
Schema: clientSchema,
}
}

func readDataClient(d *schema.ResourceData, m interface{}) error {
clientId := auth0.StringValue(String(d, "client_id"))
if clientId != "" {
d.SetId(clientId)
return readClient(d, m)
}

//If not provided ID, perform looking of client by name
name := auth0.StringValue(String(d, "name"))
if name == "" {
return errors.New("no 'client_id' or 'name' was specified")
}

api := m.(*management.Management)
clients, err := api.Client.List(management.IncludeFields("client_id", "name"))
if err != nil {
return err
}
for _, client := range clients.Clients {
if auth0.StringValue(client.Name) == name {
clientId = auth0.StringValue(client.ClientID)
d.SetId(clientId)
return readClient(d, m)
}
}
return fmt.Errorf("no client found with 'name' = '%s'", name)
}
149 changes: 149 additions & 0 deletions auth0/data_source_auth0_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package auth0

import (
"fmt"
"testing"

"github.com/alexkappa/terraform-provider-auth0/auth0/internal/random"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

const testAccDataClientConfigInit = `
sergiught marked this conversation as resolved.
Show resolved Hide resolved
resource "auth0_client" "test" {
name = "Acceptance Test - {{.random}}"
description = "Test Application Long Description"
app_type = "non_interactive"
custom_login_page_on = true
is_first_party = true
is_token_endpoint_ip_header_trusted = true
token_endpoint_auth_method = "client_secret_post"
oidc_conformant = true
callbacks = [ "https://example.com/callback" ]
allowed_origins = [ "https://example.com" ]
allowed_clients = [ "https://allowed.example.com" ]
grant_types = [ "authorization_code", "http://auth0.com/oauth/grant-type/password-realm", "implicit", "password", "refresh_token" ]
organization_usage = "deny"
organization_require_behavior = "no_prompt"
allowed_logout_urls = [ "https://example.com" ]
web_origins = [ "https://example.com" ]
jwt_configuration {
lifetime_in_seconds = 300
secret_encoded = true
alg = "RS256"
scopes = {
foo = "bar"
}
}
client_metadata = {
foo = "zoo"
}
addons {
firebase = {
client_email = "john.doe@example.com"
lifetime_in_seconds = 1
private_key = "wer"
private_key_id = "qwreerwerwe"
}
samlp {
audience = "https://example.com/saml"
mappings = {
email = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
create_upn_claim = false
passthrough_claims_with_no_mapping = false
map_unknown_claims_as_is = false
map_identities = false
name_identifier_format = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
name_identifier_probes = [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
]
logout = {
callback = "http://example.com/callback"
slo_enabled = true
}
signing_cert = "-----BEGIN PUBLIC KEY-----\nMIGf...bpP/t3\n+JGNGIRMj1hF1rnb6QIDAQAB\n-----END PUBLIC KEY-----\n"
}
}
refresh_token {
leeway = 42
token_lifetime = 424242
rotation_type = "rotating"
expiration_type = "expiring"
infinite_token_lifetime = true
infinite_idle_token_lifetime = false
idle_token_lifetime = 3600
}
mobile {
ios {
team_id = "9JA89QQLNQ"
app_bundle_identifier = "com.my.bundle.id"
}
}
initiate_login_uri = "https://example.com/login"
}
`

const testAccDataClientConfigByName = `
%v
data auth0_client test {
name = "Acceptance Test - {{.random}}"
}
`

const testAccDataClientConfigById = `
%v
data auth0_client test {
client_id = auth0_client.test.client_id
}
`

func TestAccDataClientByName(t *testing.T) {
rand := random.String(6)

resource.Test(t, resource.TestCase{
Providers: map[string]terraform.ResourceProvider{
"auth0": Provider(),
},
PreventPostDestroyRefresh: true,
Steps: []resource.TestStep{
{
Config: random.Template(testAccDataClientConfigInit, rand), // must initialize resource before reading with data source
},
{
Config: random.Template(fmt.Sprintf(testAccDataClientConfigByName, testAccDataClientConfigInit), rand),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.auth0_client.test", "client_id"),
resource.TestCheckResourceAttr("data.auth0_client.test", "name", fmt.Sprintf("Acceptance Test - %v", rand)),
resource.TestCheckResourceAttr("data.auth0_client.test", "app_type", "non_interactive"),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check for against the app_type property is only arbitrary and a naive way of checking that properties outside the ID and name exist on the schema.

PR #363 introduced a more comprehensive method of comparing the data source against the resource configuration, but I think that functionality needs to be looked at closer before we fully integrate.

resource.TestCheckNoResourceAttr("data.auth0_client.test", "client_secret_rotation_trigger"),
),
},
},
})
}

func TestAccDataClientById(t *testing.T) {
rand := random.String(6)

resource.Test(t, resource.TestCase{
Providers: map[string]terraform.ResourceProvider{
"auth0": Provider(),
},
PreventPostDestroyRefresh: true,
Steps: []resource.TestStep{
{
Config: random.Template(testAccDataClientConfigInit, rand),
},
{
Config: random.Template(fmt.Sprintf(testAccDataClientConfigById, testAccDataClientConfigInit), rand),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.auth0_client.test", "id"),
resource.TestCheckResourceAttrSet("data.auth0_client.test", "name"),
resource.TestCheckNoResourceAttr("data.auth0_client.test", "client_secret_rotation_trigger"),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking for the absence of this particular property because we explicitly excluded it from the schema definition.

),
},
},
})
}
3 changes: 3 additions & 0 deletions auth0/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func Provider() *schema.Provider {
"auth0_action": newAction(),
"auth0_trigger_binding": newTriggerBinding(),
},
DataSourcesMap: map[string]*schema.Resource{
"auth0_client": newDataClient(),
},
}

provider.ConfigureFunc = ConfigureProvider(provider.TerraformVersion)
Expand Down
32 changes: 32 additions & 0 deletions docs/datasources/client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
layout: "auth0"
page_title: "Data Source: auth0_client"
description: |-
Data source to retrieve a specific Auth0 Application client by 'client_id' or 'name'
---

# Data Source: auth0_client

Data source to retrieve a specific Auth0 Application client by 'client_id' or 'name'

## Example Usage

```hcl
data "auth0_client" "some-client-by-name" {
name = "Name of my Application"
}
data "auth0_client" "some-client-by-id" {
client_id = "abcdefghkijklmnopqrstuvwxyz0123456789"
}
```

## Argument Reference

At least one of the following arguments required:

- `client_id` - (Optional) String. client_id of the application.
- `name` - (Optional) String. Name of the application. Ignored if `client_id` is also specified.

## Attribute Reference

The client data source possesses the same attributes as the `auth0_client` resource, with the exception of `client_secret_rotation_trigger`. Refer to the [auth0_client resource documentation](../resources/client.md) for a list of returned attributes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems more reasonable than just duplicating the properties again, it'll just become more of a maintenance liability. However, I'm unsure if this will interfere with other documentation, for example the TF registry docs.