feat: support admin modify smtp config

This commit is contained in:
LinkinStar 2022-10-20 16:38:56 +08:00
parent c8da6a3087
commit 41e1175620
11 changed files with 158 additions and 47 deletions

View File

@ -163,7 +163,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
reasonController := controller.NewReasonController(reasonService) reasonController := controller.NewReasonController(reasonService)
themeController := controller_backyard.NewThemeController() themeController := controller_backyard.NewThemeController()
siteInfoRepo := repo.NewSiteInfo(dataData) siteInfoRepo := repo.NewSiteInfo(dataData)
siteInfoService := service.NewSiteInfoService(siteInfoRepo) siteInfoService := service.NewSiteInfoService(siteInfoRepo, emailService)
siteInfoController := controller_backyard.NewSiteInfoController(siteInfoService) siteInfoController := controller_backyard.NewSiteInfoController(siteInfoService)
siteinfoController := controller.NewSiteinfoController(siteInfoService) siteinfoController := controller.NewSiteinfoController(siteInfoService)
notificationRepo := notification.NewNotificationRepo(dataData) notificationRepo := notification.NewNotificationRepo(dataData)

6
go.mod
View File

@ -4,8 +4,8 @@ go 1.18
require ( require (
github.com/Chain-Zhang/pinyin v0.1.3 github.com/Chain-Zhang/pinyin v0.1.3
github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267
github.com/bwmarrin/snowflake v0.3.0 github.com/bwmarrin/snowflake v0.3.0
github.com/gin-contrib/gzip v0.0.6
github.com/gin-gonic/gin v1.8.1 github.com/gin-gonic/gin v1.8.1
github.com/go-playground/locales v0.14.0 github.com/go-playground/locales v0.14.0
github.com/go-playground/universal-translator v0.18.0 github.com/go-playground/universal-translator v0.18.0
@ -16,7 +16,6 @@ require (
github.com/google/wire v0.5.0 github.com/google/wire v0.5.0
github.com/jinzhu/copier v0.3.5 github.com/jinzhu/copier v0.3.5
github.com/jinzhu/now v1.1.5 github.com/jinzhu/now v1.1.5
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
github.com/lib/pq v1.10.2 github.com/lib/pq v1.10.2
github.com/mattn/go-sqlite3 v2.0.3+incompatible github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/mojocn/base64Captcha v1.3.5 github.com/mojocn/base64Captcha v1.3.5
@ -33,6 +32,7 @@ require (
github.com/swaggo/swag v1.8.6 github.com/swaggo/swag v1.8.6
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
golang.org/x/net v0.0.0-20220927171203-f486391704dc golang.org/x/net v0.0.0-20220927171203-f486391704dc
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
xorm.io/builder v0.3.12 xorm.io/builder v0.3.12
xorm.io/core v0.7.3 xorm.io/core v0.7.3
xorm.io/xorm v1.3.2 xorm.io/xorm v1.3.2
@ -40,7 +40,6 @@ require (
require ( require (
github.com/KyleBanks/depth v1.2.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect
github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267 // indirect
github.com/andybalholm/brotli v1.0.1 // indirect github.com/andybalholm/brotli v1.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect
@ -86,6 +85,7 @@ require (
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.1.12 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

6
go.sum
View File

@ -351,8 +351,6 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@ -1016,6 +1014,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -1026,6 +1026,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View File

@ -15,6 +15,7 @@ import (
"github.com/segmentfault/answer/internal/base/translator" "github.com/segmentfault/answer/internal/base/translator"
myErrors "github.com/segmentfault/pacman/errors" myErrors "github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/i18n" "github.com/segmentfault/pacman/i18n"
"github.com/segmentfault/pacman/log"
) )
// MyValidator my validator // MyValidator my validator
@ -92,6 +93,7 @@ func (m *MyValidator) Check(value interface{}) (errField *ErrorField, err error)
if err != nil { if err != nil {
var valErrors validator.ValidationErrors var valErrors validator.ValidationErrors
if !errors.As(err, &valErrors) { if !errors.As(err, &valErrors) {
log.Error(err)
return nil, errors.New("validate check exception") return nil, errors.New("validate check exception")
} }

View File

@ -80,3 +80,34 @@ func (sc *SiteInfoController) UpdateInterface(ctx *gin.Context) {
err := sc.siteInfoService.SaveSiteInterface(ctx, req) err := sc.siteInfoService.SaveSiteInterface(ctx, req)
handler.HandleResponse(ctx, err, nil) handler.HandleResponse(ctx, err, nil)
} }
// GetSMTPConfig get smtp config
// @Summary GetSMTPConfig get smtp config
// @Description GetSMTPConfig get smtp config
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceResp}
// @Router /answer/admin/api/setting/smtp [get]
func (sc *SiteInfoController) GetSMTPConfig(ctx *gin.Context) {
resp, err := sc.siteInfoService.GetSMTPConfig(ctx)
handler.HandleResponse(ctx, err, resp)
}
// UpdateSMTPConfig update smtp config
// @Summary update smtp config
// @Description update smtp config
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
// @Param data body schema.SiteInterfaceReq true "general"
// @Success 200 {object} handler.RespBody{}
// @Router /answer/admin/api/setting/smtp [put]
func (sc *SiteInfoController) UpdateSMTPConfig(ctx *gin.Context) {
req := &schema.UpdateSMTPConfigReq{}
if handler.BindAndCheck(ctx, req) {
return
}
err := sc.siteInfoService.UpdateSMTPConfig(ctx, req)
handler.HandleResponse(ctx, err, nil)
}

View File

@ -120,3 +120,14 @@ func (cr *configRepo) GetConfigById(id int, value any) (err error) {
value = json.Unmarshal([]byte(conf.(string)), value) value = json.Unmarshal([]byte(conf.(string)), value)
return return
} }
func (cr *configRepo) SetConfig(key, value string) (err error) {
id := Key2IDMapping[key]
_, err = cr.data.DB.ID(id).Update(&entity.Config{Value: value})
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} else {
Key2ValueMapping[key] = value
}
return
}

View File

@ -223,4 +223,6 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
r.GET("/siteinfo/interface", a.siteInfoController.GetInterface) r.GET("/siteinfo/interface", a.siteInfoController.GetInterface)
r.PUT("/siteinfo/general", a.siteInfoController.UpdateGeneral) r.PUT("/siteinfo/general", a.siteInfoController.UpdateGeneral)
r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface) r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface)
r.GET("/setting/smtp", a.siteInfoController.GetSMTPConfig)
r.PUT("/setting/smtp", a.siteInfoController.UpdateSMTPConfig)
} }

View File

@ -24,3 +24,25 @@ type SiteInfoResp struct {
General *SiteGeneralResp `json:"general"` General *SiteGeneralResp `json:"general"`
Face *SiteInterfaceResp `json:"interface"` Face *SiteInterfaceResp `json:"interface"`
} }
// UpdateSMTPConfigReq get smtp config request
type UpdateSMTPConfigReq struct {
FromEmailAddress string `validate:"omitempty,gt=0,lte=256" json:"from_email_address"`
FromName string `validate:"omitempty,gt=0,lte=256" json:"from_name"`
SMTPHost string `validate:"omitempty,gt=0,lte=256" json:"smtp_host"`
SMTPPort int `validate:"omitempty,min=1,max=65535" json:"smtp_port"`
Encryption string `validate:"omitempty,oneof=SSL" json:"encryption"` // "" SSL TLS
SMTPUsername string `validate:"omitempty,gt=0,lte=256" json:"smtp_username"`
SMTPPassword string `validate:"omitempty,gt=0,lte=256" json:"smtp_password"`
}
// GetSMTPConfigResp get smtp config response
type GetSMTPConfigResp struct {
FromEmailAddress string `json:"from_email_address"`
FromName string `json:"from_name"`
SMTPHost string `json:"smtp_host"`
SMTPPort int `json:"smtp_port"`
Encryption string `json:"encryption"` // "" SSL TLS
SMTPUsername string `json:"smtp_username"`
SMTPPassword string `json:"smtp_password"`
}

