From 3e52620c29e6893ce1cf5e45ec4e00a37184edd6 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Wed, 28 Aug 2013 15:53:04 +0200 Subject: Added mailing interface (from other project) --- mailing/mailer.go | 13 +++++++++ mailing/mailers.go | 5 ++++ mailing/sendmail_mailer.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++ mailing/smtp_mailer.go | 60 +++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 mailing/mailer.go create mode 100644 mailing/mailers.go create mode 100644 mailing/sendmail_mailer.go create mode 100644 mailing/smtp_mailer.go diff --git a/mailing/mailer.go b/mailing/mailer.go new file mode 100644 index 0000000..c9ab8d0 --- /dev/null +++ b/mailing/mailer.go @@ -0,0 +1,13 @@ +package mailing + +import ( + "github.com/kch42/simpleconf" +) + +// Mailer is a interface that defines the Mail function. +type Mailer interface { + Mail(to, from string, msg []byte) error +} + +// MailerCreator is a function that creates a Mailer instance from config values. +type MailerCreator func(conf simpleconf.Config) (Mailer, error) diff --git a/mailing/mailers.go b/mailing/mailers.go new file mode 100644 index 0000000..7f550c5 --- /dev/null +++ b/mailing/mailers.go @@ -0,0 +1,5 @@ +package mailing + +var MailersByName = map[string]MailerCreator{ + "smtp": SMTPMailerCreator, + "sendmail": SendmailMailerCreator} diff --git a/mailing/sendmail_mailer.go b/mailing/sendmail_mailer.go new file mode 100644 index 0000000..ad864fb --- /dev/null +++ b/mailing/sendmail_mailer.go @@ -0,0 +1,73 @@ +package mailing + +import ( + "errors" + "fmt" + "github.com/kch42/simpleconf" + "os/exec" +) + +// SendmailMailer is a Mailer implementation that sends mail using a sendmail-ish executable. +// +// Sendmail-ish in this context means: +// +// * The executable must accept the from address using the `-f ` switch +// * The executable must accept the to address as a parameter +// * The executable expects a mail (including all headers) on stdin that is terminated by EOF +type SendmailMailer struct { + Exec string + Args []string +} + +func (sm SendmailMailer) Mail(to, from string, msg []byte) (outerr error) { + off := len(sm.Args) + args := make([]string, off+3) + copy(args, sm.Args) + args[off] = "-f" + args[off+1] = from + args[off+2] = to + + cmd := exec.Command(sm.Exec, args...) + pipe, err := cmd.StdinPipe() + if err != nil { + return err + } + + if err = cmd.Start(); err != nil { + return err + } + defer func() { + pipe.Close() + err := cmd.Wait() + if outerr == nil { + outerr = err + } + }() + + _, err = pipe.Write(msg) + return err +} + +// SendmailMailerCreator creates an SendmailMailer using configuration values in the [mail] section. +// +// exec - The name of the executable +// argX - (optional) Additional arguments for the executable. X is a ascending number starting with 1 +func SendmailMailerCreator(conf simpleconf.Config) (Mailer, error) { + rv := SendmailMailer{} + var err error + + if rv.Exec, err = conf.GetString("mail", "exec"); err != nil { + return rv, errors.New("Missing [mail] exec config") + } + + for i := 1; ; i++ { + arg, err := conf.GetString("mail", fmt.Sprintf("arg%d", i)) + if err != nil { + break + } + + rv.Args = append(rv.Args, arg) + } + + return rv, nil +} diff --git a/mailing/smtp_mailer.go b/mailing/smtp_mailer.go new file mode 100644 index 0000000..2a90173 --- /dev/null +++ b/mailing/smtp_mailer.go @@ -0,0 +1,60 @@ +package mailing + +import ( + "errors" + "github.com/kch42/simpleconf" + "net/smtp" +) + +// SMTPMailer is a Mailer implementation that sends mail via an smtp server. +type SMTPMailer struct { + Host string // Host is the expected hostname of the server + Addr string // Addr is the address of the server + UseCRAMMD5 bool + Username string + Password string +} + +func (sm SMTPMailer) Mail(to, from string, msg []byte) error { + var auth smtp.Auth + if sm.UseCRAMMD5 { + auth = smtp.CRAMMD5Auth(sm.Username, sm.Password) + } else { + auth = smtp.PlainAuth("", sm.Username, sm.Password, sm.Host) + } + + return smtp.SendMail(sm.Addr, auth, from, []string{to}, msg) +} + +// SMTPMailerCreator creates an SMTPMailer using configuration values in the [mail] section. +// +// addr - The address of the smtp server (go notation) +// user - Username +// passwd - Password +// crammd5 - Should CRAMMD5 (on) or PLAIN (off) be used? +// host - The expected hostname of the mailserver (can be left out, if crammd5 is on) +// +func SMTPMailerCreator(conf simpleconf.Config) (Mailer, error) { + rv := SMTPMailer{} + var err error + + if rv.Addr, err = conf.GetString("mail", "addr"); err != nil { + return rv, errors.New("Missing [mail] addr config") + } + if rv.UseCRAMMD5, err = conf.GetBool("mail", "crammd5"); err != nil { + return rv, errors.New("Missing [mail] crammd5 config") + } + if rv.Username, err = conf.GetString("mail", "user"); err != nil { + return rv, errors.New("Missing [mail] user config") + } + if rv.Password, err = conf.GetString("mail", "passwd"); err != nil { + return rv, errors.New("Missing [mail] passwd config") + } + if !rv.UseCRAMMD5 { + if rv.Host, err = conf.GetString("mail", "host"); err != nil { + return rv, errors.New("Missing [mail] host config") + } + } + + return rv, nil +} -- cgit v1.2.3-54-g00ecf