github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/log/smtp.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 // Copyright 2014 The Gogs Authors. All rights reserved. 7 8 package log 9 10 import ( 11 "fmt" 12 "net/smtp" 13 "strings" 14 15 "github.com/gitbundle/modules/json" 16 ) 17 18 type smtpWriter struct { 19 owner *SMTPLogger 20 } 21 22 // Write sends the message as an email 23 func (s *smtpWriter) Write(p []byte) (int, error) { 24 return s.owner.sendMail(p) 25 } 26 27 // Close does nothing 28 func (s *smtpWriter) Close() error { 29 return nil 30 } 31 32 // SMTPLogger implements LoggerProvider and is used to send emails via given SMTP-server. 33 type SMTPLogger struct { 34 WriterLogger 35 Username string `json:"Username"` 36 Password string `json:"password"` 37 Host string `json:"host"` 38 Subject string `json:"subject"` 39 RecipientAddresses []string `json:"sendTos"` 40 sendMailFn func(string, smtp.Auth, string, []string, []byte) error 41 } 42 43 // NewSMTPLogger creates smtp writer. 44 func NewSMTPLogger() LoggerProvider { 45 s := &SMTPLogger{} 46 s.Level = TRACE 47 s.sendMailFn = smtp.SendMail 48 return s 49 } 50 51 // Init smtp writer with json config. 52 // config like: 53 // 54 // { 55 // "Username":"example@gmail.com", 56 // "password:"password", 57 // "host":"smtp.gmail.com:465", 58 // "subject":"email title", 59 // "sendTos":["email1","email2"], 60 // "level":LevelError 61 // } 62 func (log *SMTPLogger) Init(jsonconfig string) error { 63 err := json.Unmarshal([]byte(jsonconfig), log) 64 if err != nil { 65 return fmt.Errorf("Unable to parse JSON: %v", err) 66 } 67 log.NewWriterLogger(&smtpWriter{ 68 owner: log, 69 }) 70 log.sendMailFn = smtp.SendMail 71 return nil 72 } 73 74 // WriteMsg writes message in smtp writer. 75 // it will send an email with subject and only this message. 76 func (log *SMTPLogger) sendMail(p []byte) (int, error) { 77 hp := strings.Split(log.Host, ":") 78 79 // Set up authentication information. 80 auth := smtp.PlainAuth( 81 "", 82 log.Username, 83 log.Password, 84 hp[0], 85 ) 86 // Connect to the server, authenticate, set the sender and recipient, 87 // and send the email all in one step. 88 contentType := "Content-Type: text/plain" + "; charset=UTF-8" 89 mailmsg := []byte("To: " + strings.Join(log.RecipientAddresses, ";") + "\r\nFrom: " + log.Username + "<" + log.Username + 90 ">\r\nSubject: " + log.Subject + "\r\n" + contentType + "\r\n\r\n") 91 mailmsg = append(mailmsg, p...) 92 return len(p), log.sendMailFn( 93 log.Host, 94 auth, 95 log.Username, 96 log.RecipientAddresses, 97 mailmsg, 98 ) 99 } 100 101 // Content returns the content accumulated in the content provider 102 func (log *SMTPLogger) Content() (string, error) { 103 return "", fmt.Errorf("not supported") 104 } 105 106 // Flush when log should be flushed 107 func (log *SMTPLogger) Flush() { 108 } 109 110 // ReleaseReopen does nothing 111 func (log *SMTPLogger) ReleaseReopen() error { 112 return nil 113 } 114 115 // GetName returns the default name for this implementation 116 func (log *SMTPLogger) GetName() string { 117 return "smtp" 118 } 119 120 func init() { 121 Register("smtp", NewSMTPLogger) 122 }