Skip to content

Commit

Permalink
Add support for importing email templates (#988)
Browse files Browse the repository at this point in the history
* Add support for importing email templates

* added mock and testcases for email template

* updated the docs

* updated email_template.go && email_provider.go to automatic generate mocks

---------

Co-authored-by: Kunal Dawar <kunal.dawar@okta.com>
Co-authored-by: KunalOfficial <35455566+developerkunal@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 27, 2024
1 parent 0181f8d commit b612de8
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/auth0_terraform_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ auth0 terraform generate [flags]
```
--force Skip confirmation.
-o, --output-dir string Output directory for the generated Terraform config files. If not provided, the files will be saved in the current working directory. (default "./")
-r, --resources strings Resource types to generate Terraform config for. If not provided, config files for all available resources will be generated. (default [auth0_action,auth0_attack_protection,auth0_branding,auth0_client,auth0_client_grant,auth0_connection,auth0_custom_domain,auth0_email_provider,auth0_guardian,auth0_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_resource_server,auth0_role,auth0_tenant,auth0_trigger_actions])
-r, --resources strings Resource types to generate Terraform config for. If not provided, config files for all available resources will be generated. (default [auth0_action,auth0_attack_protection,auth0_branding,auth0_client,auth0_client_grant,auth0_connection,auth0_custom_domain,auth0_email_provider,auth0_email_template,auth0_guardian,auth0_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_resource_server,auth0_role,auth0_tenant,auth0_trigger_actions])
```


Expand Down
2 changes: 2 additions & 0 deletions internal/auth0/email_provider.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:generate mockgen -source=email_provider.go -destination=mock/email_provider_mock.go -package=mock

package auth0

import (
Expand Down
2 changes: 2 additions & 0 deletions internal/auth0/email_template.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:generate mockgen -source=email_template.go -destination=mock/email_template_mock.go -package=mock

package auth0

import (
Expand Down
4 changes: 2 additions & 2 deletions internal/auth0/mock/email_provider_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 94 additions & 0 deletions internal/auth0/mock/email_template_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions internal/cli/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ func (i *terraformInputs) parseResourceFetchers(api *auth0.API) ([]resourceDataF
fetchers = append(fetchers, &customDomainResourceFetcher{api})
case "auth0_email_provider":
fetchers = append(fetchers, &emailProviderResourceFetcher{api})
case "auth0_email_template":
fetchers = append(fetchers, &emailTemplateResourceFetcher{api})
case "auth0_guardian":
fetchers = append(fetchers, &guardianResourceFetcher{})
case "auth0_log_stream":
Expand Down
29 changes: 28 additions & 1 deletion internal/cli/terraform_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/auth0/auth0-cli/internal/auth0"
)

var defaultResources = []string{"auth0_action", "auth0_attack_protection", "auth0_branding", "auth0_client", "auth0_client_grant", "auth0_connection", "auth0_custom_domain", "auth0_email_provider", "auth0_guardian", "auth0_organization", "auth0_pages", "auth0_prompt", "auth0_prompt_custom_text", "auth0_resource_server", "auth0_role", "auth0_tenant", "auth0_trigger_actions"}
var defaultResources = []string{"auth0_action", "auth0_attack_protection", "auth0_branding", "auth0_client", "auth0_client_grant", "auth0_connection", "auth0_custom_domain", "auth0_email_provider", "auth0_email_template", "auth0_guardian", "auth0_organization", "auth0_pages", "auth0_prompt", "auth0_prompt_custom_text", "auth0_resource_server", "auth0_role", "auth0_tenant", "auth0_trigger_actions"}

type (
importDataList []importDataItem
Expand Down Expand Up @@ -54,6 +54,10 @@ type (
api *auth0.API
}

emailTemplateResourceFetcher struct {
api *auth0.API
}

guardianResourceFetcher struct{}
logStreamResourceFetcher struct {
api *auth0.API
Expand Down Expand Up @@ -245,6 +249,29 @@ func (f *emailProviderResourceFetcher) FetchData(ctx context.Context) (importDat
}, nil
}

func (f *emailTemplateResourceFetcher) FetchData(ctx context.Context) (importDataList, error) {
var data importDataList

templates := []string{`verify_email`, `reset_email`, `welcome_email`, `blocked_account`, `stolen_credentials`, `enrollment_email`, `mfa_oob_code`, `change_password`, `password_reset`}

for _, template := range templates {
emailTemplate, err := f.api.EmailTemplate.Read(ctx, template)
if err != nil {
if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound {
continue
}
return nil, err
}

data = append(data, importDataItem{
ResourceName: "auth0_email_template." + sanitizeResourceName(emailTemplate.GetTemplate()),
ImportID: sanitizeResourceName(emailTemplate.GetTemplate()),
})
}

return data, nil
}

func (f *guardianResourceFetcher) FetchData(_ context.Context) (importDataList, error) {
return []importDataItem{
{
Expand Down
118 changes: 118 additions & 0 deletions internal/cli/terraform_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,124 @@ func TestEmailProviderResourceFetcher_FetchData(t *testing.T) {
assert.EqualError(t, err, "failed to read email provider")
})
}
func TestEmailTemplateResourceFetcher_FetchData(t *testing.T) {
t.Run("it successfully retrieves email templates data", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

emailTemplateAPI := mock.NewMockEmailTemplateAPI(ctrl)
templates := []string{
"verify_email", "reset_email", "welcome_email",
"blocked_account", "stolen_credentials",
"enrollment_email", "mfa_oob_code",
"change_password", "password_reset",
}

for _, tmpl := range templates {
emailTemplateAPI.EXPECT().
Read(gomock.Any(), tmpl).
Return(&management.EmailTemplate{Template: auth0.String(tmpl)}, nil)
}

fetcher := emailTemplateResourceFetcher{
api: &auth0.API{
EmailTemplate: emailTemplateAPI,
},
}

expectedData := importDataList{
{
ResourceName: "auth0_email_template.verify_email",
ImportID: "verify_email",
},
{
ResourceName: "auth0_email_template.reset_email",
ImportID: "reset_email",
},
{
ResourceName: "auth0_email_template.welcome_email",
ImportID: "welcome_email",
},
{
ResourceName: "auth0_email_template.blocked_account",
ImportID: "blocked_account",
},
{
ResourceName: "auth0_email_template.stolen_credentials",
ImportID: "stolen_credentials",
},
{
ResourceName: "auth0_email_template.enrollment_email",
ImportID: "enrollment_email",
},
{
ResourceName: "auth0_email_template.mfa_oob_code",
ImportID: "mfa_oob_code",
},
{
ResourceName: "auth0_email_template.change_password",
ImportID: "change_password",
},
{
ResourceName: "auth0_email_template.password_reset",
ImportID: "password_reset",
},
}

data, err := fetcher.FetchData(context.Background())
assert.NoError(t, err)
assert.Equal(t, expectedData, data)
})

t.Run("it does not generate email template import data if email template does not exist", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mErr := mockManagamentError{status: http.StatusNotFound}
emailTemplateAPI := mock.NewMockEmailTemplateAPI(ctrl)
templates := []string{
"verify_email", "reset_email", "welcome_email",
"blocked_account", "stolen_credentials",
"enrollment_email", "mfa_oob_code",
"change_password", "password_reset",
}

for _, tmpl := range templates {
emailTemplateAPI.EXPECT().
Read(gomock.Any(), tmpl).
Return(nil, mErr)
}

fetcher := emailTemplateResourceFetcher{
api: &auth0.API{
EmailTemplate: emailTemplateAPI,
},
}

data, err := fetcher.FetchData(context.Background())
assert.NoError(t, err)
assert.Len(t, data, 0)
})

t.Run("it returns an error if api call fails", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

emailTemplateAPI := mock.NewMockEmailTemplateAPI(ctrl)
emailTemplateAPI.EXPECT().
Read(gomock.Any(), gomock.Any()).
Return(nil, fmt.Errorf("failed to read email template"))

fetcher := emailTemplateResourceFetcher{
api: &auth0.API{
EmailTemplate: emailTemplateAPI,
},
}

_, err := fetcher.FetchData(context.Background())
assert.EqualError(t, err, "failed to read email template")
})
}

func TestLogStreamResourceFetcher_FetchData(t *testing.T) {
t.Run("it successfully retrieves log streams data", func(t *testing.T) {
Expand Down

0 comments on commit b612de8

Please sign in to comment.