Commit bca3975fdb1111af509f4c3049c799a499661df3

Authored by Marko Tikvić
1 parent d3cc6a2895
Exists in master

email

Showing 2 changed files with 158 additions and 2 deletions   Show diff stats
... ... @@ -0,0 +1,157 @@
  1 +package webutility
  2 +
  3 +// TODO(markO): test test test test test (and open source?)
  4 +
  5 +import (
  6 + "crypto/tls"
  7 + "errors"
  8 + "fmt"
  9 + "net/smtp"
  10 + "strings"
  11 +)
  12 +
  13 +type EmailConfig struct {
  14 + ServerName string
  15 + Identity string
  16 + Username string
  17 + Password string
  18 + Host string
  19 + Port int
  20 +}
  21 +
  22 +func NewEmailConfig(ident, uname, pword, host string, port int) *EmailConfig {
  23 + return &EmailConfig{
  24 + ServerName: host + fmt.Sprintf(":%d", port),
  25 + Identity: ident,
  26 + Username: uname,
  27 + Password: pword,
  28 + Host: host,
  29 + Port: port,
  30 + }
  31 +}
  32 +
  33 +type Email struct {
  34 + To []string
  35 + From string
  36 + Subject string
  37 + Body string
  38 +}
  39 +
  40 +func NewEmail(to []string, from, subject, body string) *Email {
  41 + return &Email{
  42 + To: to,
  43 + From: from,
  44 + Subject: subject,
  45 + Body: body,
  46 + }
  47 +}
  48 +
  49 +func SendEmail(email *Email, conf *EmailConfig) error {
  50 + if email == nil {
  51 + return errors.New("no email to send")
  52 +
  53 + }
  54 +
  55 + if conf == nil {
  56 + // use (some?) default settings
  57 + conf = NewEmailConfig("", "marko.tikvic@to-net.rs", "quantumleap010", "mail.to-net.rs", 25)
  58 + }
  59 +
  60 + c, err := smtp.Dial(conf.ServerName)
  61 + if err != nil {
  62 + return err
  63 + }
  64 +
  65 + defer c.Close()
  66 +
  67 + // not sure if this is needed
  68 + //if err = c.Hello(conf.ServerName); err != nil {
  69 + // return err
  70 + //}
  71 +
  72 + if ok, _ := c.Extension("STARTTLS"); ok {
  73 + // disable stupid tls check for self-signed certificates
  74 + config := &tls.Config{
  75 + ServerName: conf.ServerName,
  76 + InsecureSkipVerify: true,
  77 + }
  78 + // for golang testing
  79 + //if testHookStartTLS != nil {
  80 + // testHookStartTLS(config)
  81 + //}
  82 + if err = c.StartTLS(config); err != nil {
  83 + return err
  84 + }
  85 + }
  86 +
  87 + /*
  88 + // don't know what to do with this
  89 + if a != nil && c.ext != nil {
  90 + if _, ok := c.ext["AUTH"]; !ok {
  91 + return errors.New("smtp: server doesn't support AUTH")
  92 + }
  93 + if err = c.Auth(a); err != nil {
  94 + return err
  95 + }
  96 + }
  97 + */
  98 +
  99 + // Set up authentication information.
  100 + auth := smtp.PlainAuth(conf.Identity, conf.Username, conf.Password, conf.Host)
  101 + if err = c.Auth(auth); err != nil {
  102 + return err
  103 + }
  104 +
  105 + if err = c.Mail(email.From); err != nil {
  106 + return err
  107 + }
  108 +
  109 + for _, addr := range email.To {
  110 + if err = c.Rcpt(addr); err != nil {
  111 + return err
  112 + }
  113 + }
  114 +
  115 + w, err := c.Data()
  116 + if err != nil {
  117 + return err
  118 + }
  119 +
  120 + _, err = w.Write(email.Bytes())
  121 + if err != nil {
  122 + return err
  123 + }
  124 +
  125 + err = w.Close()
  126 + if err != nil {
  127 + return err
  128 + }
  129 +
  130 + return c.Quit()
  131 +}
  132 +
  133 +func (e *Email) String() string {
  134 + var str strings.Builder
  135 +
  136 + str.WriteString("From:" + e.From + "\r\n")
  137 +
  138 + str.WriteString("To:")
  139 + for i, _ := range e.To {
  140 + if i > 0 {
  141 + str.WriteString(",")
  142 + }
  143 + str.WriteString(e.To[i])
  144 + }
  145 + str.WriteString("\r\n")
  146 +
  147 + str.WriteString("Subject:" + e.Subject + "\r\n")
  148 +
  149 + // body
  150 + str.WriteString("\r\n" + e.Body + "\r\n")
  151 +
  152 + return str.String()
  153 +}
  154 +
  155 +func (e *Email) Bytes() []byte {
  156 + return []byte(e.String())
  157 +}
... ...
... ... @@ -73,8 +73,7 @@ func MakeFilterString(prefix string, filters Filter, validFilters []string) (res
73 73 }
74 74 c := string(v[0])
75 75 if c == "<" || c == ">" {
76   - symbol = c
77   - v = string(v[1:])
  76 + symbol = "" // examples: >3, >=3
78 77 } else {
79 78 symbol = "="
80 79 }
... ...