2019-04-24 21:52:08 +00:00
package notification
import (
2019-12-20 18:40:01 +00:00
"crypto/tls"
2019-12-30 02:03:51 +00:00
"crypto/x509"
2019-12-20 18:40:01 +00:00
"errors"
2019-04-24 21:52:08 +00:00
"fmt"
2019-12-30 02:03:51 +00:00
"io/ioutil"
2019-04-24 21:52:08 +00:00
"net/smtp"
2019-12-20 18:40:01 +00:00
"strings"
2019-04-24 21:52:08 +00:00
2020-04-05 12:37:21 +00:00
log "github.com/sirupsen/logrus"
2019-12-24 02:14:52 +00:00
"github.com/authelia/authelia/internal/configuration/schema"
2019-12-20 18:40:01 +00:00
"github.com/authelia/authelia/internal/utils"
2019-04-24 21:52:08 +00:00
)
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// SMTPNotifier a notifier to send emails to SMTP servers.
2019-04-24 21:52:08 +00:00
type SMTPNotifier struct {
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
username string
password string
sender string
host string
port int
trustedCert string
disableVerifyCert bool
disableRequireTLS bool
address string
subject string
startupCheckAddress string
client * smtp . Client
tlsConfig * tls . Config
2019-04-24 21:52:08 +00:00
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// NewSMTPNotifier creates a SMTPNotifier using the notifier configuration.
2019-04-24 21:52:08 +00:00
func NewSMTPNotifier ( configuration schema . SMTPNotifierConfiguration ) * SMTPNotifier {
2019-12-30 02:03:51 +00:00
notifier := & SMTPNotifier {
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
username : configuration . Username ,
password : configuration . Password ,
sender : configuration . Sender ,
host : configuration . Host ,
port : configuration . Port ,
trustedCert : configuration . TrustedCert ,
disableVerifyCert : configuration . DisableVerifyCert ,
disableRequireTLS : configuration . DisableRequireTLS ,
address : fmt . Sprintf ( "%s:%d" , configuration . Host , configuration . Port ) ,
subject : configuration . Subject ,
startupCheckAddress : configuration . StartupCheckAddress ,
2019-04-24 21:52:08 +00:00
}
2019-12-30 02:03:51 +00:00
notifier . initializeTLSConfig ( )
return notifier
2019-04-24 21:52:08 +00:00
}
2019-12-30 02:03:51 +00:00
func ( n * SMTPNotifier ) initializeTLSConfig ( ) {
2020-04-09 01:05:17 +00:00
// Do not allow users to disable verification of certs if they have also set a trusted cert that was loaded
// The second part of this check happens in the Configure Cert Pool code block
2019-12-30 02:03:51 +00:00
log . Debug ( "Notifier SMTP client initializing TLS configuration" )
2019-04-24 21:52:08 +00:00
2020-04-09 01:05:17 +00:00
//Configure Cert Pool
2019-12-30 02:03:51 +00:00
certPool , err := x509 . SystemCertPool ( )
if err != nil || certPool == nil {
certPool = x509 . NewCertPool ( )
2019-11-02 14:32:58 +00:00
}
2019-12-30 02:03:51 +00:00
if n . trustedCert != "" {
log . Debugf ( "Notifier SMTP client attempting to load certificate from %s" , n . trustedCert )
if exists , err := utils . FileExists ( n . trustedCert ) ; exists {
pem , err := ioutil . ReadFile ( n . trustedCert )
if err != nil {
log . Warnf ( "Notifier SMTP failed to load cert from file with error: %s" , err )
} else {
if ok := certPool . AppendCertsFromPEM ( pem ) ; ! ok {
log . Warn ( "Notifier SMTP failed to import cert loaded from file" )
} else {
log . Debug ( "Notifier SMTP successfully loaded certificate" )
if n . disableVerifyCert {
log . Warn ( "Notifier SMTP when trusted_cert is specified we force disable_verify_cert to false, if you want to disable certificate validation please comment/delete trusted_cert from your config" )
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
n . disableVerifyCert = false
2019-12-30 02:03:51 +00:00
}
}
}
} else {
log . Warnf ( "Notifier SMTP failed to load cert from file (file does not exist) with error: %s" , err )
2019-12-20 18:40:01 +00:00
}
2019-12-30 02:03:51 +00:00
}
n . tlsConfig = & tls . Config {
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
InsecureSkipVerify : n . disableVerifyCert , //nolint:gosec // This is an intended config, we never default true, provide alternate options, and we constantly warn the user.
2019-12-30 02:03:51 +00:00
ServerName : n . host ,
RootCAs : certPool ,
}
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Do startTLS if available (some servers only provide the auth extension after, and encryption is preferred).
2020-04-21 05:53:47 +00:00
func ( n * SMTPNotifier ) startTLS ( ) ( err error ) {
2020-04-09 01:05:17 +00:00
// Only start if not already encrypted
2019-12-30 02:03:51 +00:00
if _ , ok := n . client . TLSConnectionState ( ) ; ok {
log . Debugf ( "Notifier SMTP connection is already encrypted, skipping STARTTLS" )
2020-04-21 05:53:47 +00:00
return
2019-12-30 02:03:51 +00:00
}
ok , _ := n . client . Extension ( "STARTTLS" )
if ok {
log . Debugf ( "Notifier SMTP server supports STARTTLS (disableVerifyCert: %t, ServerName: %s), attempting" , n . tlsConfig . InsecureSkipVerify , n . tlsConfig . ServerName )
2020-04-21 05:53:47 +00:00
err = n . client . StartTLS ( n . tlsConfig )
2019-12-20 18:40:01 +00:00
if err != nil {
2020-04-21 05:53:47 +00:00
return
2019-12-20 18:40:01 +00:00
}
2020-04-09 01:05:17 +00:00
log . Debug ( "Notifier SMTP STARTTLS completed without error" )
2019-12-30 02:03:51 +00:00
} else if n . disableRequireTLS {
log . Warn ( "Notifier SMTP server does not support STARTTLS and SMTP configuration is set to disable the TLS requirement (only useful for unauthenticated emails over plain text)" )
2019-12-20 18:40:01 +00:00
} else {
2020-04-21 05:53:47 +00:00
return errors . New ( "Notifier SMTP server does not support TLS and it is required by default (see documentation if you want to disable this highly recommended requirement)" )
2019-12-20 18:40:01 +00:00
}
2020-04-21 05:53:47 +00:00
return
2019-12-30 02:03:51 +00:00
}
2019-12-20 18:40:01 +00:00
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Attempt Authentication.
2020-04-21 05:53:47 +00:00
func ( n * SMTPNotifier ) auth ( ) ( err error ) {
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Attempt AUTH if password is specified only.
2019-12-20 18:40:01 +00:00
if n . password != "" {
2019-12-30 02:03:51 +00:00
_ , ok := n . client . TLSConnectionState ( )
if ! ok {
2020-04-21 05:53:47 +00:00
return errors . New ( "Notifier SMTP client does not support authentication over plain text and the connection is currently plain text" )
2019-12-28 02:49:29 +00:00
}
2019-12-20 18:40:01 +00:00
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Check the server supports AUTH, and get the mechanisms.
2019-12-30 02:03:51 +00:00
ok , m := n . client . Extension ( "AUTH" )
if ok {
log . Debugf ( "Notifier SMTP server supports authentication with the following mechanisms: %s" , m )
2019-12-20 18:40:01 +00:00
mechanisms := strings . Split ( m , " " )
var auth smtp . Auth
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Adaptively select the AUTH mechanism to use based on what the server advertised.
2019-12-20 18:40:01 +00:00
if utils . IsStringInSlice ( "PLAIN" , mechanisms ) {
auth = smtp . PlainAuth ( "" , n . username , n . password , n . host )
2019-12-30 02:03:51 +00:00
log . Debug ( "Notifier SMTP client attempting AUTH PLAIN with server" )
2019-12-20 18:40:01 +00:00
} else if utils . IsStringInSlice ( "LOGIN" , mechanisms ) {
2019-12-30 02:03:51 +00:00
auth = newLoginAuth ( n . username , n . password , n . host )
log . Debug ( "Notifier SMTP client attempting AUTH LOGIN with server" )
2019-12-20 18:40:01 +00:00
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Throw error since AUTH extension is not supported.
2019-12-20 18:40:01 +00:00
if auth == nil {
2020-04-21 05:53:47 +00:00
return fmt . Errorf ( "notifier SMTP server does not advertise a AUTH mechanism that are supported by Authelia (PLAIN or LOGIN are supported, but server advertised %s mechanisms)" , m )
2019-12-20 18:40:01 +00:00
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Authenticate.
2020-04-21 05:53:47 +00:00
err = n . client . Auth ( auth )
2019-12-20 18:40:01 +00:00
if err != nil {
2020-04-21 05:53:47 +00:00
return
2019-12-20 18:40:01 +00:00
}
2020-04-09 01:05:17 +00:00
log . Debug ( "Notifier SMTP client authenticated successfully with the server" )
2020-04-21 05:53:47 +00:00
return nil
2019-12-20 18:40:01 +00:00
}
2020-04-21 05:53:47 +00:00
return errors . New ( "Notifier SMTP server does not advertise the AUTH extension but config requires AUTH (password specified), either disable AUTH, or use an SMTP host that supports AUTH PLAIN or AUTH LOGIN" )
2019-12-20 18:40:01 +00:00
}
2020-04-09 01:05:17 +00:00
log . Debug ( "Notifier SMTP config has no password specified so authentication is being skipped" )
2020-04-21 05:53:47 +00:00
return nil
2019-12-30 02:03:51 +00:00
}
2019-12-20 18:40:01 +00:00
2020-04-21 05:53:47 +00:00
func ( n * SMTPNotifier ) compose ( recipient , subject , body string ) ( err error ) {
2019-12-30 02:03:51 +00:00
log . Debugf ( "Notifier SMTP client attempting to send email body to %s" , recipient )
if ! n . disableRequireTLS {
_ , ok := n . client . TLSConnectionState ( )
if ! ok {
return errors . New ( "Notifier SMTP client can't send an email over plain text connection" )
}
}
wc , err := n . client . Data ( )
if err != nil {
log . Debugf ( "Notifier SMTP client error while obtaining WriteCloser: %s" , err )
return err
}
msg := "From: " + n . sender + "\n" +
"To: " + recipient + "\n" +
"Subject: " + subject + "\n" +
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +
body
2020-04-09 01:05:17 +00:00
_ , err = fmt . Fprint ( wc , msg )
2019-12-30 02:03:51 +00:00
if err != nil {
log . Debugf ( "Notifier SMTP client error while sending email body over WriteCloser: %s" , err )
2019-04-24 21:52:08 +00:00
return err
}
2019-12-30 02:03:51 +00:00
err = wc . Close ( )
if err != nil {
log . Debugf ( "Notifier SMTP client error while closing the WriteCloser: %s" , err )
2019-04-24 21:52:08 +00:00
return err
}
2019-12-30 02:03:51 +00:00
return nil
}
2019-04-24 21:52:08 +00:00
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Dial the SMTP server with the SMTPNotifier config.
2020-04-21 05:53:47 +00:00
func ( n * SMTPNotifier ) dial ( ) ( err error ) {
2019-12-30 02:03:51 +00:00
log . Debugf ( "Notifier SMTP client attempting connection to %s" , n . address )
2020-02-20 01:09:46 +00:00
if n . port == 465 {
log . Warnf ( "Notifier SMTP client configured to connect to a SMTPS server. It's highly recommended you use a non SMTPS port and STARTTLS instead of SMTPS, as the protocol is long deprecated." )
conn , err := tls . Dial ( "tcp" , n . address , n . tlsConfig )
if err != nil {
return err
}
client , err := smtp . NewClient ( conn , n . host )
if err != nil {
return err
}
n . client = client
} else {
client , err := smtp . Dial ( n . address )
if err != nil {
return err
}
n . client = client
2019-04-24 21:52:08 +00:00
}
2019-12-30 02:03:51 +00:00
log . Debug ( "Notifier SMTP client connected successfully" )
return nil
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Closes the connection properly.
2020-01-28 04:00:43 +00:00
func ( n * SMTPNotifier ) cleanup ( ) {
err := n . client . Quit ( )
if err != nil {
log . Warnf ( "Notifier SMTP client encountered error during cleanup: %s" , err )
}
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// StartupCheck checks the server is functioning correctly and the configuration is correct.
func ( n * SMTPNotifier ) StartupCheck ( ) ( ok bool , err error ) {
ok = true
if err = n . dial ( ) ; err != nil {
ok = false
return
}
defer n . cleanup ( )
2020-04-21 05:53:47 +00:00
if err = n . startTLS ( ) ; err != nil {
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
ok = false
return
}
2020-04-21 05:53:47 +00:00
if err = n . auth ( ) ; err != nil {
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
ok = false
return
}
if err = n . client . Mail ( n . sender ) ; err != nil {
ok = false
return
}
if err = n . client . Rcpt ( n . startupCheckAddress ) ; err != nil {
ok = false
return
}
if err = n . client . Reset ( ) ; err != nil {
ok = false
return
}
return
}
// Send is used to send an email to a recipient.
2020-04-09 00:21:28 +00:00
func ( n * SMTPNotifier ) Send ( recipient , title , body string ) error {
subject := strings . ReplaceAll ( n . subject , "{title}" , title )
2020-01-28 04:00:43 +00:00
if err := n . dial ( ) ; err != nil {
2019-04-24 21:52:08 +00:00
return err
}
2019-12-30 02:03:51 +00:00
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Always execute QUIT at the end once we're connected.
2020-01-28 04:00:43 +00:00
defer n . cleanup ( )
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Start TLS and then Authenticate.
2020-04-21 05:53:47 +00:00
if err := n . startTLS ( ) ; err != nil {
2019-12-30 02:03:51 +00:00
return err
}
2020-04-21 05:53:47 +00:00
if err := n . auth ( ) ; err != nil {
2019-12-30 02:03:51 +00:00
return err
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Set the sender and recipient first.
2019-12-30 02:03:51 +00:00
if err := n . client . Mail ( n . sender ) ; err != nil {
log . Debugf ( "Notifier SMTP failed while sending MAIL FROM (using sender) with error: %s" , err )
return err
}
if err := n . client . Rcpt ( recipient ) ; err != nil {
log . Debugf ( "Notifier SMTP failed while sending RCPT TO (using recipient) with error: %s" , err )
return err
}
[FEATURE] Notifier Startup Checks (#889)
* implement SMTP notifier startup check
* check dial, starttls, auth, mail from, rcpt to, reset, and quit
* log the error on failure
* implement mock
* misc optimizations, adjustments, and refactoring
* implement validate_skip config option
* fix comments to end with period
* fix suites that used smtp notifier without a smtp container
* add docs
* add file notifier startup check
* move file mode into const.go
* disable gosec linting on insecureskipverify since it's intended, warned, and discouraged
* minor PR commentary adjustment
* apply suggestions from code review
Co-Authored-By: Amir Zarrinkafsh <nightah@me.com>
2020-04-21 04:59:38 +00:00
// Compose and send the email body to the server.
2019-12-30 02:03:51 +00:00
if err := n . compose ( recipient , subject , body ) ; err != nil {
2019-04-24 21:52:08 +00:00
return err
}
2019-12-30 02:03:51 +00:00
log . Debug ( "Notifier SMTP client successfully sent email" )
2019-04-24 21:52:08 +00:00
return nil
}