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

add support for Management API tokens #487

Merged
merged 7 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
45 changes: 31 additions & 14 deletions auth0/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,24 @@ func Provider() *schema.Provider {
DefaultFunc: schema.EnvDefaultFunc("AUTH0_DOMAIN", nil),
},
"client_id": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("AUTH0_CLIENT_ID", nil),
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("AUTH0_CLIENT_ID", nil),
RequiredWith: []string{"client_secret"},
ConflictsWith: []string{"api_token"},
},
"client_secret": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("AUTH0_CLIENT_SECRET", nil),
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("AUTH0_CLIENT_SECRET", nil),
RequiredWith: []string{"client_id"},
ConflictsWith: []string{"api_token"},
},
"api_token": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("AUTH0_API_TOKEN", nil),
ConflictsWith: []string{"client_id", "client_secret"},
},
"debug": {
Type: schema.TypeBool,
Expand Down Expand Up @@ -82,11 +92,6 @@ func Provider() *schema.Provider {
// client is stored and passed into the subsequent resources as the meta parameter.
func ConfigureProvider(terraformVersion string) func(data *schema.ResourceData) (interface{}, error) {
return func(data *schema.ResourceData) (interface{}, error) {
domain := data.Get("domain").(string)
id := data.Get("client_id").(string)
secret := data.Get("client_secret").(string)
debug := data.Get("debug").(bool)

providerVersion := version.ProviderVersion
sdkVersion := auth0.Version
terraformSDKVersion := meta.SDKVersionString()
Expand All @@ -99,9 +104,21 @@ func ConfigureProvider(terraformVersion string) func(data *schema.ResourceData)
terraformVersion,
)

return management.New(
domain,
management.WithClientCredentials(id, secret),
domain := data.Get("domain").(string)
debug := data.Get("debug").(bool)
clientID := data.Get("client_id").(string)
clientSecret := data.Get("client_secret").(string)
apiToken := data.Get("api_token").(string)

authenticationOption := management.WithStaticToken(apiToken)
// if api_token is not specified, authenticate with client ID and client secret.
// This is safe because of the provider schema.
if apiToken == "" {
authenticationOption = management.WithClientCredentials(clientID, clientSecret)
}

return management.New(domain,
authenticationOption,
management.WithDebug(debug),
management.WithUserAgent(userAgent),
)
Expand Down
80 changes: 80 additions & 0 deletions auth0/provider_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package auth0

import (
"errors"
"os"
"sort"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
Expand Down Expand Up @@ -71,3 +74,80 @@ func TestProvider_debugDefaults(t *testing.T) {
}
}
}

func TestProvider_configValidation(t *testing.T) {
testCases := []struct {
name string
resourceConfig map[string]interface{}
expectedErrors []error
}{
{
name: "missing client id",
resourceConfig: map[string]interface{}{"domain": "test", "client_secret": "test"},
expectedErrors: []error{errors.New("\"client_secret\": all of `client_id,client_secret` must be specified")},
},
{
name: "missing client secret",
resourceConfig: map[string]interface{}{"domain": "test", "client_id": "test"},
expectedErrors: []error{errors.New("\"client_id\": all of `client_id,client_secret` must be specified")},
},
{
name: "conflicting auth0 client and management token without domain",
resourceConfig: map[string]interface{}{"client_id": "test", "client_secret": "test", "api_token": "test"},
expectedErrors: []error{
errors.New("\"domain\": required field is not set"),
errors.New("\"client_id\": conflicts with api_token"),
errors.New("\"client_secret\": conflicts with api_token"),
errors.New("\"api_token\": conflicts with client_id"),
},
},
{
name: "valid auth0 client",
resourceConfig: map[string]interface{}{"domain": "valid_domain", "client_id": "test", "client_secret": "test"},
expectedErrors: nil,
},
{
name: "valid auth0 token",
resourceConfig: map[string]interface{}{"domain": "valid_domain", "api_token": "test"},
expectedErrors: nil,
},
}

originalEnviroment := os.Environ()
os.Clearenv()
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
c := terraform.NewResourceConfigRaw(test.resourceConfig)
p := Provider()

_, errs := p.Validate(c)
assertErrorsSliceEqual(t, test.expectedErrors, errs)
})
}

for _, e := range originalEnviroment {
environmentPair := strings.Split(e, "=")
os.Setenv(environmentPair[0], environmentPair[1])
}
}

func sortErrors(errs []error) {
sort.Slice(errs, func(i, j int) bool {
return errs[i].Error() < errs[j].Error()
})
}

func assertErrorsSliceEqual(t *testing.T, expected, actual []error) {
if len(expected) != len(actual) {
t.Fatalf("actual did not match expected. len(expected) != len(actual). expected: %v, actual: %v", expected, actual)
}

sortErrors(expected)
sortErrors(actual)

for i := range expected {
if expected[i].Error() != actual[i].Error() {
t.Fatalf("actual did not match expected. expected[%d] != actual[%d]. expected: %v, actual: %v", i, i, expected, actual)
}
}
}
9 changes: 7 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ provider "auth0" {
## Argument Reference

* `domain` - (Required) Your Auth0 domain name. It can also be sourced from the `AUTH0_DOMAIN` environment variable.
* `client_id` - (Required) Your Auth0 client ID. It can also be sourced from the `AUTH0_CLIENT_ID` environment variable.
* `client_secret` - (Required) Your Auth0 client secret. It can also be sourced from the `AUTH0_CLIENT_SECRET` environment variable.
* `client_id` - (Optional) Your Auth0 client ID. It can also be sourced from the `AUTH0_CLIENT_ID` environment variable.
* `client_secret` - (Optional) Your Auth0 client secret. It can also be sourced from the `AUTH0_CLIENT_SECRET` environment variable.
* `api_token` - (Optional) Your Auth0 [management api access token](https://auth0.com/docs/security/tokens/access-tokens/management-api-access-tokens).
It can also be sourced from the `AUTH0_API_TOKEN` environment variable. Can be
used instead of `client_id` + `client_secret`. If both are specified,
`management_token` will be used over `client_id` + `client_secret` fields.
* `debug` - (Optional) Indicates whether or not to turn on debug mode.

## Environment Variables
Expand All @@ -51,3 +55,4 @@ $ terraform plan
## Importing resources

To import Auth0 resources, you will need to know their id. You can use the [Auth0 API Explorer](https://auth0.com/docs/api/management/v2) to easily find your resource id.