authelia/internal/notification/smtp_notifier.go

95 lines
2.1 KiB
Go

package notification
import (
"fmt"
"net/smtp"
"github.com/clems4ever/authelia/internal/configuration/schema"
)
// SMTPNotifier a notifier to send emails to SMTP servers.
type SMTPNotifier struct {
address string
sender string
username string
password string
host string
port int
}
// NewSMTPNotifier create an SMTPNotifier targeting a given address.
func NewSMTPNotifier(configuration schema.SMTPNotifierConfiguration) *SMTPNotifier {
return &SMTPNotifier{
host: configuration.Host,
port: configuration.Port,
address: fmt.Sprintf("%s:%d", configuration.Host, configuration.Port),
sender: configuration.Sender,
username: configuration.Username,
password: configuration.Password,
}
}
func (n *SMTPNotifier) authenticatedSend(recipient string, msg string) error {
auth := smtp.PlainAuth("", n.username, n.password, n.host)
err := smtp.SendMail(fmt.Sprintf("%s:%d", n.host, n.port), auth, n.sender,
[]string{recipient}, []byte(msg))
if err != nil {
return err
}
return nil
}
func (n *SMTPNotifier) unauthenticatedSend(recipient string, msg string) error {
// Connect to the remote SMTP server.
c, err := smtp.Dial(n.address)
if err != nil {
return err
}
// Set the sender and recipient first
if err := c.Mail(n.sender); err != nil {
return err
}
if err := c.Rcpt(recipient); err != nil {
return err
}
// Send the email body.
wc, err := c.Data()
if err != nil {
return err
}
_, err = fmt.Fprintf(wc, msg)
if err != nil {
return err
}
err = wc.Close()
if err != nil {
return err
}
// Send the QUIT command and close the connection.
err = c.Quit()
if err != nil {
return err
}
return nil
}
// Send send a identity verification link to a user.
func (n *SMTPNotifier) Send(recipient string, subject string, body string) error {
msg := "From: " + n.sender + "\n" +
"To: " + recipient + "\n" +
"Subject: " + subject + "\n" +
"Content-Type: text/html\n" +
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +
body
if n.password != "" {
return n.authenticatedSend(recipient, msg)
}
return n.unauthenticatedSend(recipient, msg)
}