Commit f6e0abe6 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

refactor: use email helper for sending keyshare emails

parent db1cf0e6
package server
import "net/smtp"
func SendHTMLMail(addr string, a smtp.Auth, from, to, subject string, msg []byte) error {
headers := []byte("To: " + to + "\r\n" +
"From: " + from + "\r\n" +
"Subject: " + subject + "\r\n" +
"Content-Type: text/html; charset=UTF-8\r\n" +
"Content-Transfer-Encoding: binary\r\n" +
"\r\n")
return smtp.SendMail(addr, a, from, []string{to}, append(headers, msg...))
}
package keyshare
import (
"bytes"
"html/template"
"net/smtp"
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago/server"
)
type EmailConfiguration struct {
......@@ -42,10 +44,52 @@ func (conf EmailConfiguration) TranslateString(strings map[string]string, lang s
return strings[conf.DefaultLanguage]
}
func (conf EmailConfiguration) TranslateTemplate(templates map[string]*template.Template, lang string) *template.Template {
func (conf EmailConfiguration) translateTemplate(templates map[string]*template.Template, lang string) *template.Template {
t, ok := templates[lang]
if ok {
return t
}
return templates[conf.DefaultLanguage]
}
func (conf EmailConfiguration) SendEmail(
templates map[string]*template.Template,
subjects map[string]string,
templateData map[string]string,
emails []string,
lang string,
) error {
var msg bytes.Buffer
err := conf.translateTemplate(templates, lang).Execute(&msg, templateData)
if err != nil {
server.Logger.WithField("error", err).Error("Could not generate email from template")
return err
}
for _, email := range emails {
err = sendHTMLEmail(
conf.EmailServer,
conf.EmailAuth,
conf.EmailFrom,
email,
conf.TranslateString(subjects, lang),
msg.Bytes(),
)
if err != nil {
server.Logger.WithField("error", err).Error("Could not send email")
return err
}
}
return nil
}
func sendHTMLEmail(addr string, a smtp.Auth, from, to, subject string, msg []byte) error {
headers := []byte("To: " + to + "\r\n" +
"From: " + from + "\r\n" +
"Subject: " + subject + "\r\n" +
"Content-Type: text/html; charset=UTF-8\r\n" +
"Content-Transfer-Encoding: binary\r\n" +
"\r\n")
return smtp.SendMail(addr, a, from, []string{to}, append(headers, msg...))
}
package keyshareserver
import (
"bytes"
"context"
"fmt"
"net/http"
......@@ -521,11 +520,6 @@ func (s *Server) doRegistration(msg irma.KeyshareEnrollment) (*irma.Qr, error) {
}
func (s *Server) sendRegistrationEmail(user *KeyshareUser, language, email string) error {
// Fetch template and configuration data for users language, falling back if needed
template := s.conf.TranslateTemplate(s.conf.registrationEmailTemplates, language)
verificationBaseURL := s.conf.TranslateString(s.conf.VerificationURL, language)
subject := s.conf.TranslateString(s.conf.RegistrationEmailSubject, language)
// Generate token
token := common.NewSessionToken()
......@@ -536,29 +530,14 @@ func (s *Server) sendRegistrationEmail(user *KeyshareUser, language, email strin
return err
}
// Build message
var msg bytes.Buffer
err = template.Execute(&msg, map[string]string{"VerificationURL": verificationBaseURL + token})
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not generate email verification mail")
return err
}
// And send it
err = server.SendHTMLMail(
s.conf.EmailServer,
s.conf.EmailAuth,
s.conf.EmailFrom,
email,
subject,
msg.Bytes())
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not send email verification mail")
return err
}
return nil
verificationBaseURL := s.conf.TranslateString(s.conf.VerificationURL, language)
return s.conf.SendEmail(
s.conf.registrationEmailTemplates,
s.conf.RegistrationEmailSubject,
map[string]string{"VerificationURL": verificationBaseURL + token},
[]string{email},
language,
)
}
func (s *Server) userMiddleware(next http.Handler) http.Handler {
......
package myirmaserver
import (
"bytes"
"context"
"net/http"
"strconv"
......@@ -131,29 +130,17 @@ func (s *Server) sendDeleteEmails(session *Sessiondata) error {
return err
}
template := s.conf.TranslateTemplate(s.conf.deleteAccountTemplates, userData.language)
subject := s.conf.TranslateString(s.conf.DeleteAccountSubject, userData.language)
var emsg bytes.Buffer
err = template.Execute(&emsg, map[string]string{"Username": userData.Username})
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not render account deletion email")
return err
}
emails := make([]string, 0, len(userData.Emails))
for _, email := range userData.Emails {
err = server.SendHTMLMail(
s.conf.EmailServer,
s.conf.EmailAuth,
s.conf.EmailFrom,
email.Email,
subject,
emsg.Bytes())
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not send account deletion email")
return err
}
}
return nil
emails = append(emails, email.Email)
}
return s.conf.SendEmail(
s.conf.deleteAccountTemplates,
s.conf.DeleteAccountFiles,
map[string]string{"Username": userData.Username},
emails,
userData.language,
)
}
func (s *Server) handleDeleteUser(w http.ResponseWriter, r *http.Request) {
......@@ -212,30 +199,14 @@ func (s *Server) sendLoginEmail(request EmailLoginRequest) error {
return err
}
template := s.conf.TranslateTemplate(s.conf.loginEmailTemplates, request.Language)
subject := s.conf.TranslateString(s.conf.LoginEmailSubject, request.Language)
baseURL := s.conf.TranslateString(s.conf.LoginEmailBaseURL, request.Language)
var emsg bytes.Buffer
err = template.Execute(&emsg, map[string]string{"TokenURL": baseURL + token})
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not generate login mail from template")
return err
}
err = server.SendHTMLMail(
s.conf.EmailServer,
s.conf.EmailAuth,
s.conf.EmailFrom,
request.Email,
subject,
emsg.Bytes())
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not send login mail")
return err
}
return nil
return s.conf.SendEmail(
s.conf.loginEmailTemplates,
s.conf.LoginEmailSubject,
map[string]string{"TokenURL": baseURL + token},
[]string{request.Email},
request.Language,
)
}
func (s *Server) handleEmailLogin(w http.ResponseWriter, r *http.Request) {
......@@ -474,33 +445,6 @@ func (s *Server) handleGetLogs(w http.ResponseWriter, r *http.Request) {
server.WriteJson(w, entries)
}
func (s *Server) sendEmailRemovalEmail(info UserInformation, email string) error {
template := s.conf.TranslateTemplate(s.conf.deleteEmailTemplates, info.language)
subject := s.conf.TranslateString(s.conf.DeleteEmailSubject, info.language)
var emsg bytes.Buffer
err := template.Execute(&emsg, map[string]string{"Username": info.Username})
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not generate email removal mail from template")
return err
}
err = server.SendHTMLMail(
s.conf.EmailServer,
s.conf.EmailAuth,
s.conf.EmailFrom,
email,
subject,
emsg.Bytes())
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not send email removal mail")
return err
}
return nil
}
func (s *Server) processRemoveEmail(session *Sessiondata, email string) error {
info, err := s.db.UserInformation(*session.userID)
if err != nil {
......@@ -519,7 +463,13 @@ func (s *Server) processRemoveEmail(session *Sessiondata, email string) error {
}
if s.conf.EmailServer != "" {
err = s.sendEmailRemovalEmail(info, email)
err = s.conf.SendEmail(
s.conf.deleteEmailTemplates,
s.conf.DeleteEmailSubject,
map[string]string{"Username": info.Username},
[]string{email},
info.language,
)
if err != nil {
// already logged
return err
......
package taskserver
import (
"bytes"
"database/sql"
"time"
_ "github.com/jackc/pgx/stdlib"
"github.com/privacybydesign/irmago/internal/common"
"github.com/privacybydesign/irmago/server"
)
type TaskHandler struct {
......@@ -79,26 +77,15 @@ func (t *TaskHandler) sendExpiryEmails(id int64, username, lang string) error {
return err
}
// Prepare email body
template := t.conf.TranslateTemplate(t.conf.deleteExpiredAccountTemplate, lang)
subject := t.conf.TranslateString(t.conf.DeleteExpiredAccountSubject, lang)
var emsg bytes.Buffer
err = template.Execute(&emsg, map[string]string{"Username": username, "Email": email})
if err != nil {
t.conf.Logger.WithField("error", err).Error("Could not render email")
return err
}
// And send
err = server.SendHTMLMail(
t.conf.EmailServer,
t.conf.EmailAuth,
t.conf.EmailFrom,
email,
subject,
emsg.Bytes())
err = t.conf.SendEmail(
t.conf.deleteExpiredAccountTemplate,
t.conf.DeleteExpiredAccountSubject,
map[string]string{"Username": username, "Email": email},
[]string{email},
lang,
)
if err != nil {
t.conf.Logger.WithField("error", err).Error("Could not send email")
return err
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment