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

Commit b0b1c5f

Browse files
authored
Merge pull request #497 from jluiz20/added_auth0_prompt_custom_text
Add auth0 prompt custom text
2 parents 8ca0c0b + d550a43 commit b0b1c5f

6 files changed

+314
-0
lines changed

.github/labeler.yml

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ resource/auth0_prompt:
5454
- '**/*prompt.go'
5555
- '**/*prompt_test.go'
5656

57+
resource/auth0_prompt_custom_text:
58+
- '**/*prompt_custom_text.go'
59+
- '**/*prompt_custom_text_test.go'
60+
5761
resource/auth0_resource_server:
5862
- '**/*resource_server.go'
5963
- '**/*resource_server_test.go'

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.26.0
2+
3+
ENHANCEMENTS:
4+
5+
* **New Resource:** `auth0_prompt_custom_text` ([#497](https://github.com/alexkappa/terraform-provider-auth0/pull/497))
6+
17
## 0.25.1
28

39
ENHANCEMENTS:

auth0/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func init() {
5656
"auth0_rule_config": newRuleConfig(),
5757
"auth0_hook": newHook(),
5858
"auth0_prompt": newPrompt(),
59+
"auth0_prompt_custom_text": newPromptCustomText(),
5960
"auth0_email": newEmail(),
6061
"auth0_email_template": newEmailTemplate(),
6162
"auth0_user": newUser(),
+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package auth0
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"net/http"
8+
"strings"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
11+
"github.com/hashicorp/terraform-plugin-sdk/helper/structure"
12+
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
13+
14+
"gopkg.in/auth0.v5/management"
15+
)
16+
17+
var (
18+
availablePrompts = []string{
19+
"login", "login-id", "login-password", "login-email-verification", "signup", "signup-id", "signup-password",
20+
"reset-password", "consent", "mfa-push", "mfa-otp", "mfa-voice", "mfa-phone", "mfa-webauthn", "mfa-sms",
21+
"mfa-email", "mfa-recovery-code", "mfa", "status", "device-flow", "email-verification", "email-otp-challenge",
22+
"organizations", "invitation", "common",
23+
}
24+
availableLanguages = []string{
25+
"ar", "bg", "bs", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "fr-CA", "fr-FR", "he", "hi", "hr",
26+
"hu", "id", "is", "it", "ja", "ko", "lt", "lv", "nb", "nl", "pl", "pt", "pt-BR", "pt-PT", "ro", "ru", "sk",
27+
"sl", "sr", "sv", "th", "tr", "uk", "vi", "zh-CN", "zh-TW",
28+
}
29+
errEmptyPromptCustomTextID = fmt.Errorf("ID cannot be empty")
30+
errInvalidPromptCustomTextIDFormat = fmt.Errorf("ID must be formated as prompt:language")
31+
)
32+
33+
func newPromptCustomText() *schema.Resource {
34+
return &schema.Resource{
35+
Create: createPromptCustomText,
36+
Read: readPromptCustomText,
37+
Update: updatePromptCustomText,
38+
Delete: deletePromptCustomText,
39+
Importer: &schema.ResourceImporter{
40+
State: importPromptCustomText,
41+
},
42+
Schema: map[string]*schema.Schema{
43+
"prompt": {
44+
Type: schema.TypeString,
45+
Required: true,
46+
ValidateFunc: validation.StringInSlice(availablePrompts, false),
47+
},
48+
"language": {
49+
Type: schema.TypeString,
50+
Required: true,
51+
ValidateFunc: validation.StringInSlice(availableLanguages, false),
52+
},
53+
"body": {
54+
Type: schema.TypeString,
55+
Required: true,
56+
ValidateFunc: validation.StringIsJSON,
57+
DiffSuppressFunc: structure.SuppressJsonDiff,
58+
},
59+
},
60+
}
61+
}
62+
63+
func importPromptCustomText(d *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) {
64+
prompt, language, err := getPromptAndLanguage(d)
65+
if err != nil {
66+
return []*schema.ResourceData{}, err
67+
}
68+
69+
d.SetId(d.Id())
70+
d.Set("prompt", prompt)
71+
d.Set("language", language)
72+
73+
return []*schema.ResourceData{d}, nil
74+
}
75+
76+
func createPromptCustomText(d *schema.ResourceData, m interface{}) error {
77+
d.SetId(d.Get("prompt").(string) + ":" + d.Get("language").(string))
78+
return updatePromptCustomText(d, m)
79+
}
80+
81+
func readPromptCustomText(d *schema.ResourceData, m interface{}) error {
82+
api := m.(*management.Management)
83+
customText, err := api.Prompt.CustomText(d.Get("prompt").(string), d.Get("language").(string))
84+
if err != nil {
85+
if mErr, ok := err.(management.Error); ok {
86+
if mErr.Status() == http.StatusNotFound {
87+
d.SetId("")
88+
return nil
89+
}
90+
}
91+
return err
92+
}
93+
94+
body, err := marshalCustomTextBody(customText)
95+
if err != nil {
96+
return err
97+
}
98+
99+
d.Set("body", body)
100+
return nil
101+
}
102+
103+
func updatePromptCustomText(d *schema.ResourceData, m interface{}) error {
104+
api := m.(*management.Management)
105+
prompt, language, err := getPromptAndLanguage(d)
106+
if err != nil {
107+
return err
108+
}
109+
110+
if d.Get("body").(string) != "" {
111+
var body map[string]interface{}
112+
if err := json.Unmarshal([]byte(d.Get("body").(string)), &body); err != nil {
113+
return err
114+
}
115+
116+
err := api.Prompt.SetCustomText(prompt, language, body)
117+
if err != nil {
118+
return err
119+
}
120+
}
121+
122+
return readPromptCustomText(d, m)
123+
}
124+
125+
func deletePromptCustomText(d *schema.ResourceData, m interface{}) error {
126+
d.Set("body", "{}")
127+
128+
if err := updatePromptCustomText(d, m); err != nil {
129+
return err
130+
}
131+
132+
d.SetId("")
133+
return nil
134+
}
135+
136+
func getPromptAndLanguage(d *schema.ResourceData) (string, string, error) {
137+
rawID := d.Id()
138+
if rawID == "" {
139+
return "", "", errEmptyPromptCustomTextID
140+
}
141+
142+
if !strings.Contains(rawID, ":") {
143+
return "", "", errInvalidPromptCustomTextIDFormat
144+
}
145+
146+
idPair := strings.Split(rawID, ":")
147+
if len(idPair) != 2 {
148+
return "", "", errInvalidPromptCustomTextIDFormat
149+
}
150+
151+
return idPair[0], idPair[1], nil
152+
}
153+
154+
func marshalCustomTextBody(b map[string]interface{}) (string, error) {
155+
bodyBytes, err := json.Marshal(b)
156+
if err != nil {
157+
return "", fmt.Errorf("Failed to serialize the custom texts to JSON: %w", err)
158+
}
159+
160+
var buffer bytes.Buffer
161+
const jsonIndentation = " "
162+
if err := json.Indent(&buffer, bodyBytes, "", jsonIndentation); err != nil {
163+
return "", fmt.Errorf("Failed to format the custom texts JSON: %w", err)
164+
}
165+
166+
return buffer.String(), nil
167+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package auth0
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
7+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
8+
)
9+
10+
func TestAccPromptCustomText(t *testing.T) {
11+
resource.Test(t, resource.TestCase{
12+
Providers: map[string]terraform.ResourceProvider{
13+
"auth0": Provider(),
14+
},
15+
Steps: []resource.TestStep{
16+
{
17+
Config: testAccPromptCustomTextCreate,
18+
Check: resource.ComposeTestCheckFunc(
19+
resource.TestCheckResourceAttr("auth0_prompt_custom_text.prompt_custom_text", "prompt", "login"),
20+
resource.TestCheckResourceAttr("auth0_prompt_custom_text.prompt_custom_text", "language", "en"),
21+
resource.TestCheckResourceAttr(
22+
"auth0_prompt_custom_text.prompt_custom_text",
23+
"body",
24+
"{\n \"login\": {\n \"alertListTitle\": \"Alerts\",\n \"buttonText\": \"Continue\",\n \"emailPlaceholder\": \"Email address\"\n }\n}",
25+
),
26+
),
27+
},
28+
{
29+
Config: testAccPromptCustomTextUpdate,
30+
Check: resource.ComposeTestCheckFunc(
31+
resource.TestCheckResourceAttr("auth0_prompt_custom_text.prompt_custom_text", "prompt", "login"),
32+
resource.TestCheckResourceAttr("auth0_prompt_custom_text.prompt_custom_text", "language", "en"),
33+
resource.TestCheckResourceAttr(
34+
"auth0_prompt_custom_text.prompt_custom_text",
35+
"body",
36+
"{\n \"login\": {\n \"alertListTitle\": \"Alerts\",\n \"buttonText\": \"Proceed\",\n \"emailPlaceholder\": \"Email Address\"\n }\n}",
37+
),
38+
),
39+
},
40+
},
41+
})
42+
}
43+
44+
const testAccPromptCustomTextCreate = `
45+
resource "auth0_prompt_custom_text" "prompt_custom_text" {
46+
prompt = "login"
47+
language = "en"
48+
body = jsonencode(
49+
{
50+
"login" : {
51+
"alertListTitle" : "Alerts",
52+
"buttonText" : "Continue",
53+
"emailPlaceholder" : "Email address"
54+
}
55+
}
56+
)
57+
}
58+
`
59+
60+
const testAccPromptCustomTextUpdate = `
61+
resource "auth0_prompt_custom_text" "prompt_custom_text" {
62+
prompt = "login"
63+
language = "en"
64+
body = jsonencode(
65+
{
66+
"login" : {
67+
"alertListTitle" : "Alerts",
68+
"buttonText" : "Proceed",
69+
"emailPlaceholder" : "Email Address"
70+
}
71+
}
72+
)
73+
}
74+
`

docs/resources/prompt_custom_text.md

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
layout: "auth0"
3+
page_title: "Auth0: auth0_prompt_custom_text"
4+
description: |-
5+
With this resource, you can manage custom texts on your Auth0 prompts.
6+
---
7+
8+
# auth0_prompt_custom_text
9+
10+
With this resource, you can manage custom text on your Auth0 prompts. You can read more about custom texts
11+
[here](https://auth0.com/docs/customize/universal-login-pages/customize-login-text-prompts).
12+
13+
## Example Usage
14+
15+
```hcl
16+
resource "auth0_prompt_custom_text" "example" {
17+
prompt = "login"
18+
language = "en"
19+
body = jsonencode(
20+
{
21+
"login" : {
22+
"alertListTitle" : "Alerts",
23+
"buttonText" : "Continue",
24+
"description" : "Login to",
25+
"editEmailText" : "Edit",
26+
"emailPlaceholder" : "Email address",
27+
"federatedConnectionButtonText" : "Continue with ${connectionName}",
28+
"footerLinkText" : "Sign up",
29+
"footerText" : "Don't have an account?",
30+
"forgotPasswordText" : "Forgot password?",
31+
"invitationDescription" : "Log in to accept ${inviterName}'s invitation to join ${companyName} on ${clientName}.",
32+
"invitationTitle" : "You've Been Invited!",
33+
"logoAltText" : "${companyName}",
34+
"pageTitle" : "Log in | ${clientName}",
35+
"passwordPlaceholder" : "Password",
36+
"separatorText" : "Or",
37+
"signupActionLinkText" : "${footerLinkText}",
38+
"signupActionText" : "${footerText}",
39+
"title" : "Welcome",
40+
"usernamePlaceholder" : "Username or email address"
41+
}
42+
}
43+
)
44+
}
45+
```
46+
47+
## Argument Reference
48+
49+
The following arguments are supported:
50+
51+
* `prompt` - (Required) The term `prompt` is used to refer to a specific step in the login flow. Options include `login`, `login-id`, `login-password`, `login-email-verification`, `signup`, `signup-id`, `signup-password`, `reset-password`, `consent`, `mfa-push`, `mfa-otp`, `mfa-voice`, `mfa-phone`, `mfa-webauthn`, `mfa-sms`, `mfa-email`, `mfa-recovery-code`, `mfa`, `status`, `device-flow`, `email-verification`, `email-otp-challenge`, `organizations`, `invitation`, `common`
52+
* `language` - (Required) Language of the custom text. Options include `ar`, `bg`, `bs`, `cs`, `da`, `de`, `el`, `en`, `es`, `et`, `fi`, `fr`, `fr-CA`, `fr-FR`, `he`, `hi`, `hr`, `hu`, `id`, `is`, `it`, `ja`, `ko`, `lt`, `lv`, `nb`, `nl`, `pl`, `pt`, `pt-BR`, `pt-PT`, `ro`, `ru`, `sk`, `sl`, `sr`, `sv`, `th`, `tr`, `uk`, `vi`, `zh-CN`, `zh-TW`
53+
* `body` - (Required) JSON containing the custom texts. You can check the options for each prompt [here](https://auth0.com/docs/customize/universal-login-pages/customize-login-text-prompts#prompt-values)
54+
55+
## Import
56+
57+
auth0_prompt_custom_text can be imported using the import command and specifying the prompt and language separated
58+
by *:* , e.g.
59+
60+
```terminal
61+
terraform import auth0_prompt_custom_text.example login:en
62+
```

0 commit comments

Comments
 (0)