Skip to content

Commit

Permalink
fix: send email with local name via custom client (#607)
Browse files Browse the repository at this point in the history
* fix: send email with local name via custom client

* remove unneeded (duplicated) checks

* add `local-name` to a config file

* remove unneeded `return`

* change logs

* refactor: using smtp.Dial()

* add comments for the new fuction

* update: change a field name
  • Loading branch information
afdesk committed Sep 13, 2023
1 parent 4c539f2 commit ba3603d
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 18 deletions.
77 changes: 67 additions & 10 deletions actions/email.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package actions

import (
"crypto/tls"
"errors"
"fmt"
"log"
Expand All @@ -19,15 +20,16 @@ var (
)

type EmailAction struct {
Name string
User string
Password string
Host string
Port int
Sender string
Recipients []string
UseMX bool
sendFunc func(addr string, a smtp.Auth, from string, to []string, msg []byte) error
Name string
User string
Password string
Host string
Port int
Sender string
Recipients []string
ClientHostName string
UseMX bool
sendFunc func(addr string, a smtp.Auth, from string, to []string, msg []byte) error
}

func (email *EmailAction) GetName() string {
Expand All @@ -39,8 +41,13 @@ func (email *EmailAction) Init() error {
if email.Sender == "" {
email.Sender = email.User
}
if email.ClientHostName != "" {
log.Printf("Action %q uses a custom client name %q instead of `localhost`", email.Name, email.ClientHostName)
email.sendFunc = email.sendEmailWithCustomClient
} else {
email.sendFunc = smtp.SendMail
}

email.sendFunc = smtp.SendMail
return nil
}

Expand Down Expand Up @@ -89,6 +96,56 @@ func (email *EmailAction) Send(content map[string]string) error {
return nil
}

// sendEmailWithCustomClient replaces smtp.SendMail() in cases
// where it is necessary to establish a custom client host name instead of "localhost",
// while keeping the remaining behavior unchanged.
func (email EmailAction) sendEmailWithCustomClient(addr string, a smtp.Auth, from string, to []string, msg []byte) error {
log.Printf("Sending an email via Custom client for action %q", email.Name)

c, err := smtp.Dial(addr)
if err != nil {
return err
}
defer c.Close()

if err := c.Hello(email.ClientHostName); err != nil {
return err
}

if ok, _ := c.Extension("STARTTLS"); ok {
config := &tls.Config{ServerName: email.Host}
if err = c.StartTLS(config); err != nil {
return err
}
}
if a != nil {
if err = c.Auth(a); err != nil {
return err
}
}
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(msg)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}

func (email EmailAction) sendViaMxServers(port string, msg string, recipients []string) {
for _, rcpt := range recipients {
at := strings.LastIndex(rcpt, "@")
Expand Down
1 change: 1 addition & 0 deletions cfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ actions:
host: # Mandatory: SMTP host name (e.g. smtp.gmail.com)
port: # Mandatory: SMTP server port (e.g. 587)
sender: # Mandatory: The email address to use as a sender
client-host-name: # Optional: setting the local client name instead of `localhost`
recipients: ["", ""] # Mandatory: comma separated list of recipients

- name: my-email-smtp-server
Expand Down
17 changes: 9 additions & 8 deletions router/builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,15 @@ func buildSlackAction(sourceSettings *ActionSettings, aqua string) *actions.Slac

func buildEmailAction(sourceSettings *ActionSettings) *actions.EmailAction {
return &actions.EmailAction{
Name: sourceSettings.Name,
User: sourceSettings.User,
Password: sourceSettings.Password,
Host: sourceSettings.Host,
Port: sourceSettings.Port,
Sender: sourceSettings.Sender,
Recipients: sourceSettings.Recipients,
UseMX: sourceSettings.UseMX,
Name: sourceSettings.Name,
User: sourceSettings.User,
Password: sourceSettings.Password,
Host: sourceSettings.Host,
Port: sourceSettings.Port,
Sender: sourceSettings.Sender,
Recipients: sourceSettings.Recipients,
ClientHostName: sourceSettings.ClientHostName,
UseMX: sourceSettings.UseMX,
}
}
func buildNexusIqAction(sourceSettings *ActionSettings) *actions.NexusIqAction {
Expand Down
1 change: 1 addition & 0 deletions router/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type ActionSettings struct {
Recipients []string `json:"recipients,omitempty"`
Sender string `json:"sender,omitempty"`
Token string `json:"token,omitempty"`
ClientHostName string `json:"client-host-name,omitempty"`
UseMX bool `json:"use-mx,omitempty"`
InstanceName string `json:"instance,omitempty"`
SizeLimit int `json:"size-limit,omitempty"`
Expand Down

0 comments on commit ba3603d

Please sign in to comment.