124 lines
3.9 KiB
Go
124 lines
3.9 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"git.pcux.cn/xuans/Scert/backend/internal/notification"
|
|
)
|
|
|
|
type notificationTestRequest struct {
|
|
SMTPEnabled bool `json:"smtp_enabled"`
|
|
SMTPHost string `json:"smtp_host"`
|
|
SMTPPort int `json:"smtp_port"`
|
|
SMTPUsername string `json:"smtp_username"`
|
|
SMTPPassword string `json:"smtp_password"`
|
|
SMTPMode string `json:"smtp_mode"`
|
|
SMTPAllowPlaintextAuth bool `json:"smtp_allow_plaintext_auth"`
|
|
Recipient string `json:"recipient"`
|
|
HTTPEnabled bool `json:"http_enabled"`
|
|
HTTPCredentials map[string]string `json:"http_credentials"`
|
|
Provider string `json:"provider"`
|
|
Endpoint string `json:"endpoint"`
|
|
HTTPPath string `json:"http_path"`
|
|
HTTPLoginPath string `json:"http_login_path"`
|
|
HTTPAuthMode string `json:"http_auth_mode"`
|
|
}
|
|
|
|
type memoryCredentialReader struct {
|
|
creds map[string]map[string]string
|
|
}
|
|
|
|
func (m *memoryCredentialReader) Get(ctx context.Context, ref string) (map[string]string, error) {
|
|
if m == nil || m.creds == nil {
|
|
return nil, errors.New("凭据不存在")
|
|
}
|
|
val, ok := m.creds[ref]
|
|
if !ok {
|
|
return nil, errors.New("凭据不存在")
|
|
}
|
|
return val, nil
|
|
}
|
|
|
|
func (s *Server) testNotification(c *gin.Context) {
|
|
_, authenticated := s.currentAuthSession(c)
|
|
if !authenticated {
|
|
s.writeError(c, http.StatusUnauthorized, "请先登录管理后台", nil)
|
|
return
|
|
}
|
|
var req notificationTestRequest
|
|
if err := bindJSON(c, &req, jsonRequestBodyLimit); err != nil {
|
|
s.writeError(c, http.StatusBadRequest, "测试请求参数无效", err)
|
|
return
|
|
}
|
|
|
|
targetRecipient := strings.TrimSpace(req.Recipient)
|
|
if targetRecipient == "" {
|
|
s.writeError(c, http.StatusBadRequest, "请输入测试收件人邮箱", nil)
|
|
return
|
|
}
|
|
|
|
s.configMu.RLock()
|
|
currentCfg := s.config.Notification
|
|
s.configMu.RUnlock()
|
|
|
|
testCfg := currentCfg
|
|
testCfg.SMTPEnabled = req.SMTPEnabled
|
|
if req.SMTPHost != "" {
|
|
testCfg.SMTPHost = strings.TrimSpace(req.SMTPHost)
|
|
}
|
|
if req.SMTPPort > 0 {
|
|
testCfg.SMTPPort = req.SMTPPort
|
|
}
|
|
if req.SMTPUsername != "" {
|
|
testCfg.SMTPUsername = strings.TrimSpace(req.SMTPUsername)
|
|
}
|
|
if req.SMTPMode != "" {
|
|
testCfg.SMTPMode = strings.TrimSpace(req.SMTPMode)
|
|
}
|
|
testCfg.SMTPAllowPlaintextAuth = req.SMTPAllowPlaintextAuth
|
|
|
|
credsMap := make(map[string]map[string]string)
|
|
smtpPassword := strings.TrimSpace(req.SMTPPassword)
|
|
if smtpPassword != "" {
|
|
testRef := "secret://test/smtp"
|
|
testCfg.SMTPCredentialRef = testRef
|
|
credsMap[testRef] = map[string]string{
|
|
"username": testCfg.SMTPUsername,
|
|
"password": smtpPassword,
|
|
}
|
|
} else if testCfg.SMTPCredentialRef != "" {
|
|
if reader, ok := s.secrets.(readinessSecretReader); ok && reader != nil {
|
|
if realCreds, err := reader.Get(c.Request.Context(), testCfg.SMTPCredentialRef); err == nil && realCreds != nil {
|
|
credsMap[testCfg.SMTPCredentialRef] = realCreds
|
|
}
|
|
}
|
|
}
|
|
|
|
if testCfg.SMTPEnabled && credsMap[testCfg.SMTPCredentialRef] == nil && testCfg.UsesSmailSystemAccount() {
|
|
s.writeError(c, http.StatusBadRequest, "尚未配置 SMTP 密码,请先输入密码再进行测试", nil)
|
|
return
|
|
}
|
|
|
|
reader := &memoryCredentialReader{creds: credsMap}
|
|
notifService := notification.New(testCfg, reader)
|
|
|
|
testCtx, cancel := context.WithTimeout(c.Request.Context(), 15*time.Second)
|
|
defer cancel()
|
|
|
|
if err := notifService.SendTestMail(testCtx, targetRecipient); err != nil {
|
|
s.writeError(c, http.StatusUnprocessableEntity, "邮件测试发送失败:"+err.Error(), err)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "测试邮件已发送,请检查收件箱",
|
|
"recipient": targetRecipient,
|
|
})
|
|
}
|