Skip to content

Commit

Permalink
Feat: Add resource for prompt partials (#918)
Browse files Browse the repository at this point in the history
* Add resource for prompt partials

* Added docs for prompt partials

* Add cassette for tests

* Add comment to public function

* Adjust imports for linter

* Teardown partials in tests

* Go the TF config route

* Wait on branding for test dependency

* Fix auth0_prompt_partials

---------

Co-authored-by: Michael Christenson II <michael.christensonii@okta.com>
Co-authored-by: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 28, 2024
1 parent b5d51e8 commit 21e8c52
Show file tree
Hide file tree
Showing 13 changed files with 1,400 additions and 13 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ override.tf.json
*_override.tf
*_override.tf.json

# VSCode ###
# Editors ###
.vscode/*
!.vscode/tasks.json
*.code-workspace
.idea

# Environment
.env
.envrc
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## v1.2.0

FEATURES:

- `resource/auth0_prompt_partials`: Add new resource to manage prompt partials ([#918](https://github.com/auth0/terraform-provider-auth0/pull/918))


## v1.1.2

ENHANCEMENTS:
Expand Down
55 changes: 55 additions & 0 deletions docs/resources/prompt_partials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
page_title: "Resource: auth0_prompt_partials"
description: |-
With this resource, you can manage a customized sign up and login experience by adding custom content, form elements and css/javascript. You can read more about this here https://auth0.com/docs/customize/universal-login-pages/customize-signup-and-login-prompts.
---

# Resource: auth0_prompt_partials

With this resource, you can manage a customized sign up and login experience by adding custom content, form elements and css/javascript. You can read more about this [here](https://auth0.com/docs/customize/universal-login-pages/customize-signup-and-login-prompts).

## Example Usage

```terraform
resource "auth0_prompt_partials" "my_login_prompt_partials" {
prompt = "login"
form_content_start = "<div>Updated Form Content Start</div>"
form_content_end = "<div>Updated Form Content End</div>"
form_footer_start = "<div>Updated Footer Start</div>"
form_footer_end = "<div>Updated Footer End</div>"
secondary_actions_start = "<div>Updated Secondary Actions Start</div>"
secondary_actions_end = "<div>Updated Secondary Actions End</div>"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `prompt` (String) The prompt that you are adding partials for. Options are: `login-id`, `login`, `login-password`, `signup`, `signup-id`, `signup-password`.

### Optional

- `form_content_end` (String) Content that goes at the end of the form.
- `form_content_start` (String) Content that goes at the start of the form.
- `form_footer_end` (String) Footer content for the end of the footer.
- `form_footer_start` (String) Footer content for the start of the footer.
- `secondary_actions_end` (String) Actions that go at the end of secondary actions.
- `secondary_actions_start` (String) Actions that go at the start of secondary actions.

### 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 prompt name.
#
# Example:
terraform import auth0_prompt_partials.my_login_prompt_partials "login"
```
4 changes: 4 additions & 0 deletions examples/resources/auth0_prompt_partials/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This resource can be imported using the prompt name.
#
# Example:
terraform import auth0_prompt_partials.my_login_prompt_partials "login"
10 changes: 10 additions & 0 deletions examples/resources/auth0_prompt_partials/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "auth0_prompt_partials" "my_login_prompt_partials" {
prompt = "login"

form_content_start = "<div>Updated Form Content Start</div>"
form_content_end = "<div>Updated Form Content End</div>"
form_footer_start = "<div>Updated Footer Start</div>"
form_footer_end = "<div>Updated Footer End</div>"
secondary_actions_start = "<div>Updated Secondary Actions Start</div>"
secondary_actions_end = "<div>Updated Secondary Actions End</div>"
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.21

require (
github.com/PuerkitoBio/rehttp v1.3.0
github.com/auth0/go-auth0 v1.4.0
github.com/auth0/go-auth0 v1.4.1
github.com/google/go-cmp v0.6.0
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/go-multierror v1.1.1
Expand All @@ -29,7 +29,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/cli v1.1.6 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
Expand Down Expand Up @@ -73,8 +73,8 @@ require (
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/auth0/go-auth0 v1.4.0 h1:oZL3xIBBPW2ckLQmp6BSqpx5RV5yuqqOEVEPp4cipR4=
github.com/auth0/go-auth0 v1.4.0/go.mod h1:X1o5gVvYUYAQltayD5HrLimFZN9tfZUlJDUh+lz8h9I=
github.com/auth0/go-auth0 v1.4.1 h1:0AWqPCzw4Su38qx5jSxAwwuEBROdrpjsq4t9/GshZE0=
github.com/auth0/go-auth0 v1.4.1/go.mod h1:5EO0p8vRuUgY4a0VPTCDzXbIVMxWn8Jon3aEGQQFOoQ=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
Expand Down Expand Up @@ -66,8 +66,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8=
github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -225,10 +225,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
13 changes: 13 additions & 0 deletions internal/auth0/prompt/expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package prompt
import (
"github.com/auth0/go-auth0/management"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/auth0/terraform-provider-auth0/internal/value"
)
Expand All @@ -20,3 +21,15 @@ func expandPrompt(data cty.Value) *management.Prompt {

return &prompt
}

func expandPromptPartials(data *schema.ResourceData) *management.PromptPartials {
return &management.PromptPartials{
Prompt: management.PromptType(data.Get("prompt").(string)),
FormContentStart: data.Get("form_content_start").(string),
FormContentEnd: data.Get("form_content_end").(string),
FormFooterStart: data.Get("form_footer_start").(string),
FormFooterEnd: data.Get("form_footer_end").(string),
SecondaryActionsStart: data.Get("secondary_actions_start").(string),
SecondaryActionsEnd: data.Get("secondary_actions_end").(string),
}
}
13 changes: 13 additions & 0 deletions internal/auth0/prompt/flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ func flattenPrompt(data *schema.ResourceData, prompt *management.Prompt) error {
return result.ErrorOrNil()
}

func flattenPromptPartials(data *schema.ResourceData, promptPartials *management.PromptPartials) error {
result := multierror.Append(
data.Set("form_content_start", promptPartials.FormContentStart),
data.Set("form_content_end", promptPartials.FormContentEnd),
data.Set("form_footer_start", promptPartials.FormFooterStart),
data.Set("form_footer_end", promptPartials.FormFooterEnd),
data.Set("secondary_actions_start", promptPartials.SecondaryActionsStart),
data.Set("secondary_actions_end", promptPartials.SecondaryActionsEnd),
)

return result.ErrorOrNil()
}

func flattenPromptCustomText(data *schema.ResourceData, customText map[string]interface{}) error {
body, err := marshalCustomTextBody(customText)
if err != nil {
Expand Down
116 changes: 116 additions & 0 deletions internal/auth0/prompt/resource_partials.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package prompt

import (
"context"
"strings"

"github.com/auth0/go-auth0/management"
"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"
)

var allowedPromptsWithPartials = []string{
string(management.PromptLoginID),
string(management.PromptLogin),
string(management.PromptLoginPassword),
string(management.PromptSignup),
string(management.PromptSignupID),
string(management.PromptSignupPassword),
}

// NewPartialsResource creates a new resource for partial prompts.
func NewPartialsResource() *schema.Resource {
return &schema.Resource{
CreateContext: createPromptPartials,
ReadContext: readPromptPartials,
UpdateContext: updatePromptPartials,
DeleteContext: deletePromptPartials,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Description: "With this resource, you can manage a customized sign up and login experience by adding custom content, form elements and css/javascript. " +
"You can read more about this [here](https://auth0.com/docs/customize/universal-login-pages/customize-signup-and-login-prompts).",
Schema: map[string]*schema.Schema{
"form_content_start": {
Type: schema.TypeString,
Optional: true,
Description: "Content that goes at the start of the form.",
},
"form_content_end": {
Type: schema.TypeString,
Optional: true,
Description: "Content that goes at the end of the form.",
},
"form_footer_start": {
Type: schema.TypeString,
Optional: true,
Description: "Footer content for the start of the footer.",
},
"form_footer_end": {
Type: schema.TypeString,
Optional: true,
Description: "Footer content for the end of the footer.",
},
"secondary_actions_start": {
Type: schema.TypeString,
Optional: true,
Description: "Actions that go at the start of secondary actions.",
},
"secondary_actions_end": {
Type: schema.TypeString,
Optional: true,
Description: "Actions that go at the end of secondary actions.",
},
"prompt": {
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(allowedPromptsWithPartials, false),
Description: "The prompt that you are adding partials for. " +
"Options are: `" + strings.Join(allowedPromptsWithPartials, "`, `") + "`.",
Required: true,
},
},
}
}
func createPromptPartials(ctx context.Context, data *schema.ResourceData, meta any) diag.Diagnostics {
prompt := data.Get("prompt").(string)
data.SetId(prompt)
return updatePromptPartials(ctx, data, meta)
}

func readPromptPartials(ctx context.Context, data *schema.ResourceData, meta any) diag.Diagnostics {
api := meta.(*config.Config).GetAPI()

promptPartials, err := api.Prompt.ReadPartials(ctx, management.PromptType(data.Id()))
if err != nil {
return diag.FromErr(err)
}

return diag.FromErr(flattenPromptPartials(data, promptPartials))
}

func updatePromptPartials(ctx context.Context, data *schema.ResourceData, meta any) diag.Diagnostics {
api := meta.(*config.Config).GetAPI()

promptPartials := expandPromptPartials(data)

if err := api.Prompt.UpdatePartials(ctx, promptPartials); err != nil {
return diag.FromErr(err)
}

return readPromptPartials(ctx, data, meta)
}

func deletePromptPartials(ctx context.Context, data *schema.ResourceData, meta any) diag.Diagnostics {
api := meta.(*config.Config).GetAPI()

prompt := data.Get("prompt").(string)

if err := api.Prompt.DeletePartials(ctx, management.PromptType(prompt)); err != nil {
return diag.FromErr(err)
}

return nil
}
Loading

0 comments on commit 21e8c52

Please sign in to comment.