You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smtp.go 2.8KB

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