Skip to content

Commit

Permalink
feat: add support for email configuration additional headers (#237)
Browse files Browse the repository at this point in the history
* feat: add support for email configuration additional headers

* fix: retain backwards compatibility with existing syntax

During implementation I initially aligned the notation more closely with syntax used elsewhere in the project. However, due to that being a breaking change for existing users that was reconsidered.
  • Loading branch information
marco-tresch authored Oct 4, 2023
1 parent e6a9a69 commit 4268a39
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 12 deletions.
4 changes: 4 additions & 0 deletions docs/resources/tenant.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ resource "fusionauth_tenant" "example" {
username = "username"
verify_email = true
verify_email_when_changed = true
additional_headers = {
"HeaderName1" = "HeaderValue1"
"HeaderName2" = "HeaderValue2"
}
}
event_configuration {
enabled = false
Expand Down
60 changes: 48 additions & 12 deletions fusionauth/resource_fusionauth_tenant_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ func buildTenant(data *schema.ResourceData) (fusionauth.Tenant, diag.Diagnostics
tenant := fusionauth.Tenant{
Data: data.Get("data").(map[string]interface{}),
EmailConfiguration: fusionauth.EmailConfiguration{
// AdditionalHeaders: data.Get("email_configuration.0.additional_headers").(string),
EmailUpdateEmailTemplateId: data.Get("email_configuration.0.email_update_email_template_id").(string),
EmailVerifiedEmailTemplateId: data.Get("email_configuration.0.email_verified_email_template_id").(string),
ImplicitEmailVerificationAllowed: data.Get("email_configuration.0.implicit_email_verification_allowed").(bool),
Expand Down Expand Up @@ -301,12 +300,44 @@ func buildTenant(data *schema.ResourceData) (fusionauth.Tenant, diag.Diagnostics
},
}

connectorPolicies, diags := buildConnectorPolicies(data)
if diags == nil {
connectorPolicies, connectorDiags := buildConnectorPolicies(data)
if connectorDiags == nil {
tenant.ConnectorPolicies = connectorPolicies
}

return tenant, diags
additionalheaders, emailDiags := buildAdditionalHeaders(data)
if emailDiags == nil {
tenant.EmailConfiguration.AdditionalHeaders = additionalheaders
}

return tenant, append(connectorDiags, emailDiags...)
}

func buildAdditionalHeaders(data *schema.ResourceData) (emailHeaders []fusionauth.EmailHeader, diags diag.Diagnostics) {
emailHeadersData, ok := data.Get("email_configuration.0.additional_headers").(map[string]interface{})
if emailHeadersData == nil || !ok {
if !ok {
diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: "Unable to convert additional headers data",
Detail: "additional_headers unable to be typecast to map[string]interface{}",
})
}

// Nothing to do here!
return emailHeaders, diags
}

emailHeaders = make([]fusionauth.EmailHeader, len(emailHeadersData))
i := 0
for headerName, headerValue := range emailHeadersData {
emailHeaders[i] = fusionauth.EmailHeader{
Name: headerName,
Value: headerValue.(string),
}
i++
}
return emailHeaders, diags
}

func buildConnectorPolicies(data *schema.ResourceData) (connectorPolicies []fusionauth.ConnectorPolicy, diags diag.Diagnostics) {
Expand Down Expand Up @@ -389,9 +420,14 @@ func buildResourceDataFromTenant(t fusionauth.Tenant, data *schema.ResourceData)
return diag.Errorf("tenant.connector_policy: %s", err.Error())
}

additionalHeaders := make(map[string]string, len(t.EmailConfiguration.AdditionalHeaders))
for _, additionalHeader := range t.EmailConfiguration.AdditionalHeaders {
additionalHeaders[additionalHeader.Name] = additionalHeader.Value
}

err := data.Set("email_configuration", []map[string]interface{}{
{
// "additional_headers": t.EmailConfiguration.AdditionalHeaders,
"additional_headers": additionalHeaders,
"email_update_email_template_id": t.EmailConfiguration.EmailUpdateEmailTemplateId,
"email_verified_email_template_id": t.EmailConfiguration.EmailVerifiedEmailTemplateId,
"forgot_password_email_template_id": t.EmailConfiguration.ForgotPasswordEmailTemplateId,
Expand All @@ -411,13 +447,13 @@ func buildResourceDataFromTenant(t fusionauth.Tenant, data *schema.ResourceData)
"set_password_email_template_id": t.EmailConfiguration.SetPasswordEmailTemplateId,
"two_factor_method_add_email_template_id": t.EmailConfiguration.TwoFactorMethodAddEmailTemplateId,
"two_factor_method_remove_email_template_id": t.EmailConfiguration.TwoFactorMethodRemoveEmailTemplateId,
"username": t.EmailConfiguration.Username,
"verification_email_template_id": t.EmailConfiguration.VerificationEmailTemplateId,
"verification_strategy": t.EmailConfiguration.VerificationStrategy,
"verify_email": t.EmailConfiguration.VerifyEmail,
"verify_email_when_changed": t.EmailConfiguration.VerifyEmailWhenChanged,
"default_from_email": t.EmailConfiguration.DefaultFromEmail,
"default_from_name": t.EmailConfiguration.DefaultFromName,
"username": t.EmailConfiguration.Username,
"verification_email_template_id": t.EmailConfiguration.VerificationEmailTemplateId,
"verification_strategy": t.EmailConfiguration.VerificationStrategy,
"verify_email": t.EmailConfiguration.VerifyEmail,
"verify_email_when_changed": t.EmailConfiguration.VerifyEmailWhenChanged,
"default_from_email": t.EmailConfiguration.DefaultFromEmail,
"default_from_name": t.EmailConfiguration.DefaultFromName,
"unverified": []map[string]interface{}{{
"allow_email_change_when_gated": t.EmailConfiguration.Unverified.AllowEmailChangeWhenGated,
"behavior": t.EmailConfiguration.Unverified.Behavior,
Expand Down
13 changes: 13 additions & 0 deletions fusionauth/resource_fusionauth_tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func testTenantAccTestCheckFuncs(
resource.TestCheckResourceAttr(tfResourcePath, "data.lives", "here"),

// email_configuration
testAccCheckEmailConfigurationAdditionalHeaders(tfResourcePath),
resource.TestCheckResourceAttr(tfResourcePath, "email_configuration.0.default_from_name", "noreply"),
resource.TestCheckResourceAttr(tfResourcePath, "email_configuration.0.default_from_email", fromEmail),
// resource.TestCheckResourceAttr(tfResourcePath, "email_configuration.0.forgot_password_email_template_id", "UUID"),
Expand Down Expand Up @@ -303,6 +304,14 @@ func testAccCheckConnectorPolicies(tfResourcePath string, genericConnectorInclud
)
}

func testAccCheckEmailConfigurationAdditionalHeaders(tfResourcePath string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(tfResourcePath, "email_configuration.0.additional_headers.%", "2"),
resource.TestCheckResourceAttr(tfResourcePath, "email_configuration.0.additional_headers.HeaderName1", "HeaderValue1"),
resource.TestCheckResourceAttr(tfResourcePath, "email_configuration.0.additional_headers.HeaderName2", "HeaderValue2"),
)
}

func testAccCheckFusionauthTenantExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
Expand Down Expand Up @@ -471,6 +480,10 @@ resource "fusionauth_tenant" "test_%[1]s" {
}
email_configuration {
default_from_name = "noreply"
additional_headers = {
"HeaderName1" = "HeaderValue1"
"HeaderName2" = "HeaderValue2"
}
default_from_email = "%[3]s"
#forgot_password_email_template_id = ""
host = "smtp.example.com"
Expand Down

0 comments on commit 4268a39

Please sign in to comment.