View File

@ -8,6 +8,7 @@ type ConfigRepo interface {
GetArrayString(key string) ([]string, error) GetArrayString(key string) ([]string, error)
GetConfigType(key string) (int, error) GetConfigType(key string) (int, error)
GetConfigById(id int, value any) (err error) GetConfigById(id int, value any) (err error)
SetConfig(key, value string) (err error)
} }
// ConfigService user service // ConfigService user service

View File

@ -3,14 +3,14 @@ package export
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt"
"html/template" "html/template"
"net/smtp"
"github.com/jordan-wright/email" "github.com/segmentfault/answer/internal/base/reason"
"github.com/segmentfault/answer/internal/service/config" "github.com/segmentfault/answer/internal/service/config"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log" "github.com/segmentfault/pacman/log"
"golang.org/x/net/context" "golang.org/x/net/context"
"gopkg.in/gomail.v2"
) )
// EmailService kit service // EmailService kit service
@ -35,18 +35,24 @@ func NewEmailService(configRepo config.ConfigRepo, emailRepo EmailRepo) *EmailSe
// EmailConfig email config // EmailConfig email config
type EmailConfig struct { type EmailConfig struct {
EmailWebName string `json:"email_web_name"` FromEmailAddress string `json:"from_email_address"`
EmailFrom string `json:"email_from"` FromName string `json:"from_name"`
EmailFromPass string `json:"email_from_pass"` SMTPHost string `json:"smtp_host"`
EmailFromHostname string `json:"email_from_hostname"` SMTPPort int `json:"smtp_port"`
EmailFromSMTP string `json:"email_from_smtp"` Encryption string `json:"encryption"` // "" SSL
EmailFromName string `json:"email_from_name"` SMTPUsername string `json:"smtp_username"`
EmailRegisterTitle string `json:"email_register_title"` SMTPPassword string `json:"smtp_password"`
EmailRegisterBody string `json:"email_register_body"`
EmailPassResetTitle string `json:"email_pass_reset_title"` RegisterTitle string `json:"register_title"`
EmailPassResetBody string `json:"email_pass_reset_body"` RegisterBody string `json:"register_body"`
EmailChangeTitle string `json:"email_change_title"` PassResetTitle string `json:"pass_reset_title"`
EmailChangeBody string `json:"email_change_body"` PassResetBody string `json:"pass_reset_body"`
ChangeTitle string `json:"change_title"`
ChangeBody string `json:"change_body"`
}
func (e *EmailConfig) IsSSL() bool {
return e.Encryption == "SSL"
} }
type RegisterTemplateData struct { type RegisterTemplateData struct {
@ -65,25 +71,28 @@ type ChangeEmailTemplateData struct {
} }
// Send email send // Send email send
func (es *EmailService) Send(ctx context.Context, emailAddr, title, body, code, content string) { func (es *EmailService) Send(ctx context.Context, toEmailAddr, subject, body, code, codeContent string) {
emailClient := email.NewEmail() ec, err := es.GetEmailConfig()
ec, err := es.getEmailConfig()
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return return
} }
emailClient.From = fmt.Sprintf("%s <%s>", ec.EmailFromName, ec.EmailFrom) m := gomail.NewMessage()
emailClient.To = []string{emailAddr} m.SetHeader("From", ec.FromEmailAddress)
emailClient.Subject = title m.SetHeader("To", toEmailAddr)
emailClient.HTML = []byte(body) m.SetHeader("Subject", subject)
err = emailClient.Send(ec.EmailFromSMTP, smtp.PlainAuth("", ec.EmailFrom, ec.EmailFromPass, ec.EmailFromHostname)) m.SetBody("text/html", body)
if err != nil {
d := gomail.NewDialer(ec.SMTPHost, ec.SMTPPort, ec.SMTPUsername, ec.SMTPPassword)
if ec.IsSSL() {
d.SSL = true
}
if err := d.DialAndSend(m); err != nil {
log.Error(err) log.Error(err)
} }
err = es.emailRepo.SetCode(ctx, code, content) err = es.emailRepo.SetCode(ctx, code, codeContent)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
@ -100,13 +109,15 @@ func (es *EmailService) VerifyUrlExpired(ctx context.Context, code string) (cont
} }
func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string, err error) { func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string, err error) {
ec, err := es.getEmailConfig() ec, err := es.GetEmailConfig()
if err != nil { if err != nil {
return return
} }
templateData := RegisterTemplateData{ec.EmailWebName, registerUrl} templateData := RegisterTemplateData{
tmpl, err := template.New("register_title").Parse(ec.EmailRegisterTitle) SiteName: ec.FromName, RegisterUrl: registerUrl,
}
tmpl, err := template.New("register_title").Parse(ec.RegisterTitle)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
@ -117,7 +128,7 @@ func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string
return "", "", err return "", "", err
} }
tmpl, err = template.New("register_body").Parse(ec.EmailRegisterBody) tmpl, err = template.New("register_body").Parse(ec.RegisterBody)
err = tmpl.Execute(bodyBuf, templateData) err = tmpl.Execute(bodyBuf, templateData)
if err != nil { if err != nil {
return "", "", err return "", "", err
@ -127,13 +138,13 @@ func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string
} }
func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body string, err error) { func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body string, err error) {
ec, err := es.getEmailConfig() ec, err := es.GetEmailConfig()
if err != nil { if err != nil {
return return
} }
templateData := PassResetTemplateData{ec.EmailWebName, passResetUrl} templateData := PassResetTemplateData{SiteName: ec.FromName, PassResetUrl: passResetUrl}
tmpl, err := template.New("pass_reset_title").Parse(ec.EmailPassResetTitle) tmpl, err := template.New("pass_reset_title").Parse(ec.PassResetTitle)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
@ -144,7 +155,7 @@ func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body stri
return "", "", err return "", "", err
} }
tmpl, err = template.New("pass_reset_body").Parse(ec.EmailPassResetBody) tmpl, err = template.New("pass_reset_body").Parse(ec.PassResetBody)
err = tmpl.Execute(bodyBuf, templateData) err = tmpl.Execute(bodyBuf, templateData)
if err != nil { if err != nil {
return "", "", err return "", "", err
@ -153,16 +164,16 @@ func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body stri
} }
func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body string, err error) { func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body string, err error) {
ec, err := es.getEmailConfig() ec, err := es.GetEmailConfig()
if err != nil { if err != nil {
return return
} }
templateData := ChangeEmailTemplateData{ templateData := ChangeEmailTemplateData{
SiteName: ec.EmailWebName, SiteName: ec.FromName,
ChangeEmailUrl: changeEmailUrl, ChangeEmailUrl: changeEmailUrl,
} }
tmpl, err := template.New("email_change_title").Parse(ec.EmailChangeTitle) tmpl, err := template.New("email_change_title").Parse(ec.ChangeTitle)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
@ -173,7 +184,7 @@ func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body
return "", "", err return "", "", err
} }
tmpl, err = template.New("email_change_body").Parse(ec.EmailChangeBody) tmpl, err = template.New("email_change_body").Parse(ec.ChangeBody)
err = tmpl.Execute(bodyBuf, templateData) err = tmpl.Execute(bodyBuf, templateData)
if err != nil { if err != nil {
return "", "", err return "", "", err
@ -181,7 +192,7 @@ func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body
return titleBuf.String(), bodyBuf.String(), nil return titleBuf.String(), bodyBuf.String(), nil
} }
func (es *EmailService) getEmailConfig() (ec *EmailConfig, err error) { func (es *EmailService) GetEmailConfig() (ec *EmailConfig, err error) {
emailConf, err := es.configRepo.GetString("email.config") emailConf, err := es.configRepo.GetString("email.config")
if err != nil { if err != nil {
return nil, err return nil, err
@ -189,7 +200,13 @@ func (es *EmailService) getEmailConfig() (ec *EmailConfig, err error) {
ec = &EmailConfig{} ec = &EmailConfig{}
err = json.Unmarshal([]byte(emailConf), ec) err = json.Unmarshal([]byte(emailConf), ec)
if err != nil { if err != nil {
return nil, err return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
return ec, nil return ec, nil
} }
// SetEmailConfig set email config
func (es *EmailService) SetEmailConfig(ec *EmailConfig) (err error) {
data, _ := json.Marshal(ec)
return es.configRepo.SetConfig("email.config", string(data))
}

View File

@ -4,20 +4,24 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/jinzhu/copier"
"github.com/segmentfault/answer/internal/base/reason" "github.com/segmentfault/answer/internal/base/reason"
"github.com/segmentfault/answer/internal/entity" "github.com/segmentfault/answer/internal/entity"
"github.com/segmentfault/answer/internal/schema" "github.com/segmentfault/answer/internal/schema"
"github.com/segmentfault/answer/internal/service/export"
"github.com/segmentfault/answer/internal/service/siteinfo_common" "github.com/segmentfault/answer/internal/service/siteinfo_common"
"github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/errors"
) )
type SiteInfoService struct { type SiteInfoService struct {
siteInfoRepo siteinfo_common.SiteInfoRepo siteInfoRepo siteinfo_common.SiteInfoRepo
emailService *export.EmailService
} }
func NewSiteInfoService(siteInfoRepo siteinfo_common.SiteInfoRepo) *SiteInfoService { func NewSiteInfoService(siteInfoRepo siteinfo_common.SiteInfoRepo, emailService *export.EmailService) *SiteInfoService {
return &SiteInfoService{ return &SiteInfoService{
siteInfoRepo: siteInfoRepo, siteInfoRepo: siteInfoRepo,
emailService: emailService,
} }
} }
@ -113,3 +117,22 @@ func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.Site
err = s.siteInfoRepo.SaveByType(ctx, siteType, &data) err = s.siteInfoRepo.SaveByType(ctx, siteType, &data)
return return
} }
// GetSMTPConfig get smtp config
func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (
resp *schema.GetSMTPConfigResp, err error) {
emailConfig, err := s.emailService.GetEmailConfig()
if err != nil {
return nil, err
}
resp = &schema.GetSMTPConfigResp{}
_ = copier.Copy(resp, emailConfig)
return resp, nil
}
// UpdateSMTPConfig get smtp config
func (s *SiteInfoService) UpdateSMTPConfig(ctx context.Context, req *schema.UpdateSMTPConfigReq) (err error) {
ec := &export.EmailConfig{}
_ = copier.Copy(ec, req)
return s.emailService.SetEmailConfig(ec)
}