diff --git a/docs/data-sources/flow.md b/docs/data-sources/flow.md new file mode 100644 index 00000000..068c087a --- /dev/null +++ b/docs/data-sources/flow.md @@ -0,0 +1,32 @@ +--- +page_title: "Data Source: auth0_flow" +description: |- + Data source to retrieve a specific Auth0 Flow by id +--- + +# Data Source: auth0_flow + +Data source to retrieve a specific Auth0 Flow by `id` + +## Example Usage + +```terraform +# An Auth0 flow loaded using its ID. +data "auth0_flow" "my_flow_data" { + id = "af_5CTYdsXHLoLXD7ZVwvFHew" +} +``` + + +## Schema + +### Required + +- `id` (String) The id of the Flow. + +### Read-Only + +- `actions` (String) Actions of the flow. +- `name` (String) Name of the flow. + + diff --git a/docs/data-sources/flow_vault_connection.md b/docs/data-sources/flow_vault_connection.md new file mode 100644 index 00000000..edfe0365 --- /dev/null +++ b/docs/data-sources/flow_vault_connection.md @@ -0,0 +1,37 @@ +--- +page_title: "Data Source: auth0_flow_vault_connection" +description: |- + Data source to retrieve a specific Auth0 Flow Vault Connection by id +--- + +# Data Source: auth0_flow_vault_connection + +Data source to retrieve a specific Auth0 Flow Vault Connection by `id` + +## Example Usage + +```terraform +# An Auth0 flow vault connection loaded using its ID. +data "auth0_flow_vault_connection" "data_connection" { + id = "ac_9m2uqjHsqs19riN9N6sZQ7" +} +``` + + +## Schema + +### Required + +- `id` (String) The id of the Flow Vault Connection. + +### Read-Only + +- `account_name` (String) Custom account name of the vault connection. +- `app_id` (String) App identifier of the vault connection. +- `environment` (String) Environment of the vault connection. +- `fingerprint` (String) Fingerprint of the vault connection. +- `name` (String) Name of the vault connection. +- `ready` (Boolean) Indicates if the vault connection is configured. +- `setup` (Map of String) Configuration of the vault connection. (Mapping information must be provided as key/value pairs) + + diff --git a/docs/data-sources/form.md b/docs/data-sources/form.md new file mode 100644 index 00000000..646e25ac --- /dev/null +++ b/docs/data-sources/form.md @@ -0,0 +1,55 @@ +--- +page_title: "Data Source: auth0_form" +description: |- + Data source to retrieve a specific Auth0 Form by id +--- + +# Data Source: auth0_form + +Data source to retrieve a specific Auth0 Form by `id` + +## Example Usage + +```terraform +# An Auth0 form loaded using its ID. +data "auth0_flow" "my_form_data" { + id = "ap_31LxRJphZF1Kqzf2zBgmgA" +} +``` + + +## Schema + +### Required + +- `id` (String) The id of the Form. + +### Read-Only + +- `ending` (String) Submission configuration of the form. (JSON encoded) +- `languages` (List of Object) Language specific configuration for the form. (see [below for nested schema](#nestedatt--languages)) +- `messages` (List of Object) Message specific configuration for the form. (see [below for nested schema](#nestedatt--messages)) +- `name` (String) Name of the form. +- `nodes` (String) Nodes of the form. (JSON encoded) +- `start` (String) Input setup of the form. (JSON encoded) +- `style` (String) Style specific configuration for the form. (JSON encoded) +- `translations` (String) Translations of the form. (JSON encoded) + + +### Nested Schema for `languages` + +Read-Only: + +- `default` (String) +- `primary` (String) + + + +### Nested Schema for `messages` + +Read-Only: + +- `custom` (String) +- `errors` (String) + + diff --git a/docs/resources/flow.md b/docs/resources/flow.md new file mode 100644 index 00000000..6e768792 --- /dev/null +++ b/docs/resources/flow.md @@ -0,0 +1,61 @@ +--- +page_title: "Resource: auth0_flow" +description: |- + With this resource, you can create and manage Flows for a tenant. +--- + +# Resource: auth0_flow + +With this resource, you can create and manage Flows for a tenant. + +## Example Usage + +```terraform +# Example: +resource "auth0_flow" "my_flow" { + actions = jsonencode([{ + action = "UPDATE_USER" + alias = "user meta data" + allow_failure = false + id = "update_user_PmSa" + mask_output = false + params = { + changes = { + user_metadata = { + full_name = "{{fields.full_name}}" + } + } + connection_id = "" # Altenative ways: (connection_id = auth0_flow_vault_connection.my_connection.id) or using terraform variables + user_id = "{{context.user.user_id}}" + } + type = "AUTH0" + }]) + name = "Flow KYC update data" +} +``` + + +## Schema + +### Required + +- `name` (String) Name of the flow. + +### Optional + +- `actions` (String) Actions of the flow. + +### Read-Only + +- `id` (String) The ID of this resource. + +## Import + +Import is supported using the following syntax: + +```shell +# This resource can be imported using the flow ID. +# +# Example: +terraform import auth0_form.my_flow "af_4JwsAjokf6DpK8xJCkTRjK" +``` diff --git a/docs/resources/flow_vault_connection.md b/docs/resources/flow_vault_connection.md new file mode 100644 index 00000000..3069664f --- /dev/null +++ b/docs/resources/flow_vault_connection.md @@ -0,0 +1,56 @@ +--- +page_title: "Resource: auth0_flow_vault_connection" +description: |- + With this resource, you can create and manage flow vault connections for a tenant. +--- + +# Resource: auth0_flow_vault_connection + +With this resource, you can create and manage flow vault connections for a tenant. + +## Example Usage + +```terraform +# Example: +resource "auth0_flow_vault_connection" "my_connection" { + app_id = "AUTH0" + name = "Auth0 M2M Connection" + setup = { + client_id = "******************" + client_secret = "*********************************" + domain = "*****************************" + type = "OAUTH_APP" + } +} +``` + + +## Schema + +### Required + +- `app_id` (String) App identifier of the vault connection. +- `name` (String) Name of the vault connection. + +### Optional + +- `account_name` (String) Custom account name of the vault connection. +- `environment` (String) Environment of the vault connection. +- `fingerprint` (String) Fingerprint of the vault connection. +- `ready` (Boolean) Indicates if the vault connection is configured. +- `setup` (Map of String, Sensitive) Configuration of the vault connection. (Mapping information must be provided as key/value pairs) + +### Read-Only + +- `id` (String) The ID of this resource. + +## Import + +Import is supported using the following syntax: + +```shell +# This resource can be imported using the flow vault connection ID. +# +# Example: +terraform import auth0_flow_vault_connection.my_connection "ac_42HT5oiobDyUs8ASwEEWK0" +``` diff --git a/docs/resources/form.md b/docs/resources/form.md new file mode 100644 index 00000000..470c759b --- /dev/null +++ b/docs/resources/form.md @@ -0,0 +1,144 @@ +--- +page_title: "Resource: auth0_form" +description: |- + With this resource, you can create and manage Forms for a tenant. +--- + +# Resource: auth0_form + +With this resource, you can create and manage Forms for a tenant. + +## Example Usage + +```terraform +# Example: +resource "auth0_form" "my_form" { + name = "My KYC Form" + + start = jsonencode({ + coordinates = { + x = 0 + y = 0 + } + next_node = "step_ggeX" + }) + nodes = jsonencode([{ + alias = "New step" + config = { + components = [{ + category = "FIELD" + config = { + max_length = 50 + min_length = 1 + multiline = false + } + id = "full_name" + label = "Your Name" + required = true + sensitive = false + type = "TEXT" + }, { + category = "BLOCK" + config = { + text = "Continue" + } + id = "next_button_3FbA" + type = "NEXT_BUTTON" + }] + next_node = "$ending" + } + coordinates = { + x = 500 + y = 0 + } + id = "step_ggeX" + type = "STEP" + }]) + ending = jsonencode({ + after_submit = { + flow_id = "" # Altenative ways: (flow_id = auth0_flow.my_flow.id) or using terraform variables + } + coordinates = { + x = 1250 + y = 0 + } + resume_flow = true + }) + + style = jsonencode({ + css = "h1 {\n color: white;\n text-align: center;\n}" + }) + + translations = jsonencode({ + es = { + components = { + rich_text_uctu = { + config = { + content = "

