mirror of
https://github.com/go-gitea/gitea.git
synced 2025-12-06 13:20:14 +01:00
Backport #36055 by @lunny Replace #36032 Fix #36030 This PR use `net/smtp` instead of gomail's smtp. Now github.com/wneessen/go-mail will be used only for generating email message body. Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
52902d4ece
commit
0ab447005d
@ -33,7 +33,13 @@ func (s *SendmailSender) Send(from string, to []string, msg io.WriterTo) error {
|
|||||||
|
|
||||||
args := []string{"-f", envelopeFrom, "-i"}
|
args := []string{"-f", envelopeFrom, "-i"}
|
||||||
args = append(args, setting.MailService.SendmailArgs...)
|
args = append(args, setting.MailService.SendmailArgs...)
|
||||||
args = append(args, to...)
|
for _, recipient := range to {
|
||||||
|
smtpTo, err := sanitizeEmailAddress(recipient)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid recipient address %q: %w", recipient, err)
|
||||||
|
}
|
||||||
|
args = append(args, smtpTo)
|
||||||
|
}
|
||||||
log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)
|
log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)
|
||||||
|
|
||||||
desc := fmt.Sprintf("SendMail: %s %v", setting.MailService.SendmailPath, args)
|
desc := fmt.Sprintf("SendMail: %s %v", setting.MailService.SendmailPath, args)
|
||||||
|
|||||||
@ -9,13 +9,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/mail"
|
||||||
|
"net/smtp"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/wneessen/go-mail/smtp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SMTPSender Sender SMTP mail sender
|
// SMTPSender Sender SMTP mail sender
|
||||||
@ -108,7 +108,7 @@ func (s *SMTPSender) Send(from string, to []string, msg io.WriterTo) error {
|
|||||||
if strings.Contains(options, "CRAM-MD5") {
|
if strings.Contains(options, "CRAM-MD5") {
|
||||||
auth = smtp.CRAMMD5Auth(opts.User, opts.Passwd)
|
auth = smtp.CRAMMD5Auth(opts.User, opts.Passwd)
|
||||||
} else if strings.Contains(options, "PLAIN") {
|
} else if strings.Contains(options, "PLAIN") {
|
||||||
auth = smtp.PlainAuth("", opts.User, opts.Passwd, host, false)
|
auth = smtp.PlainAuth("", opts.User, opts.Passwd, host)
|
||||||
} else if strings.Contains(options, "LOGIN") {
|
} else if strings.Contains(options, "LOGIN") {
|
||||||
// Patch for AUTH LOGIN
|
// Patch for AUTH LOGIN
|
||||||
auth = LoginAuth(opts.User, opts.Passwd)
|
auth = LoginAuth(opts.User, opts.Passwd)
|
||||||
@ -123,18 +123,24 @@ func (s *SMTPSender) Send(from string, to []string, msg io.WriterTo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.OverrideEnvelopeFrom {
|
fromAddr := from
|
||||||
if err = client.Mail(opts.EnvelopeFrom); err != nil {
|
if opts.OverrideEnvelopeFrom && opts.EnvelopeFrom != "" {
|
||||||
return fmt.Errorf("failed to issue MAIL command: %w", err)
|
fromAddr = opts.EnvelopeFrom
|
||||||
}
|
}
|
||||||
} else {
|
smtpFrom, err := sanitizeEmailAddress(fromAddr)
|
||||||
if err = client.Mail(fmt.Sprintf("<%s>", from)); err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to issue MAIL command: %w", err)
|
return fmt.Errorf("invalid envelope from address: %w", err)
|
||||||
}
|
}
|
||||||
|
if err = client.Mail(smtpFrom); err != nil {
|
||||||
|
return fmt.Errorf("failed to issue MAIL command: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rec := range to {
|
for _, rec := range to {
|
||||||
if err = client.Rcpt(rec); err != nil {
|
smtpTo, err := sanitizeEmailAddress(rec)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid recipient address %q: %w", rec, err)
|
||||||
|
}
|
||||||
|
if err = client.Rcpt(smtpTo); err != nil {
|
||||||
return fmt.Errorf("failed to issue RCPT command: %w", err)
|
return fmt.Errorf("failed to issue RCPT command: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,3 +161,11 @@ func (s *SMTPSender) Send(from string, to []string, msg io.WriterTo) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitizeEmailAddress(raw string) (string, error) {
|
||||||
|
addr, err := mail.ParseAddress(strings.TrimSpace(strings.Trim(raw, "<>")))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return addr.Address, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -6,9 +6,9 @@ package sender
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/smtp"
|
||||||
|
|
||||||
"github.com/Azure/go-ntlmssp"
|
"github.com/Azure/go-ntlmssp"
|
||||||
"github.com/wneessen/go-mail/smtp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type loginAuth struct {
|
type loginAuth struct {
|
||||||
|
|||||||
30
services/mailer/sender/smtp_test.go
Normal file
30
services/mailer/sender/smtp_test.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package sender
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSanitizeEmailAddress(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
hasError bool
|
||||||
|
}{
|
||||||
|
{"abc@gitea.com", "abc@gitea.com", false},
|
||||||
|
{"<abc@gitea.com>", "abc@gitea.com", false},
|
||||||
|
{"ssss.com", "", true},
|
||||||
|
{"<invalid-email>", "", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
result, err := sanitizeEmailAddress(tt.input)
|
||||||
|
if (err != nil) != tt.hasError {
|
||||||
|
t.Errorf("sanitizeEmailAddress(%q) unexpected error status: got %v, want error: %v", tt.input, err != nil, tt.hasError)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if result != tt.expected {
|
||||||
|
t.Errorf("sanitizeEmailAddress(%q) = %q; want %q", tt.input, result, tt.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user