135 lines
3.4 KiB
Go
135 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net/smtp"
|
|
"text/template"
|
|
|
|
"github.com/jordan-wright/email"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type EmailTemplate struct {
|
|
Subject string
|
|
Body string
|
|
}
|
|
|
|
var emailTemplates = map[string]EmailTemplate{
|
|
"peer_created": {
|
|
Subject: "New Peer Created: {{.Peer.IP}}",
|
|
Body: "Peer {{.Peer.IP}} was created on server {{.Server.Name}}.\nPublic Key: {{.Peer.PublicKey}}",
|
|
},
|
|
"peer_deleted": {
|
|
Subject: "Peer Deleted: {{.Peer.IP}}",
|
|
Body: "Peer {{.Peer.IP}} was deleted from server {{.Server.Name}}.",
|
|
},
|
|
"policy_changed": {
|
|
Subject: "Policy Updated for {{.Peer.IP}}",
|
|
Body: "Policy updated for peer {{.Peer.IP}} on server {{.Server.Name}}.\nChanges: {{range .Policy.Changes}}{{.}} {{end}}",
|
|
},
|
|
}
|
|
|
|
func GetSMTPSettings() (settings SMTPSettings, err error) {
|
|
err = db.First(&settings).Error
|
|
if err == gorm.ErrRecordNotFound {
|
|
return SMTPSettings{}, nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func SaveSMTPSettings(settings SMTPSettings) error {
|
|
var existing SMTPSettings
|
|
if err := db.First(&existing).Error; err == gorm.ErrRecordNotFound {
|
|
return db.Create(&settings).Error
|
|
}
|
|
return db.Model(&existing).Updates(settings).Error
|
|
}
|
|
|
|
func SendEmail(to, templateName string, data map[string]interface{}) error {
|
|
settings, err := GetSMTPSettings()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !settings.Enabled {
|
|
return fmt.Errorf("SMTP is disabled")
|
|
}
|
|
|
|
template, ok := emailTemplates[templateName]
|
|
if !ok {
|
|
return fmt.Errorf("template %s not found", templateName)
|
|
}
|
|
|
|
subject, err := renderTemplate(template.Subject, data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
body, err := renderTemplate(template.Body, data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
e := email.NewEmail()
|
|
e.From = fmt.Sprintf("%s <%s>", settings.FromName, settings.FromEmail)
|
|
e.To = []string{to}
|
|
e.Subject = subject
|
|
e.Text = []byte(body)
|
|
|
|
addr := fmt.Sprintf("%s:%d", settings.Server, settings.Port)
|
|
if settings.UseAuth {
|
|
return e.Send(addr, smtp.PlainAuth("", settings.Username, settings.Password, settings.Server))
|
|
}
|
|
return e.Send(addr, nil)
|
|
}
|
|
|
|
func TestSMTP(settings SMTPSettings) error {
|
|
e := email.NewEmail()
|
|
e.From = fmt.Sprintf("%s <%s>", settings.FromName, settings.FromEmail)
|
|
e.To = []string{settings.FromEmail}
|
|
e.Subject = "WGRplane SMTP Test"
|
|
e.Text = []byte("This is a test email from WGRplane.")
|
|
|
|
addr := fmt.Sprintf("%s:%d", settings.Server, settings.Port)
|
|
if settings.UseAuth {
|
|
return e.Send(addr, smtp.PlainAuth("", settings.Username, settings.Password, settings.Server))
|
|
}
|
|
return e.Send(addr, nil)
|
|
}
|
|
|
|
func renderTemplate(tmpl string, data map[string]interface{}) (string, error) {
|
|
t, err := template.New("email").Parse(tmpl)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := t.Execute(&buf, data); err != nil {
|
|
return "", err
|
|
}
|
|
return buf.String(), nil
|
|
}
|
|
|
|
func NotifyPeerCreated(server *Server, peer *Peer) error {
|
|
data := map[string]interface{}{
|
|
"Server": server,
|
|
"Peer": peer,
|
|
}
|
|
return SendEmail(server.Endpoint, "peer_created", data)
|
|
}
|
|
|
|
func NotifyPeerDeleted(server *Server, peer *Peer) error {
|
|
data := map[string]interface{}{
|
|
"Server": server,
|
|
"Peer": peer,
|
|
}
|
|
return SendEmail(server.Endpoint, "peer_deleted", data)
|
|
}
|
|
|
|
func NotifyPolicyChanged(server *Server, peer *Peer, changes []string) error {
|
|
data := map[string]interface{}{
|
|
"Server": server,
|
|
"Peer": peer,
|
|
"Policy": Policy{Action: "updated", Changes: changes},
|
|
}
|
|
return SendEmail(server.Endpoint, "policy_changed", data)
|
|
}
|