3
0

Refactored system auth notification

This commit is contained in:
Denis Arh
2020-08-15 19:25:14 +02:00
parent 3c6ffe4cef
commit 0af3f68d16
4 changed files with 50 additions and 42 deletions

View File

@@ -119,13 +119,13 @@ func Auth(app serviceInitializer) *cobra.Command {
var (
ctx = auth.SetSuperUserContext(cli.Context())
err error
ntf = service.DefaultAuthNotification.With(ctx)
ntf = service.DefaultAuthNotification
)
err = ntf.EmailConfirmation("en", args[0], "notification-testing-token")
err = ntf.EmailConfirmation(ctx, "en", args[0], "notification-testing-token")
cli.HandleError(err)
err = ntf.PasswordReset("en", args[0], "notification-testing-token")
err = ntf.PasswordReset(ctx, "en", args[0], "notification-testing-token")
cli.HandleError(err)
},

View File

@@ -855,7 +855,7 @@ func (svc auth) sendEmailAddressConfirmationToken(u *types.User) (err error) {
return
}
if err = svc.notifications.EmailConfirmation(notificationLang, u.Email, token); err != nil {
if err = svc.notifications.EmailConfirmation(svc.ctx, notificationLang, u.Email, token); err != nil {
return
}
@@ -916,7 +916,7 @@ func (svc auth) sendPasswordResetToken(u *types.User) (err error) {
return err
}
return svc.notifications.PasswordReset(notificationLang, u.Email, token)
return svc.notifications.PasswordReset(svc.ctx, notificationLang, u.Email, token)
}
func (svc auth) loadUserFromToken(token, kind string) (u *types.User, err error) {

View File

@@ -17,16 +17,13 @@ import (
type (
authNotification struct {
ctx context.Context
logger *zap.Logger
settings *types.AppSettings
}
AuthNotificationService interface {
With(ctx context.Context) AuthNotificationService
EmailConfirmation(lang string, emailAddress string, url string) error
PasswordReset(lang string, emailAddress string, url string) error
EmailConfirmation(ctx context.Context, lang string, emailAddress string, url string) error
PasswordReset(ctx context.Context, lang string, emailAddress string, url string) error
}
authNotificationPayload struct {
@@ -41,18 +38,10 @@ type (
}
)
func AuthNotification(ctx context.Context) AuthNotificationService {
return (&authNotification{
logger: DefaultLogger.Named("auth-notification"),
settings: CurrentSettings,
}).With(ctx)
}
func (svc authNotification) With(ctx context.Context) AuthNotificationService {
func AuthNotification(s *types.AppSettings) AuthNotificationService {
return &authNotification{
ctx: ctx,
logger: logger.AddRequestID(ctx, svc.logger),
settings: svc.settings,
logger: DefaultLogger.Named("auth-notification"),
settings: s,
}
}
@@ -60,15 +49,15 @@ func (svc authNotification) log(ctx context.Context, fields ...zapcore.Field) *z
return logger.AddRequestID(ctx, svc.logger).With(fields...)
}
func (svc authNotification) EmailConfirmation(lang string, emailAddress string, token string) error {
return svc.send("email-confirmation", lang, authNotificationPayload{
func (svc authNotification) EmailConfirmation(ctx context.Context, lang string, emailAddress string, token string) error {
return svc.send(ctx, "email-confirmation", lang, authNotificationPayload{
EmailAddress: emailAddress,
URL: svc.settings.Auth.Frontend.Url.EmailConfirmation + token,
})
}
func (svc authNotification) PasswordReset(lang string, emailAddress string, token string) error {
return svc.send("password-reset", lang, authNotificationPayload{
func (svc authNotification) PasswordReset(ctx context.Context, lang string, emailAddress string, token string) error {
return svc.send(ctx, "password-reset", lang, authNotificationPayload{
EmailAddress: emailAddress,
URL: svc.settings.Auth.Frontend.Url.PasswordReset + token,
})
@@ -80,8 +69,12 @@ func (svc authNotification) newMail() *gomail.Message {
return m
}
func (svc authNotification) send(name, lang string, payload authNotificationPayload) error {
ntf := svc.newMail()
func (svc authNotification) send(ctx context.Context, name, lang string, payload authNotificationPayload) error {
var (
err error
tmp string
ntf = svc.newMail()
)
payload.Logo = template.URL(svc.settings.General.Mail.Logo)
payload.BaseURL = svc.settings.Auth.Frontend.Url.Base
@@ -89,25 +82,43 @@ func (svc authNotification) send(name, lang string, payload authNotificationPayl
payload.SignatureEmail = svc.settings.Auth.Mail.FromAddress
// @todo translations
payload.EmailHeaderEn = template.HTML(svc.render(svc.settings.General.Mail.Header, payload))
payload.EmailFooterEn = template.HTML(svc.render(svc.settings.General.Mail.Footer, payload))
if tmp, err = svc.render(svc.settings.General.Mail.Header, payload); err != nil {
return fmt.Errorf("failed to render svc.settings.General.Mail.Header: %w", err)
}
payload.EmailHeaderEn = template.HTML(tmp)
if tmp, err = svc.render(svc.settings.General.Mail.Footer, payload); err != nil {
return fmt.Errorf("failed to render svc.settings.General.Mail.Footer: %w", err)
}
payload.EmailFooterEn = template.HTML(tmp)
ntf.SetAddressHeader("To", payload.EmailAddress, "")
// @todo translations
switch name {
case "email-confirmation":
ntf.SetHeader("Subject", svc.render(svc.settings.Auth.Mail.EmailConfirmation.Subject, payload))
ntf.SetBody("text/html", svc.render(svc.settings.Auth.Mail.EmailConfirmation.Body, payload))
if tmp, err = svc.render(svc.settings.Auth.Mail.EmailConfirmation.Subject, payload); err != nil {
return fmt.Errorf("failed to render svc.settings.Auth.Mail.EmailConfirmation.Subject: %w", err)
}
ntf.SetHeader("Subject", tmp)
if tmp, err = svc.render(svc.settings.Auth.Mail.EmailConfirmation.Body, payload); err != nil {
return fmt.Errorf("failed to render svc.settings.Auth.Mail.EmailConfirmation.Body: %w", err)
}
ntf.SetBody("text/html", tmp)
case "password-reset":
ntf.SetHeader("Subject", svc.render(svc.settings.Auth.Mail.PasswordReset.Subject, payload))
ntf.SetBody("text/html", svc.render(svc.settings.Auth.Mail.PasswordReset.Body, payload))
if tmp, err = svc.render(svc.settings.Auth.Mail.PasswordReset.Subject, payload); err != nil {
return fmt.Errorf("failed to render svc.settings.Auth.Mail.PasswordReset.Subject: %w", err)
}
ntf.SetHeader("Subject", tmp)
if tmp, err = svc.render(svc.settings.Auth.Mail.PasswordReset.Body, payload); err != nil {
return fmt.Errorf("failed to render svc.settings.Auth.Mail.PasswordReset.Body: %w", err)
}
ntf.SetBody("text/html", tmp)
default:
return fmt.Errorf("unknown notification email template %q", name)
}
svc.log(svc.ctx).Debug(
svc.log(ctx).Debug(
"sending auth notification",
zap.String("name", name),
zap.String("language", lang),
@@ -117,7 +128,7 @@ func (svc authNotification) send(name, lang string, payload authNotificationPayl
return mail.Send(ntf)
}
func (svc authNotification) render(source string, payload interface{}) (out string) {
func (svc authNotification) render(source string, payload interface{}) (string, error) {
var (
err error
tpl *template.Template
@@ -126,16 +137,13 @@ func (svc authNotification) render(source string, payload interface{}) (out stri
tpl, err = template.New("").Parse(source)
if err != nil {
svc.log(svc.ctx, zap.Error(err)).Error("could not parse template")
return
return "", fmt.Errorf("could not parse template: %w", err)
}
err = tpl.Execute(&buf, payload)
if err != nil {
svc.log(svc.ctx, zap.Error(err)).Error("could not render template")
return
return "", fmt.Errorf("could not render template: %w", err)
}
out = buf.String()
return
return buf.String(), nil
}

View File

@@ -187,7 +187,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s interface{}, c Config) (
hcd.Add(store.Healthcheck(DefaultStore), "Store/System")
DefaultAuthNotification = AuthNotification(ctx)
DefaultAuthNotification = AuthNotification(CurrentSettings)
DefaultAuth = Auth(ctx)
DefaultUser = User(ctx)
DefaultRole = Role(ctx)