From 3e08bd661909c0dc6b9c43332d7ddc171f946fde Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Mon, 21 Sep 2015 13:42:37 -0700 Subject: [PATCH] email: Add smtp emailer --- email/interface.go | 4 ++- email/mailgun.go | 5 --- email/smtp.go | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 email/smtp.go diff --git a/email/interface.go b/email/interface.go index eb9ff908..5ab5afd0 100644 --- a/email/interface.go +++ b/email/interface.go @@ -3,6 +3,7 @@ package email import ( "encoding/json" "errors" + "expvar" "fmt" "io" "os" @@ -14,7 +15,8 @@ const ( ) var ( - ErrorNoTemplate = errors.New("No HTML or Text template found for template name.") + counterEmailSendErr = expvar.NewInt("email.send.err") + ErrorNoTemplate = errors.New("No HTML or Text template found for template name.") ) func init() { diff --git a/email/mailgun.go b/email/mailgun.go index 6661f29f..ee604853 100644 --- a/email/mailgun.go +++ b/email/mailgun.go @@ -3,7 +3,6 @@ package email import ( "encoding/json" "errors" - "expvar" "github.com/coreos/dex/pkg/log" mailgun "github.com/mailgun/mailgun-go" @@ -13,10 +12,6 @@ const ( MailgunEmailerType = "mailgun" ) -var ( - counterEmailSendErr = expvar.NewInt("mailgun.send.err") -) - func init() { RegisterEmailerConfigType(MailgunEmailerType, func() EmailerConfig { return &MailgunEmailerConfig{} }) } diff --git a/email/smtp.go b/email/smtp.go new file mode 100644 index 00000000..3d5aa175 --- /dev/null +++ b/email/smtp.go @@ -0,0 +1,85 @@ +package email + +import ( + "encoding/json" + "errors" + + "gopkg.in/gomail.v2" +) + +const ( + SmtpEmailerType = "smtp" +) + +func init() { + RegisterEmailerConfigType(SmtpEmailerType, func() EmailerConfig { return &SmtpEmailerConfig{} }) +} + +type SmtpEmailerConfig struct { + ID string `json:"id"` + Host string `json:"host"` + Port int `json:"port"` + Auth string `json:"auth"` + Username string `json:"username"` + Password string `json:"password"` +} + +func (cfg SmtpEmailerConfig) EmailerType() string { + return SmtpEmailerType +} + +func (cfg SmtpEmailerConfig) EmailerID() string { + return cfg.ID +} + +func (cfg SmtpEmailerConfig) Emailer() (Emailer, error) { + var dialer *gomail.Dialer + if cfg.Auth == "plain" { + dialer = gomail.NewPlainDialer(cfg.Host, cfg.Port, cfg.Username, cfg.Password) + } else { + dialer = &gomail.Dialer{ + Host: cfg.Host, + Port: cfg.Port, + } + } + return &smtpEmailer{ + dialer: dialer, + }, nil +} + +type smtpEmailerConfig SmtpEmailerConfig + +func (cfg *SmtpEmailerConfig) UnmarshalJSON(data []byte) error { + smtpCfg := smtpEmailerConfig{} + err := json.Unmarshal(data, &smtpCfg) + if err != nil { + return err + } + if smtpCfg.Host == "" { + return errors.New("must set SMTP host") + } + if smtpCfg.Port == "" { + return errors.New("must set SMTP port") + } + *cfg = SmtpEmailerConfig(smtpCfg) + return nil +} + +type smtpEmailer struct { + dialer *gomail.Dialer +} + +func (emailer *smtpEmailer) SendMail(from, subject, text, html string, to ...string) error { + msg := gomail.NewMessage() + msg.SetHeader("From", from) + msg.SetHeader("To", to...) + msg.SetHeader("Subject", subject) + msg.SetBody("text/plain", text) + msg.SetBody("text/html", html) + err := emailer.dialer.DialAndSend(msg) + if err != nil { + counterEmailSendErr.Add(1) + return err + } + return nil +}