Skip to content

Commit

Permalink
feat: add Form Field datasource (#209)
Browse files Browse the repository at this point in the history
* add form field datasource

* typo

* Update docs/data-sources/form_field.md

Co-authored-by: Mark Manes <[email protected]>

---------

Co-authored-by: Mark Manes <[email protected]>
  • Loading branch information
vbeausoleil and mmanes authored Jun 1, 2023
1 parent d0b65ff commit 8eab8c7
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 0 deletions.
45 changes: 45 additions & 0 deletions docs/data-sources/form_field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Form Field Resource

A FusionAuth Form Field is an object that can be customized to receive input within a FusionAuth [Form](https://fusionauth.io/docs/v1/tech/apis/forms).

[Form Field API](https://fusionauth.io/docs/v1/tech/apis/form-fields)

## Example Usage

```hcl
data "fusionauth_form_field" "default" {
name = "Email"
}
```

## Argument Reference

- `form_field_id` - (Optional) The unique id of the Form Field. Either `form_field_id` or `name` must be specified.
- `name` - (Optional) The name of the Form field. Either `form_field_id` or `name` must be specified.

## Attributes Reference

All the argument attributes are also exported as result attributes.

The following additional attributes are exported:

- `id` - The unique Id of the Form Field.
- `confirm` - Determines if the user input should be confirmed by requiring the value to be entered twice.
- consent_id
- control
- `data` - An object that can hold any information about the Form Field that should be persisted.
- description
- key
- `name` - The unique name of the Form Field.
- `options` - A list of options that are applied to checkbox, radio, or select controls.
- `required` - Determines if a value is required to complete the form.
- `type` - The form field type. The possible values are:
- `bool`
- `consent`
- `date`
- `email`
- `number`
- `string`
- `validator`
- `enabled` - Determines if user input should be validated.
- `expression` - A regular expression used to validate user input. Must be a valid regular expression pattern.
171 changes: 171 additions & 0 deletions fusionauth/datasource_fusionauth_form_field.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package fusionauth

import (
"context"
"net/http"

"github.com/FusionAuth/go-client/pkg/fusionauth"
"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"
)

func dataSourceFormField() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceFormFieldRead,
Schema: map[string]*schema.Schema{
"form_field_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ExactlyOneOf: []string{"form_field_id", "name"},
Description: "The Id to use for the new Form Field. If not specified a secure random UUID will be generated.",
ValidateFunc: validation.IsUUID,
},
"confirm": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Determines if the user input should be confirmed by requiring the value to be entered twice. If true, a confirmation field is included.",
},
"consent_id": {
Type: schema.TypeString,
Optional: true,
Description: "The Id of an existing Consent. This field will be required when the type is set to consent.",
ValidateFunc: validation.IsUUID,
},
"control": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The Form Field control",
ValidateFunc: validation.StringInSlice([]string{
"checkbox",
"number",
"password",
"radio",
"select",
"textarea",
"text",
}, false),
},
"data": {
Type: schema.TypeMap,
Optional: true,
Description: "An object that can hold any information about the Form Field that should be persisted.",
},
"description": {
Type: schema.TypeString,
Optional: true,
Description: "A description of the Form Field.",
},
"key": {
Type: schema.TypeString,
Optional: true,
Description: "The key is the path to the value in the user or registration object.",
ValidateFunc: validateKey,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
ExactlyOneOf: []string{"form_field_id", "name"},
Description: "The unique name of the Form Field.",
},
"options": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "A list of options that are applied to checkbox, radio, or select controls.",
},
"required": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Determines if a value is required to complete the form.",
},
"type": {
Type: schema.TypeString,
Optional: true,
Default: "string",
ValidateFunc: validation.StringInSlice([]string{
"bool",
"consent",
"date",
"email",
"number",
"string",
}, false),
Description: "The data type used to store the value in FusionAuth.",
},
"validator": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
ConfigMode: schema.SchemaConfigModeAttr,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Determines if user input should be validated.",
},
"expression": {
Type: schema.TypeString,
Optional: true,
Description: "A regular expression used to validate user input. Must be a valid regular expression pattern.",
ValidateFunc: validateRegex,
},
},
},
},
},
}
}

func dataSourceFormFieldRead(_ context.Context, data *schema.ResourceData, i interface{}) diag.Diagnostics {
client := i.(Client)

var searchTerm string
var res *fusionauth.FormFieldResponse
var err error

// Either `form_field_id` or `name` are guaranteed to be set
if entityID, ok := data.GetOk("form_field_id"); ok {
searchTerm = entityID.(string)
res, err = client.FAClient.RetrieveFormField(searchTerm)
} else {
searchTerm = data.Get("name").(string)
res, err = client.FAClient.RetrieveFormFields()
}
if err != nil {
return diag.FromErr(err)
}
if res.StatusCode == http.StatusNotFound {
return diag.Errorf("couldn't find form field '%s'", searchTerm)
}
if err := checkResponse(res.StatusCode, nil); err != nil {
return diag.FromErr(err)
}

foundEntity := res.Field
if len(res.Fields) > 0 {
// search based on name
var found = false
for _, entity := range res.Fields {
if entity.Name == searchTerm {
found = true
foundEntity = entity
break
}
}
if !found {
return diag.Errorf("couldn't find form field with name '%s'", searchTerm)
}
}

data.SetId(foundEntity.Id)
return buildResourceDataFromFormField(data, foundEntity)
}
1 change: 1 addition & 0 deletions fusionauth/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func Provider() *schema.Provider {
"fusionauth_application": dataSourceApplication(),
"fusionauth_application_role": dataSourceApplicationRole(),
"fusionauth_form": dataSourceForm(),
"fusionauth_form_field": dataSourceFormField(),
"fusionauth_email": dataSourceEmail(),
"fusionauth_idp": dataSourceIDP(),
"fusionauth_lambda": dataSourceLambda(),
Expand Down

0 comments on commit 8eab8c7

Please sign in to comment.