Commit edd7c4f4d70a4a883d03a5e53fe677c8d98e1660

Authored by Marko Tikvić
1 parent c99e4944e5
Exists in master

new email interface

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