2014-07-27 02:37:18 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
2019-04-02 10:48:31 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
2014-07-27 02:37:18 +04:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package log
import (
"encoding/json"
"net/smtp"
"strings"
)
2019-04-02 10:48:31 +03:00
type smtpWriter struct {
owner * SMTPLogger
}
// Write sends the message as an email
func ( s * smtpWriter ) Write ( p [ ] byte ) ( int , error ) {
return s . owner . sendMail ( p )
}
// Close does nothing
func ( s * smtpWriter ) Close ( ) error {
return nil
}
// SMTPLogger implements LoggerProvider and is used to send emails via given SMTP-server.
type SMTPLogger struct {
2019-04-07 03:25:14 +03:00
WriterLogger
2014-07-27 02:37:18 +04:00
Username string ` json:"Username" `
Password string ` json:"password" `
2019-04-02 10:48:31 +03:00
Host string ` json:"host" `
2014-07-27 02:37:18 +04:00
Subject string ` json:"subject" `
RecipientAddresses [ ] string ` json:"sendTos" `
2019-04-02 10:48:31 +03:00
sendMailFn func ( string , smtp . Auth , string , [ ] string , [ ] byte ) error
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
// NewSMTPLogger creates smtp writer.
func NewSMTPLogger ( ) LoggerProvider {
s := & SMTPLogger { }
s . Level = TRACE
s . sendMailFn = smtp . SendMail
return s
2014-07-27 02:37:18 +04:00
}
2016-11-26 14:53:29 +03:00
// Init smtp writer with json config.
2014-07-27 02:37:18 +04:00
// config like:
// {
// "Username":"example@gmail.com",
// "password:"password",
// "host":"smtp.gmail.com:465",
// "subject":"email title",
// "sendTos":["email1","email2"],
// "level":LevelError
// }
2019-04-02 10:48:31 +03:00
func ( log * SMTPLogger ) Init ( jsonconfig string ) error {
err := json . Unmarshal ( [ ] byte ( jsonconfig ) , log )
if err != nil {
return err
}
2019-04-07 03:25:14 +03:00
log . NewWriterLogger ( & smtpWriter {
2019-04-02 10:48:31 +03:00
owner : log ,
} )
log . sendMailFn = smtp . SendMail
return nil
2014-07-27 02:37:18 +04:00
}
2016-11-26 14:53:29 +03:00
// WriteMsg writes message in smtp writer.
2014-07-27 02:37:18 +04:00
// it will send an email with subject and only this message.
2019-04-02 10:48:31 +03:00
func ( log * SMTPLogger ) sendMail ( p [ ] byte ) ( int , error ) {
hp := strings . Split ( log . Host , ":" )
2014-07-27 02:37:18 +04:00
// Set up authentication information.
auth := smtp . PlainAuth (
"" ,
2019-04-02 10:48:31 +03:00
log . Username ,
log . Password ,
2014-07-27 02:37:18 +04:00
hp [ 0 ] ,
)
// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
2016-11-26 14:53:29 +03:00
contentType := "Content-Type: text/plain" + "; charset=UTF-8"
2019-04-02 10:48:31 +03:00
mailmsg := [ ] byte ( "To: " + strings . Join ( log . RecipientAddresses , ";" ) + "\r\nFrom: " + log . Username + "<" + log . Username +
">\r\nSubject: " + log . Subject + "\r\n" + contentType + "\r\n\r\n" )
mailmsg = append ( mailmsg , p ... )
return len ( p ) , log . sendMailFn (
log . Host ,
2014-07-27 02:37:18 +04:00
auth ,
2019-04-02 10:48:31 +03:00
log . Username ,
log . RecipientAddresses ,
2014-07-27 02:37:18 +04:00
mailmsg ,
)
}
2016-11-26 14:53:29 +03:00
// Flush when log should be flushed
2019-04-02 10:48:31 +03:00
func ( log * SMTPLogger ) Flush ( ) {
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
// GetName returns the default name for this implementation
func ( log * SMTPLogger ) GetName ( ) string {
return "smtp"
2014-07-27 02:37:18 +04:00
}
func init ( ) {
2019-04-02 10:48:31 +03:00
Register ( "smtp" , NewSMTPLogger )
2014-07-27 02:37:18 +04:00
}