Help us verify your personal information

We want to learn more about you so that we can validate and protect your account...

" + } + } + } + messages = { + custom = {} + errors = { + ERR_ACCEPTANCE_REQUIRED = "Por favor, marca este campo para continuar." + } + } + } + }) + + languages { + default = "en" + primary = "en" + } +} +``` + + +## Schema + +### Required + +- `name` (String) Name of the form. + +### Optional + +- `ending` (String) Submission configuration of the form. (JSON encoded) +- `languages` (Block List) Language specific configuration for the form. (see [below for nested schema](#nestedblock--languages)) +- `messages` (Block List) Message specific configuration for the form. (see [below for nested schema](#nestedblock--messages)) +- `nodes` (String) Nodes of the form. (JSON encoded) +- `start` (String) Input setup of the form. (JSON encoded) +- `style` (String) Style specific configuration for the form. (JSON encoded) +- `translations` (String) Translations of the form. (JSON encoded) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `languages` + +Optional: + +- `default` (String) Default language for the form. +- `primary` (String) Primary language for the form. + + + +### Nested Schema for `messages` + +Optional: + +- `custom` (String) Custom message for the form. (JSON encoded) +- `errors` (String) Error message for the form. (JSON encoded) + +## Import + +Import is supported using the following syntax: + +```shell +# This resource can be imported using the form ID. +# +# Example: +terraform import auth0_form.my_form "ap_ojkKbiPMG6J5E5VCKdeCzK" +``` diff --git a/examples/data-sources/auth0_flow/data-source.tf b/examples/data-sources/auth0_flow/data-source.tf new file mode 100644 index 00000000..316d4391 --- /dev/null +++ b/examples/data-sources/auth0_flow/data-source.tf @@ -0,0 +1,4 @@ +# An Auth0 flow loaded using its ID. +data "auth0_flow" "my_flow_data" { + id = "af_5CTYdsXHLoLXD7ZVwvFHew" +} diff --git a/examples/data-sources/auth0_flow_vault_connection/data-source.tf b/examples/data-sources/auth0_flow_vault_connection/data-source.tf new file mode 100644 index 00000000..30b57038 --- /dev/null +++ b/examples/data-sources/auth0_flow_vault_connection/data-source.tf @@ -0,0 +1,4 @@ +# An Auth0 flow vault connection loaded using its ID. +data "auth0_flow_vault_connection" "data_connection" { + id = "ac_9m2uqjHsqs19riN9N6sZQ7" +} diff --git a/examples/data-sources/auth0_form/data-source.tf b/examples/data-sources/auth0_form/data-source.tf new file mode 100644 index 00000000..7df013c4 --- /dev/null +++ b/examples/data-sources/auth0_form/data-source.tf @@ -0,0 +1,4 @@ +# An Auth0 form loaded using its ID. +data "auth0_flow" "my_form_data" { + id = "ap_31LxRJphZF1Kqzf2zBgmgA" +} diff --git a/examples/resources/auth0_flow/import.sh b/examples/resources/auth0_flow/import.sh new file mode 100644 index 00000000..05119366 --- /dev/null +++ b/examples/resources/auth0_flow/import.sh @@ -0,0 +1,4 @@ +# This resource can be imported using the flow ID. +# +# Example: +terraform import auth0_form.my_flow "af_4JwsAjokf6DpK8xJCkTRjK" diff --git a/examples/resources/auth0_flow/resource.tf b/examples/resources/auth0_flow/resource.tf new file mode 100644 index 00000000..70214e18 --- /dev/null +++ b/examples/resources/auth0_flow/resource.tf @@ -0,0 +1,22 @@ +# Example: +resource "auth0_flow" "my_flow" { + actions = jsonencode([{ + action = "UPDATE_USER" + alias = "user meta data" + allow_failure = false + id = "update_user_PmSa" + mask_output = false + params = { + changes = { + user_metadata = { + full_name = "{{fields.full_name}}" + } + } + connection_id = "" # Altenative ways: (connection_id = auth0_flow_vault_connection.my_connection.id) or using terraform variables + user_id = "{{context.user.user_id}}" + } + type = "AUTH0" + }]) + name = "Flow KYC update data" +} + diff --git a/examples/resources/auth0_flow_vault_connection/import.sh b/examples/resources/auth0_flow_vault_connection/import.sh new file mode 100644 index 00000000..10d38e6d --- /dev/null +++ b/examples/resources/auth0_flow_vault_connection/import.sh @@ -0,0 +1,4 @@ +# This resource can be imported using the flow vault connection ID. +# +# Example: +terraform import auth0_flow_vault_connection.my_connection "ac_42HT5oiobDyUs8ASwEEWK0" diff --git a/examples/resources/auth0_flow_vault_connection/resource.tf b/examples/resources/auth0_flow_vault_connection/resource.tf new file mode 100644 index 00000000..4652a752 --- /dev/null +++ b/examples/resources/auth0_flow_vault_connection/resource.tf @@ -0,0 +1,11 @@ +# Example: +resource "auth0_flow_vault_connection" "my_connection" { + app_id = "AUTH0" + name = "Auth0 M2M Connection" + setup = { + client_id = "******************" + client_secret = "*********************************" + domain = "*****************************" + type = "OAUTH_APP" + } +} diff --git a/examples/resources/auth0_form/import.sh b/examples/resources/auth0_form/import.sh new file mode 100644 index 00000000..0769c351 --- /dev/null +++ b/examples/resources/auth0_form/import.sh @@ -0,0 +1,4 @@ +# This resource can be imported using the form ID. +# +# Example: +terraform import auth0_form.my_form "ap_ojkKbiPMG6J5E5VCKdeCzK" diff --git a/examples/resources/auth0_form/resource.tf b/examples/resources/auth0_form/resource.tf new file mode 100644 index 00000000..8b977453 --- /dev/null +++ b/examples/resources/auth0_form/resource.tf @@ -0,0 +1,81 @@ +# Example: +resource "auth0_form" "my_form" { + name = "My KYC Form" + + start = jsonencode({ + coordinates = { + x = 0 + y = 0 + } + next_node = "step_ggeX" + }) + nodes = jsonencode([{ + alias = "New step" + config = { + components = [{ + category = "FIELD" + config = { + max_length = 50 + min_length = 1 + multiline = false + } + id = "full_name" + label = "Your Name" + required = true + sensitive = false + type = "TEXT" + }, { + category = "BLOCK" + config = { + text = "Continue" + } + id = "next_button_3FbA" + type = "NEXT_BUTTON" + }] + next_node = "$ending" + } + coordinates = { + x = 500 + y = 0 + } + id = "step_ggeX" + type = "STEP" + }]) + ending = jsonencode({ + after_submit = { + flow_id = "" # Altenative ways: (flow_id = auth0_flow.my_flow.id) or using terraform variables + } + coordinates = { + x = 1250 + y = 0 + } + resume_flow = true + }) + + style = jsonencode({ + css = "h1 {\n color: white;\n text-align: center;\n}" + }) + + translations = jsonencode({ + es = { + components = { + rich_text_uctu = { + config = { + content = "

