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.7KB

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