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  }