Help us verify your personal information

We want to learn more about you so that we can validate and protect your account...

" + } + } + } + messages = { + custom = {} + errors = { + ERR_ACCEPTANCE_REQUIRED = "Por favor, marca este campo para continuar." + } + } + } + }) + + languages { + default = "en" + primary = "en" + } +} diff --git a/internal/auth0/flow/data_source.go b/internal/auth0/flow/data_source.go new file mode 100644 index 00000000..97e83a12 --- /dev/null +++ b/internal/auth0/flow/data_source.go @@ -0,0 +1,44 @@ +package flow + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/auth0/terraform-provider-auth0/internal/config" + internalSchema "github.com/auth0/terraform-provider-auth0/internal/schema" +) + +// NewDataSource will return a new auth0_flow data source. +func NewDataSource() *schema.Resource { + return &schema.Resource{ + ReadContext: readFlowForDataSource, + Description: "Data source to retrieve a specific Auth0 Flow by `id`", + Schema: dataSourceSchema(), + } +} + +func dataSourceSchema() map[string]*schema.Schema { + dataSourceSchema := internalSchema.TransformResourceToDataSource(NewResource().Schema) + dataSourceSchema["id"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "The ID of the Flow.", + } + dataSourceSchema["id"].Description = "The id of the Flow." + return dataSourceSchema +} + +func readFlowForDataSource(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + id := data.Get("id").(string) + data.SetId(id) + flow, err := api.Flow.Read(ctx, id) + if err != nil { + return diag.FromErr(err) + } + + err = flattenFlow(data, flow) + return diag.FromErr(err) +} diff --git a/internal/auth0/flow/data_source_test.go b/internal/auth0/flow/data_source_test.go new file mode 100644 index 00000000..aef53363 --- /dev/null +++ b/internal/auth0/flow/data_source_test.go @@ -0,0 +1,56 @@ +package flow_test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + + "github.com/auth0/terraform-provider-auth0/internal/acctest" +) + +const testAGivenFlow = ` +resource "auth0_flow" "my_flow" { + name = "test-flow-{{.testName}}" +} +` + +const testDataResourceWithoutID = testAGivenFlow + ` +data "auth0_flow" "my_flow" { + depends_on = [resource.auth0_flow.my_flow] +}` + +const testDataResourceWithInvalidID = testAGivenFlow + ` +data "auth0_flow" "my_flow" { + depends_on = [resource.auth0_flow.my_flow] + id = "af_bskks8aGbiq7qS13umnuvX" +}` + +const testDataResourceWithValidID = testAGivenFlow + ` +data "auth0_flow" "my_flow" { + depends_on = [resource.auth0_flow.my_flow] + id = resource.auth0_flow.my_flow.id +}` + +func TestAccFlowDataSource(t *testing.T) { + acctest.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: acctest.ParseTestName(testDataResourceWithoutID, t.Name()), + ExpectError: regexp.MustCompile("The argument \"id\" is required, but no definition was found."), + }, + { + Config: acctest.ParseTestName(testDataResourceWithInvalidID, t.Name()), + ExpectError: regexp.MustCompile( + `Error: 404 Not Found`, + ), + }, + { + Config: acctest.ParseTestName(testDataResourceWithValidID, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.auth0_flow.my_flow", "name"), + ), + }, + }, + }) +} diff --git a/internal/auth0/flow/data_source_vault_connection.go b/internal/auth0/flow/data_source_vault_connection.go new file mode 100644 index 00000000..de5269ab --- /dev/null +++ b/internal/auth0/flow/data_source_vault_connection.go @@ -0,0 +1,44 @@ +package flow + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/auth0/terraform-provider-auth0/internal/config" + internalSchema "github.com/auth0/terraform-provider-auth0/internal/schema" +) + +// NewVaultConnectionDataSource will return a new auth0_flow_vault_connection data source. +func NewVaultConnectionDataSource() *schema.Resource { + return &schema.Resource{ + ReadContext: readVaultConnectionForDataSource, + Description: "Data source to retrieve a specific Auth0 Flow Vault Connection by `id`", + Schema: getVaultConnectionDataSourceSchema(), + } +} + +func getVaultConnectionDataSourceSchema() map[string]*schema.Schema { + dataSourceSchema := internalSchema.TransformResourceToDataSource(NewVaultConnectionResource().Schema) + dataSourceSchema["id"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "The ID of the Flow Vault Connection.", + } + dataSourceSchema["id"].Description = "The id of the Flow Vault Connection." + return dataSourceSchema +} + +func readVaultConnectionForDataSource(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + id := data.Get("id").(string) + data.SetId(id) + vaultConnection, err := api.Flow.Vault.GetConnection(ctx, id) + if err != nil { + return diag.FromErr(err) + } + + err = flattenVaultConnection(data, vaultConnection) + return diag.FromErr(err) +} diff --git a/internal/auth0/flow/data_source_vault_connection_test.go b/internal/auth0/flow/data_source_vault_connection_test.go new file mode 100644 index 00000000..437b6bdd --- /dev/null +++ b/internal/auth0/flow/data_source_vault_connection_test.go @@ -0,0 +1,57 @@ +package flow_test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + + "github.com/auth0/terraform-provider-auth0/internal/acctest" +) + +const testAGivenVaultConnection = ` +resource "auth0_flow_vault_connection" "my_connection" { + name = "test-vault-connection" + app_id = "HTTP" +} +` + +const testDataResourceVaultConnectionWithoutID = testAGivenVaultConnection + ` +data "auth0_flow_vault_connection" "my_connection" { + depends_on = [resource.auth0_flow_vault_connection.my_connection] +}` + +const testDataResourceVaultConnectionWithInvalidID = testAGivenVaultConnection + ` +data "auth0_flow_vault_connection" "my_connection" { + depends_on = [resource.auth0_flow_vault_connection.my_connection] + id = "ac_5Cy8N47rNvNixgNBShK8fK" +}` + +const testDataResourceVaultConnectionWithValidID = testAGivenVaultConnection + ` +data "auth0_flow_vault_connection" "my_connection" { + depends_on = [resource.auth0_flow_vault_connection.my_connection] + id = resource.auth0_flow_vault_connection.my_connection.id +}` + +func TestAccVaultConnectionDataSource(t *testing.T) { + acctest.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: acctest.ParseTestName(testDataResourceVaultConnectionWithoutID, t.Name()), + ExpectError: regexp.MustCompile("The argument \"id\" is required, but no definition was found."), + }, + { + Config: acctest.ParseTestName(testDataResourceVaultConnectionWithInvalidID, t.Name()), + ExpectError: regexp.MustCompile( + `Error: 404 Not Found`, + ), + }, + { + Config: acctest.ParseTestName(testDataResourceVaultConnectionWithValidID, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.auth0_flow_vault_connection.my_connection", "name"), + ), + }, + }, + }) +} diff --git a/internal/auth0/flow/expand.go b/internal/auth0/flow/expand.go new file mode 100644 index 00000000..64588ebf --- /dev/null +++ b/internal/auth0/flow/expand.go @@ -0,0 +1,103 @@ +package flow + +import ( + "encoding/json" + "fmt" + + "github.com/auth0/go-auth0/management" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/auth0/terraform-provider-auth0/internal/value" +) + +func expandFlow(data *schema.ResourceData) (*management.Flow, error) { + config := data.GetRawConfig() + + flow := &management.Flow{ + Name: value.String(config.GetAttr("name")), + Actions: expandInterfaceArray(data, "actions"), + } + + return flow, nil +} + +func expandVaultConnection(data *schema.ResourceData) (*management.FlowVaultConnection, error) { + cfg := data.GetRawConfig() + + vaultConnection := &management.FlowVaultConnection{} + + vaultConnection.Name = value.String(cfg.GetAttr("name")) + + if data.HasChange("app_id") { + vaultConnection.AppID = value.String(cfg.GetAttr("app_id")) + } + + if data.HasChange("environment") { + vaultConnection.Environment = value.String(cfg.GetAttr("environment")) + } + + if data.HasChange("setup") { + setup, err := expandStringInterfaceMap(data, "setup") + if err != nil { + return nil, err + } + vaultConnection.Setup = &setup + } + + if data.HasChange("account_name") { + vaultConnection.AccountName = value.String(cfg.GetAttr("account_name")) + } + + if data.HasChange("ready") { + vaultConnection.Ready = value.Bool(cfg.GetAttr("ready")) + } + + return vaultConnection, nil +} + +func expandStringInterfaceMap(data *schema.ResourceData, key string) (map[string]interface{}, error) { + raw := data.Get(key) + if raw == nil { + return nil, nil + } + + if m, ok := raw.(map[string]interface{}); ok { + return m, nil + } + + return nil, fmt.Errorf("expected map for %s, got %T", key, raw) +} + +func expandInterfaceArray(d *schema.ResourceData, key string) []interface{} { + oldMetadata, newMetadata := d.GetChange(key) + result := make([]interface{}, 0) + if oldMetadata == "" && newMetadata == "" { + return result + } + + if oldMetadata == "" { + if newMetadataStr, ok := newMetadata.(string); ok { + var newMetadataArr []interface{} + if err := json.Unmarshal([]byte(newMetadataStr), &newMetadataArr); err != nil { + return nil + } + return newMetadataArr + } + return result + } + + if newMetadata == "" { + return result + } + + b, err := json.Marshal(newMetadata) + if err != nil { + return nil + } + + if err := json.Unmarshal(b, &result); err != nil { + return nil + } + + return result +} diff --git a/internal/auth0/flow/flatten.go b/internal/auth0/flow/flatten.go new file mode 100644 index 00000000..057a8186 --- /dev/null +++ b/internal/auth0/flow/flatten.go @@ -0,0 +1,44 @@ +package flow + +import ( + "encoding/json" + + "github.com/auth0/go-auth0/management" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func flattenFlow(data *schema.ResourceData, form *management.Flow) error { + result := multierror.Append( + data.Set("name", form.GetName()), + data.Set("actions", flattenFlowAction(form.Actions)), + ) + return result.ErrorOrNil() +} + +func flattenFlowAction(formNodes []interface{}) string { + if formNodes == nil { + return "" + } + + nodeBytes, err := json.Marshal(formNodes) + if err != nil { + return "" + } + + return string(nodeBytes) +} + +func flattenVaultConnection(data *schema.ResourceData, vaultConnection *management.FlowVaultConnection) error { + result := multierror.Append( + data.Set("name", vaultConnection.GetName()), + data.Set("app_id", vaultConnection.GetAppID()), + data.Set("environment", vaultConnection.GetEnvironment()), + data.Set("setup", vaultConnection.GetSetup()), + data.Set("account_name", vaultConnection.GetAccountName()), + data.Set("ready", vaultConnection.GetReady()), + data.Set("fingerprint", vaultConnection.GetFingerprint()), + ) + + return result.ErrorOrNil() +} diff --git a/internal/auth0/flow/resource.go b/internal/auth0/flow/resource.go new file mode 100644 index 00000000..41c6d499 --- /dev/null +++ b/internal/auth0/flow/resource.go @@ -0,0 +1,94 @@ +package flow + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + + "github.com/auth0/terraform-provider-auth0/internal/config" + internalError "github.com/auth0/terraform-provider-auth0/internal/error" +) + +// NewResource will return a new auth0_flow resource. +func NewResource() *schema.Resource { + return &schema.Resource{ + CreateContext: createFlow, + ReadContext: readFlow, + UpdateContext: updateFlow, + DeleteContext: deleteFlow, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Description: "With this resource, you can create and manage Flows for a tenant.", + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the flow.", + }, + "actions": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + Description: "Actions of the flow.", + }, + }, + } +} + +func createFlow(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + flow, err := expandFlow(data) + if err != nil { + return diag.FromErr(err) + } + + if err := api.Flow.Create(ctx, flow); err != nil { + return diag.FromErr(err) + } + + data.SetId(flow.GetID()) + + return readFlow(ctx, data, meta) +} + +func readFlow(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + flow, err := api.Flow.Read(ctx, data.Id()) + if err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return diag.FromErr(flattenFlow(data, flow)) +} + +func updateFlow(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + flow, err := expandFlow(data) + if err != nil { + return diag.FromErr(err) + } + + if err := api.Flow.Update(ctx, data.Id(), flow); err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return readFlow(ctx, data, meta) +} + +func deleteFlow(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + if err := api.Flow.Delete(ctx, data.Id()); err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return nil +} diff --git a/internal/auth0/flow/resource_test.go b/internal/auth0/flow/resource_test.go new file mode 100644 index 00000000..fb6f4152 --- /dev/null +++ b/internal/auth0/flow/resource_test.go @@ -0,0 +1,70 @@ +package flow_test + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + + "github.com/auth0/terraform-provider-auth0/internal/acctest" +) + +const testFlowCreateInvalidAction = ` +resource "auth0_flow" "my_flow" { + name = "updated-test-flow-{{.testName}}" + actions = "invalid-json" +} +` + +const testFlowCreate = ` +resource "auth0_flow" "my_flow" { + name = "test-flow-{{.testName}}" + +} +` + +const testFlowUpdate = ` +resource "auth0_flow" "my_flow" { + name = "updated-test-flow-{{.testName}}" +} +` + +const testFlowDelete = ` +resource "auth0_flow" "my_flow" { + name = "updated-test-flow-{{.testName}}" +} +` + +func TestAccFlow(t *testing.T) { + acctest.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: acctest.ParseTestName(testFlowCreateInvalidAction, t.Name()), + ExpectError: regexp.MustCompile(`contains an invalid JSON`), + }, + { + Config: acctest.ParseTestName(testFlowCreate, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_flow.my_flow", "name", fmt.Sprintf("test-flow-%s", t.Name())), + resource.TestCheckResourceAttrSet("auth0_flow.my_flow", "id"), + ), + }, + { + Config: acctest.ParseTestName(testFlowUpdate, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_flow.my_flow", "name", fmt.Sprintf("updated-test-flow-%s", t.Name())), + resource.TestCheckResourceAttrSet("auth0_flow.my_flow", "id"), + ), + }, + { + Config: acctest.ParseTestName(testFlowDelete, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_flow.my_flow", "name", fmt.Sprintf("updated-test-flow-%s", t.Name())), + resource.TestCheckResourceAttrSet("auth0_flow.my_flow", "id"), + ), + Destroy: true, + }, + }, + }) +} diff --git a/internal/auth0/flow/resource_vault_connection.go b/internal/auth0/flow/resource_vault_connection.go new file mode 100644 index 00000000..118b82a9 --- /dev/null +++ b/internal/auth0/flow/resource_vault_connection.go @@ -0,0 +1,149 @@ +package flow + +import ( + "context" + "encoding/json" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + + "github.com/auth0/terraform-provider-auth0/internal/config" + internalError "github.com/auth0/terraform-provider-auth0/internal/error" +) + +// NewVaultConnectionResource will return a new auth0_flow_vault_connection resource. +func NewVaultConnectionResource() *schema.Resource { + return &schema.Resource{ + CreateContext: createVaultConnection, + ReadContext: readVaultConnection, + UpdateContext: updateVaultConnection, + DeleteContext: deleteVaultConnection, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Description: "With this resource, you can create and manage flow vault connections for a tenant.", + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the vault connection.", + }, + "app_id": { + Type: schema.TypeString, + Required: true, + Description: "App identifier of the vault connection.", + ValidateFunc: validation.StringInSlice([]string{ + "ACTIVECAMPAIGN", + "AIRTABLE", + "AUTH0", + "BIGQUERY", + "CLEARBIT", + "DOCUSIGN", + "GOOGLE_SHEETS", + "HTTP", + "HUBSPOT", + "JWT", + "MAILCHIMP", + "MAILJET", + "PIPEDRIVE", + "SALESFORCE", + "SENDGRID", + "SLACK", + "STRIPE", + "TELEGRAM", + "TWILIO", + "WHATSAPP", + "ZAPIER", + }, false), + }, + "environment": { + Type: schema.TypeString, + Optional: true, + Description: "Environment of the vault connection.", + }, + "setup": { + Type: schema.TypeMap, + Optional: true, + Description: "Configuration of the vault connection. (Mapping information must be provided as key/value pairs)", + Sensitive: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Custom account name of the vault connection.", + }, + "ready": { + Type: schema.TypeBool, + Optional: true, + Description: "Indicates if the vault connection is configured.", + }, + "fingerprint": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Fingerprint of the vault connection.", + }, + }, + } +} + +func createVaultConnection(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + vaultConnection, err := expandVaultConnection(data) + if err != nil { + return diag.FromErr(err) + } + + if err := api.Flow.Vault.CreateConnection(ctx, vaultConnection); err != nil { + return diag.FromErr(err) + } + + data.SetId(vaultConnection.GetID()) + + return readVaultConnection(ctx, data, meta) +} + +func readVaultConnection(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + vaultConnection, err := api.Flow.Vault.GetConnection(ctx, data.Id()) + if err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return diag.FromErr(flattenVaultConnection(data, vaultConnection)) +} + +func updateVaultConnection(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + vaultConnection, err := expandVaultConnection(data) + if err != nil { + return diag.FromErr(err) + } + + d, _ := json.Marshal(vaultConnection) + log.Println("vaultConnection", string(d)) + + if err := api.Flow.Vault.UpdateConnection(ctx, data.Id(), vaultConnection); err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return readVaultConnection(ctx, data, meta) +} + +func deleteVaultConnection(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + if err := api.Flow.Vault.DeleteConnection(ctx, data.Id()); err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return nil +} diff --git a/internal/auth0/flow/resource_vault_connection_test.go b/internal/auth0/flow/resource_vault_connection_test.go new file mode 100644 index 00000000..45629893 --- /dev/null +++ b/internal/auth0/flow/resource_vault_connection_test.go @@ -0,0 +1,56 @@ +package flow_test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + + "github.com/auth0/terraform-provider-auth0/internal/acctest" +) + +const testVaultConnectionCreateInvalidAppID = ` +resource "auth0_flow_vault_connection" "my_vault_connection" { + name = "test-v-connection" + app_id = "INVALID" +} +` + +const testVaultConnectionCreate = ` +resource "auth0_flow_vault_connection" "my_vault_connection" { + name = "test-v-connection" + app_id = "HTTP" +} +` + +const testVaultConnectionUpdate = ` +resource "auth0_flow_vault_connection" "my_vault_connection" { + name = "updated-test-v-connection" + app_id = "HTTP" +} +` + +func TestAccVaultConnection(t *testing.T) { + acctest.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: acctest.ParseTestName(testVaultConnectionCreateInvalidAppID, t.Name()), + ExpectError: regexp.MustCompile(`app_id to be one of`), + }, + { + Config: acctest.ParseTestName(testVaultConnectionCreate, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_flow_vault_connection.my_vault_connection", "name", "test-v-connection"), + resource.TestCheckResourceAttrSet("auth0_flow_vault_connection.my_vault_connection", "id"), + ), + }, + { + Config: acctest.ParseTestName(testVaultConnectionUpdate, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_flow_vault_connection.my_vault_connection", "name", "updated-test-v-connection"), + resource.TestCheckResourceAttrSet("auth0_flow_vault_connection.my_vault_connection", "id"), + ), + }, + }, + }) +} diff --git a/internal/auth0/form/data_source.go b/internal/auth0/form/data_source.go new file mode 100644 index 00000000..a6994619 --- /dev/null +++ b/internal/auth0/form/data_source.go @@ -0,0 +1,44 @@ +package form + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/auth0/terraform-provider-auth0/internal/config" + internalSchema "github.com/auth0/terraform-provider-auth0/internal/schema" +) + +// NewDataSource will return a new auth0_form data source. +func NewDataSource() *schema.Resource { + return &schema.Resource{ + ReadContext: readFormDataSource, + Description: "Data source to retrieve a specific Auth0 Form by `id`", + Schema: dataSourceSchema(), + } +} + +func dataSourceSchema() map[string]*schema.Schema { + dataSourceSchema := internalSchema.TransformResourceToDataSource(NewResource().Schema) + dataSourceSchema["id"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "The ID of the Form.", + } + dataSourceSchema["id"].Description = "The id of the Form." + return dataSourceSchema +} + +func readFormDataSource(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + id := data.Get("id").(string) + data.SetId(id) + form, err := api.Form.Read(ctx, id) + if err != nil { + return diag.FromErr(err) + } + + err = flattenForm(data, form) + return diag.FromErr(err) +} diff --git a/internal/auth0/form/data_source_test.go b/internal/auth0/form/data_source_test.go new file mode 100644 index 00000000..12cabe01 --- /dev/null +++ b/internal/auth0/form/data_source_test.go @@ -0,0 +1,58 @@ +package form_test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + + "github.com/auth0/terraform-provider-auth0/internal/acctest" +) + +const testAGivenForm = ` +resource "auth0_form" "my_form" { + name = "test-form-{{.testName}}" + ending = jsonencode({resume_flow = true}) + languages { primary = "en" } +} +` + +const testDataResourceWithoutID = testAGivenForm + ` +data "auth0_form" "my_form" { + depends_on = [resource.auth0_form.my_form] +}` + +const testDataResourceWithInvalidID = testAGivenForm + ` +data "auth0_form" "my_form" { + depends_on = [resource.auth0_form.my_form] + id = "ap_9AXxPP59pJx5ZtA471cSBx" +}` + +const testDataResourceWithValidID = testAGivenForm + ` +data "auth0_form" "my_form" { + depends_on = [resource.auth0_form.my_form] + id = resource.auth0_form.my_form.id +}` + +func TestAccFormDataSource(t *testing.T) { + acctest.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: acctest.ParseTestName(testDataResourceWithoutID, t.Name()), + ExpectError: regexp.MustCompile("The argument \"id\" is required, but no definition was found."), + }, + { + Config: acctest.ParseTestName(testDataResourceWithInvalidID, t.Name()), + ExpectError: regexp.MustCompile( + `Error: 404 Not Found`, + ), + }, + { + Config: acctest.ParseTestName(testDataResourceWithValidID, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.auth0_form.my_form", "name"), + ), + }, + }, + }) +} diff --git a/internal/auth0/form/expand.go b/internal/auth0/form/expand.go new file mode 100644 index 00000000..3bcbfadc --- /dev/null +++ b/internal/auth0/form/expand.go @@ -0,0 +1,189 @@ +package form + +import ( + "encoding/json" + + "github.com/auth0/go-auth0/management" + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" + + "github.com/auth0/terraform-provider-auth0/internal/value" +) + +func expandForm(data *schema.ResourceData) (*management.Form, error) { + cfg := data.GetRawConfig() + + form := &management.Form{} + + form.Name = value.String(cfg.GetAttr("name")) + form.Languages = expandFomLanguages(cfg.GetAttr("languages")) + form.Messages = expandFomMessages(cfg.GetAttr("messages")) + + if data.HasChange("translations") { + translations, err := expandStringInterfaceMap(data, "translations") + if err != nil { + return nil, err + } + form.Translations = &translations + } + + if data.HasChange("style") { + style, err := expandStringInterfaceMap(data, "style") + if err != nil { + return nil, err + } + form.Style = &style + } + + if data.HasChange("start") { + start, err := expandStringInterfaceMap(data, "start") + if err != nil { + return nil, err + } + form.Start = &start + } + + if data.HasChange("ending") { + ending, err := expandStringInterfaceMap(data, "ending") + if err != nil { + return nil, err + } + form.Ending = &ending + } + + if data.HasChange("nodes") { + form.Nodes = expandInterfaceArray(data, "nodes") + } + + return form, nil +} + +func expandFomLanguages(languages cty.Value) *management.FormLanguages { + if languages.IsNull() { + return nil + } + + formLanguages := &management.FormLanguages{} + + languages.ForEachElement(func(_ cty.Value, language cty.Value) (stop bool) { + formLanguages.Primary = value.String(language.GetAttr("primary")) + formLanguages.Default = value.String(language.GetAttr("default")) + return stop + }) + + return formLanguages +} + +func expandFomMessages(messages cty.Value) *management.FormMessages { + if messages.IsNull() { + return nil + } + + formMessages := &management.FormMessages{} + + messages.ForEachElement(func(_ cty.Value, message cty.Value) (stop bool) { + if message.GetAttr("custom").IsNull() { + formMessages.Custom = nil + } else { + formMessages.Custom = convertToInterfaceMap(message.GetAttr("custom")) + } + + if message.GetAttr("errors").IsNull() { + formMessages.Errors = nil + } else { + formMessages.Errors = convertToInterfaceMap(message.GetAttr("errors")) + } + + return stop + }) + + return formMessages +} + +func expandInterfaceArray(d *schema.ResourceData, key string) []interface{} { + oldMetadata, newMetadata := d.GetChange(key) + result := make([]interface{}, 0) + if oldMetadata == "" && newMetadata == "" { + return result + } + + if oldMetadata == "" { + if newMetadataStr, ok := newMetadata.(string); ok { + var newMetadataArr []interface{} + if err := json.Unmarshal([]byte(newMetadataStr), &newMetadataArr); err != nil { + return nil + } + return newMetadataArr + } + return result + } + + if newMetadata == "" { + return result + } + + b, err := json.Marshal(newMetadata) + if err != nil { + return nil + } + + if err := json.Unmarshal(b, &result); err != nil { + return nil + } + + return result +} + +func expandStringInterfaceMap(data *schema.ResourceData, key string) (map[string]interface{}, error) { + oldMetadata, newMetadata := data.GetChange(key) + if oldMetadata == "" { + return value.MapFromJSON(data.GetRawConfig().GetAttr(key)) + } + + if newMetadata == "" { + return map[string]interface{}{}, nil + } + + oldMap, err := structure.ExpandJsonFromString(oldMetadata.(string)) + if err != nil { + return map[string]interface{}{}, err + } + + newMap, err := structure.ExpandJsonFromString(newMetadata.(string)) + if err != nil { + return map[string]interface{}{}, err + } + + for key := range oldMap { + if _, ok := newMap[key]; !ok { + newMap[key] = nil + } + } + + return newMap, nil +} + +func convertToInterfaceMap(rawValue cty.Value) *map[string]interface{} { + if rawValue.IsNull() || !rawValue.CanIterateElements() { + return nil + } + + m := make(map[string]interface{}) + for key, value := range rawValue.AsValueMap() { + if value.IsNull() { + continue + } + m[key] = value + } + + return &m +} + +func isNodeEmpty(data *schema.ResourceData) bool { + if !data.IsNewResource() && !data.HasChange("nodes") { + return false + } + nodes := expandInterfaceArray(data, "nodes") + return len(nodes) == 0 +} diff --git a/internal/auth0/form/flatten.go b/internal/auth0/form/flatten.go new file mode 100644 index 00000000..5a13d1ae --- /dev/null +++ b/internal/auth0/form/flatten.go @@ -0,0 +1,124 @@ +package form + +import ( + "encoding/json" + + "github.com/auth0/go-auth0/management" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" +) + +func flattenForm(data *schema.ResourceData, form *management.Form) error { + formStyle, err := structure.FlattenJsonToString(form.GetStyle()) + if err != nil { + return err + } + + formTranslations, err := structure.FlattenJsonToString(form.GetTranslations()) + if err != nil { + return err + } + + result := multierror.Append( + data.Set("name", form.Name), + ) + if form.Languages != nil { + result = multierror.Append(result, data.Set("languages", flattenFormLanguages(form.Languages))) + } + if formStyle != "" { + result = multierror.Append(result, data.Set("style", formStyle)) + } + if form.Messages != nil { + result = multierror.Append(result, data.Set("messages", flattenFormMessages(form.Messages))) + } + if formTranslations != "" { + result = multierror.Append(result, data.Set("translations", formTranslations)) + } + if form.Start != nil { + result = multierror.Append(result, data.Set("start", flattenFormStart(form.Start))) + } + if len(form.Nodes) > 0 { + result = multierror.Append(result, data.Set("nodes", flattenFormNodes(form.Nodes))) + } + if form.Ending != nil { + result = multierror.Append(result, data.Set("ending", flattenFormEnding(form.Ending))) + } + + return result.ErrorOrNil() +} + +func flattenFormLanguages(formLanguages *management.FormLanguages) []interface{} { + if formLanguages == nil { + return nil + } + + return []interface{}{ + map[string]interface{}{ + "primary": formLanguages.Primary, + "default": formLanguages.Default, + }, + } +} + +func flattenFormMessages(formMessages *management.FormMessages) []interface{} { + if formMessages == nil { + return nil + } + + formMessagesError, err := structure.FlattenJsonToString(formMessages.GetErrors()) + if err != nil { + return nil + } + + formMessagesCustom, err := structure.FlattenJsonToString(formMessages.GetCustom()) + if err != nil { + return nil + } + + return []interface{}{ + map[string]interface{}{ + "errors": formMessagesError, + "custom": formMessagesCustom, + }, + } +} + +func flattenFormStart(formStart *map[string]interface{}) string { + if formStart == nil { + return "" + } + + formBytes, err := json.Marshal(formStart) + if err != nil { + return "" + } + + return string(formBytes) +} + +func flattenFormNodes(formNodes []interface{}) string { + if formNodes == nil { + return "" + } + + nodeBytes, err := json.Marshal(formNodes) + if err != nil { + return "" + } + + return string(nodeBytes) +} + +func flattenFormEnding(formEnding *map[string]interface{}) string { + if formEnding == nil { + return "" + } + + formBytes, err := json.Marshal(formEnding) + if err != nil { + return "" + } + + return string(formBytes) +} diff --git a/internal/auth0/form/resource.go b/internal/auth0/form/resource.go new file mode 100644 index 00000000..81e86351 --- /dev/null +++ b/internal/auth0/form/resource.go @@ -0,0 +1,186 @@ +package form + +import ( + "context" + "net/http" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + + "github.com/auth0/terraform-provider-auth0/internal/config" + internalError "github.com/auth0/terraform-provider-auth0/internal/error" +) + +// NewResource will return a new auth0_form resource. +func NewResource() *schema.Resource { + return &schema.Resource{ + CreateContext: createForm, + ReadContext: readForm, + UpdateContext: updateForm, + DeleteContext: deleteForm, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Description: "With this resource, you can create and manage Forms for a tenant.", + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the form.", + }, + "translations": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + Description: "Translations of the form. (JSON encoded)", + }, + "style": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + Description: "Style specific configuration for the form. (JSON encoded)", + }, + "start": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + Description: "Input setup of the form. (JSON encoded)", + }, + "nodes": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + Description: "Nodes of the form. (JSON encoded)", + }, + "ending": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + Description: "Submission configuration of the form. (JSON encoded)", + DefaultFunc: func() (interface{}, error) { + return `{"resume_flow":true}`, nil + }, + }, + "languages": formLanguageSchema, + "messages": formMessagesSchema, + }, + } +} + +var formLanguageSchema = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Description: "Language specific configuration for the form.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default": { + Type: schema.TypeString, + Optional: true, + Description: "Default language for the form.", + }, + "primary": { + Type: schema.TypeString, + Required: true, + Description: "Primary language for the form.", + DefaultFunc: func() (interface{}, error) { + return "en", nil + }, + }, + }, + }, +} + +var formMessagesSchema = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Description: "Message specific configuration for the form.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "errors": { + Type: schema.TypeString, + Optional: true, + Description: "Error message for the form. (JSON encoded)", + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + }, + "custom": { + Type: schema.TypeString, + Optional: true, + Description: "Custom message for the form. (JSON encoded)", + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + }, + }, + }, +} + +func createForm(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + form, err := expandForm(data) + if err != nil { + return diag.FromErr(err) + } + + if err := api.Form.Create(ctx, form); err != nil { + return diag.FromErr(err) + } + + data.SetId(form.GetID()) + + return readForm(ctx, data, meta) +} + +func readForm(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + form, err := api.Form.Read(ctx, data.Id()) + if err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return diag.FromErr(flattenForm(data, form)) +} + +func updateForm(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + form, err := expandForm(data) + if err != nil { + return diag.FromErr(err) + } + + if err := api.Form.Update(ctx, data.Id(), form); err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + if isNodeEmpty(data) { + time.Sleep(200 * time.Millisecond) + + if err := api.Request(ctx, http.MethodPatch, api.URI("forms", data.Id()), map[string]interface{}{ + "nodes": []interface{}{}, + }); err != nil { + return diag.FromErr(err) + } + } + + return readForm(ctx, data, meta) +} + +func deleteForm(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + api := meta.(*config.Config).GetAPI() + + if err := api.Form.Delete(ctx, data.Id()); err != nil { + return diag.FromErr(internalError.HandleAPIError(data, err)) + } + + return nil +} diff --git a/internal/auth0/form/resource_test.go b/internal/auth0/form/resource_test.go new file mode 100644 index 00000000..43c7d3ac --- /dev/null +++ b/internal/auth0/form/resource_test.go @@ -0,0 +1,110 @@ +package form_test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + + "github.com/auth0/terraform-provider-auth0/internal/acctest" +) + +const testFormCreateInvalidStyle = ` +resource "auth0_form" "my_form" { + name = "test-form-{{.testName}}" + style = "invalid-json" + ending = jsonencode({resume_flow = true}) + languages { primary = "en" } +} +` + +const testFormCreate = ` +resource "auth0_form" "my_form" { + name = "test-form-{{.testName}}" + ending = jsonencode({resume_flow = true}) + languages { primary = "en" } +} +` + +const testFormUpdate = ` +resource "auth0_form" "my_form" { + name = "updated-test-form-{{.testName}}" + ending = jsonencode({resume_flow = true}) + languages { primary = "en" } +} +` + +const testFormUpdateEmptyNode = ` +resource "auth0_form" "my_form" { + name = "updated-test-form-no-node-{{.testName}}" + ending = jsonencode({resume_flow = true}) + languages { primary = "en" } + nodes = jsonencode([]) +} +` + +const testFormCreateWithStyle = ` +resource "auth0_form" "my_form" { + name = "test-form-style-{{.testName}}" + languages { primary = "en" } + style = jsonencode({css = "h1 {\n color: white;\n text-align: center;\n}"}) +} +` + +const testFormCreateWithMessages = ` +resource "auth0_form" "my_form" { + name = "test-form-messages-{{.testName}}" + languages { primary = "en" } + messages { + errors = jsonencode({ + ERR_ACCEPTANCE_REQUIRED = "Custom error message" + }) + } +} +` + +func TestAccForm(t *testing.T) { + acctest.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: acctest.ParseTestName(testFormCreateInvalidStyle, t.Name()), + ExpectError: regexp.MustCompile(`contains an invalid JSON`), + }, + { + Config: acctest.ParseTestName(testFormCreate, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_form.my_form", "name", "test-form-"+t.Name()), + resource.TestCheckResourceAttrSet("auth0_form.my_form", "id"), + ), + }, + { + Config: acctest.ParseTestName(testFormUpdate, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_form.my_form", "name", "updated-test-form-"+t.Name()), + resource.TestCheckResourceAttrSet("auth0_form.my_form", "id"), + ), + }, + { + Config: acctest.ParseTestName(testFormUpdateEmptyNode, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_form.my_form", "name", "updated-test-form-no-node-"+t.Name()), + resource.TestCheckResourceAttrSet("auth0_form.my_form", "id"), + ), + }, + { + Config: acctest.ParseTestName(testFormCreateWithStyle, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_form.my_form", "name", "test-form-style-"+t.Name()), + resource.TestCheckResourceAttrSet("auth0_form.my_form", "id"), + ), + }, + { + Config: acctest.ParseTestName(testFormCreateWithMessages, t.Name()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("auth0_form.my_form", "name", "test-form-messages-"+t.Name()), + resource.TestCheckResourceAttrSet("auth0_form.my_form", "id"), + ), + }, + }, + }) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index e5f958ff..a5df748e 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -3,6 +3,10 @@ package provider import ( "os" + "github.com/auth0/terraform-provider-auth0/internal/auth0/flow" + + "github.com/auth0/terraform-provider-auth0/internal/auth0/form" + selfserviceprofile "github.com/auth0/terraform-provider-auth0/internal/auth0/selfserviceprofile" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -138,6 +142,9 @@ func New() *schema.Provider { "auth0_user_role": user.NewRoleResource(), "auth0_user_roles": user.NewRolesResource(), "auth0_self_service_profile": selfserviceprofile.NewResource(), + "auth0_form": form.NewResource(), + "auth0_flow": flow.NewResource(), + "auth0_flow_vault_connection": flow.NewVaultConnectionResource(), }, DataSourcesMap: map[string]*schema.Resource{ "auth0_attack_protection": attackprotection.NewDataSource(), @@ -156,6 +163,9 @@ func New() *schema.Provider { "auth0_user": user.NewDataSource(), "auth0_self_service_profile": selfserviceprofile.NewDataSource(), "auth0_prompt_screen_partials": prompt.NewPromptScreenPartialsDataSource(), + "auth0_form": form.NewDataSource(), + "auth0_flow": flow.NewDataSource(), + "auth0_flow_vault_connection": flow.NewVaultConnectionDataSource(), }, } diff --git a/test/data/recordings/TestAccFlow.yaml b/test/data/recordings/TestAccFlow.yaml new file mode 100644 index 00000000..51afa3d0 --- /dev/null +++ b/test/data/recordings/TestAccFlow.yaml @@ -0,0 +1,285 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 33 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"test-flow-TestAccFlow"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 145 + uncompressed: false + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:29.050Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 201 Created + code: 201 + duration: 392.373292ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:29.050Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 375.805209ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:29.050Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 373.8045ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:29.050Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 336.895208ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 41 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"updated-test-flow-TestAccFlow"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: PATCH + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"updated-test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:32.099Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 372.093583ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"updated-test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:32.099Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 341.532584ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_ttY44R8riCzpNCsngY4JJS","name":"updated-test-flow-TestAccFlow","created_at":"2024-09-28T09:51:29.050Z","updated_at":"2024-09-28T09:51:32.099Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 373.90575ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_ttY44R8riCzpNCsngY4JJS + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Type: + - application/json; charset=utf-8 + status: 204 No Content + code: 204 + duration: 367.819ms diff --git a/test/data/recordings/TestAccFlowDataSource.yaml b/test/data/recordings/TestAccFlowDataSource.yaml new file mode 100644 index 00000000..57ea9b4c --- /dev/null +++ b/test/data/recordings/TestAccFlowDataSource.yaml @@ -0,0 +1,319 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 43 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"test-flow-TestAccFlowDataSource"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 155 + uncompressed: false + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 201 Created + code: 201 + duration: 450.206958ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 426.387708ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_bskks8aGbiq7qS13umnuvX + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"statusCode":404,"error":"Not Found","message":"Flow not found"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 404 Not Found + code: 404 + duration: 366.761375ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 516.739083ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 345.244042ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 467.47425ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 451.375958ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"af_69Ldq8GBHxphmyUzursmBe","name":"test-flow-TestAccFlowDataSource","created_at":"2024-09-28T09:51:22.479Z","updated_at":"2024-09-28T09:51:22.479Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 344.152916ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.10.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/af_69Ldq8GBHxphmyUzursmBe + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Type: + - application/json; charset=utf-8 + status: 204 No Content + code: 204 + duration: 449.90775ms diff --git a/test/data/recordings/TestAccForm.yaml b/test/data/recordings/TestAccForm.yaml new file mode 100644 index 00000000..ae888847 --- /dev/null +++ b/test/data/recordings/TestAccForm.yaml @@ -0,0 +1,285 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 106 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"test-form-TestAccForm","languages":{"primary":"en"},"messages":{},"ending":{"resume_flow":true}} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 204 + uncompressed: false + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:03.587Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 201 Created + code: 201 + duration: 253.5465ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:03.587Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 383.491ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:03.587Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 225.217833ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:03.587Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 233.356042ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 84 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"updated-test-form-TestAccForm","languages":{"primary":"en"},"messages":{}} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: PATCH + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"updated-test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:05.946Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 213.874542ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"updated-test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:05.946Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 419.502583ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_4Sdqp7SJyC2d2SJ5ACAXYg","name":"updated-test-form-TestAccForm","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:30:03.587Z","updated_at":"2024-09-30T10:30:05.946Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 239.851584ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_4Sdqp7SJyC2d2SJ5ACAXYg + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Type: + - application/json; charset=utf-8 + status: 204 No Content + code: 204 + duration: 248.418542ms diff --git a/test/data/recordings/TestAccFormDataSource.yaml b/test/data/recordings/TestAccFormDataSource.yaml new file mode 100644 index 00000000..0b8f4d69 --- /dev/null +++ b/test/data/recordings/TestAccFormDataSource.yaml @@ -0,0 +1,319 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 116 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"messages":{},"ending":{"resume_flow":true}} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 214 + uncompressed: false + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 201 Created + code: 201 + duration: 242.18125ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 246.654875ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_9AXxPP59pJx5ZtA471cSBx + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"statusCode":404,"error":"Not Found","message":"Form not found"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 404 Not Found + code: 404 + duration: 232.683417ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 537.1795ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 270.351333ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 350.843375ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 355.660917ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ap_hp33m8CBGwEBdsKyG63ZPr","name":"test-form-TestAccFormDataSource","languages":{"primary":"en"},"ending":{"resume_flow":true},"created_at":"2024-09-30T10:29:23.747Z","updated_at":"2024-09-30T10:29:23.747Z"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 386.661083ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/forms/ap_hp33m8CBGwEBdsKyG63ZPr + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Type: + - application/json; charset=utf-8 + status: 204 No Content + code: 204 + duration: 453.202625ms diff --git a/test/data/recordings/TestAccVaultConnection.yaml b/test/data/recordings/TestAccVaultConnection.yaml new file mode 100644 index 00000000..b5ed7c02 --- /dev/null +++ b/test/data/recordings/TestAccVaultConnection.yaml @@ -0,0 +1,285 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 45 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"app_id":"HTTP","name":"test-v-connection"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 240 + uncompressed: false + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:24.834Z","refreshed_at":null,"fingerprint":"6879858e37a98f15e5bd92ff4d480967"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 201 Created + code: 201 + duration: 237.560459ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:24.834Z","fingerprint":"6879858e37a98f15e5bd92ff4d480967"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 219.13075ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:24.834Z","fingerprint":"6879858e37a98f15e5bd92ff4d480967"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 313.342541ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:24.834Z","fingerprint":"6879858e37a98f15e5bd92ff4d480967"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 237.953583ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 37 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"name":"updated-test-v-connection"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: PATCH + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"updated-test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:27.081Z","refreshed_at":null,"fingerprint":"57e0eb8c3e94a79cbc3ce6ba8f046286"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 222.2495ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"updated-test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:27.081Z","fingerprint":"57e0eb8c3e94a79cbc3ce6ba8f046286"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 219.678875ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_driHxZHbTWt3zCyXRqsDFo","app_id":"HTTP","name":"updated-test-v-connection","ready":false,"created_at":"2024-09-30T10:30:24.834Z","updated_at":"2024-09-30T10:30:27.081Z","fingerprint":"57e0eb8c3e94a79cbc3ce6ba8f046286"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 222.635167ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_driHxZHbTWt3zCyXRqsDFo + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Type: + - application/json; charset=utf-8 + status: 204 No Content + code: 204 + duration: 220.597875ms diff --git a/test/data/recordings/TestAccVaultConnectionDataSource.yaml b/test/data/recordings/TestAccVaultConnectionDataSource.yaml new file mode 100644 index 00000000..fb77f576 --- /dev/null +++ b/test/data/recordings/TestAccVaultConnectionDataSource.yaml @@ -0,0 +1,319 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 49 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: | + {"app_id":"HTTP","name":"test-vault-connection"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 244 + uncompressed: false + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","refreshed_at":null,"fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 201 Created + code: 201 + duration: 243.500583ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 429.863292ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_5Cy8N47rNvNixgNBShK8fK + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"statusCode":404,"error":"Not Found","message":"Connection not found"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 404 Not Found + code: 404 + duration: 235.800083ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 236.724834ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 230.571167ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 234.069042ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 211.7335ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"id":"ac_hp38yv5gxVaXoEhrcPSqqL","app_id":"HTTP","name":"test-vault-connection","ready":false,"created_at":"2024-09-30T10:30:20.369Z","updated_at":"2024-09-30T10:30:20.369Z","fingerprint":"d80212f7aca9dbea74859811c6caddba"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 309.806416ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: terraform-provider-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0/1.11.0 + url: https://terraform-provider-auth0-dev.eu.auth0.com/api/v2/flows/vault/connections/ac_hp38yv5gxVaXoEhrcPSqqL + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Type: + - application/json; charset=utf-8 + status: 204 No Content + code: 204 + duration: 249.186417ms