This is the main dovel repository, it has the Go code to run dovel SMTP server.
Author: b (git@mail.blmayer.dev)
Date: Fri Jun 30 20:50:07 2023 -0300
Parent: d301a8d
Improved handlers
commit daa51d72677f74977289e7718976094d61417209 Author: b <git@mail.blmayer.dev> Date: Fri Jun 30 20:50:07 2023 -0300 Improved handlers diff --git a/cmd/dovel/backend.go b/cmd/dovel/backend.go index cd42039..fdb0ea0 100644 --- a/cmd/dovel/backend.go +++ b/cmd/dovel/backend.go @@ -4,6 +4,7 @@ import ( "crypto" "fmt" "io" + "net/mail" "strings" "blmayer.dev/x/dovel/interfaces" @@ -13,59 +14,73 @@ import ( // A Session is returned after EHLO. type Session struct { - User string + user string handlers map[string]interfaces.Mailer + from string + to string } func (s Session) AuthPlain(username, password string) error { println("connection sent", username, password) + // call vault return nil } func (s Session) Mail(from string, opts *smtp.MailOptions) error { println("Mail from:", from) + s.from = from return nil } func (s Session) Rcpt(to string) error { println("Rcpt to:", to) + s.to = to return nil } func (s Session) Data(r io.Reader) error { - content, err := io.ReadAll(r) + email, err := mail.ReadMessage(r) if err != nil { - println("read content", err.Error()) + println("parse email", err.Error()) return err } - email, err := parsemail.Parse(strings.NewReader(string(content))) + from, err := mail.ParseAddress(s.from) if err != nil { - println("parse email", err.Error()) + println("parse address", err.Error()) + return err + } + fromDomain := strings.Split(from, "@")[1] + tos, err := mail.ParseAddressList(s.to) + if err != nil { + println("parse addresslist", err.Error()) return err } - // get user from to field - mail := interfaces.ToEmail(email) - mail.Raw = content - for _, to := range mail.To { - userDomain := strings.Split(to, "@") - handler, ok := s.handlers[userDomain[1]] - if !ok { - println("no handler for domain", userDomain[1]) - return fmt.Errorf("no handler for domain %s", userDomain) + for _, to := range tos { + localdom := strings.Split(to.Address, "@") + if h, ok := s.handlers[localdom[1]]; ok { + err = h.Save(r) + } else { + if user == "" { + return fmt.Errorf("needs auth") + } + h, ok = s.handlers[fromDomain] + if !ok { + return fmt.Errorf("from is wrong") + } + err = h.Send(r) } - mail.To = []string{to} - if err := handler.Save(mail); err != nil { + if err != nil { println("handler error", err.Error()) - return fmt.Errorf("handler error %s", err.Error()) + return } } return nil } -func (s Session) Reset() {} +func (s Session) Reset() { } func (s Session) Logout() error { println("logged out")