1/*2Maddy Mail Server - Composable all-in-one email server.3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors45This program is free software: you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation, either version 3 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program. If not, see <https://www.gnu.org/licenses/>.17*/1819package testutils2021import (22 "context"2324 "github.com/emersion/go-message/textproto"25 "github.com/foxcpp/maddy/framework/buffer"26 "github.com/foxcpp/maddy/framework/config"27 "github.com/foxcpp/maddy/framework/module"28)2930type Modifier struct {31 InstName string3233 InitErr error34 MailFromErr error35 RcptToErr error36 BodyErr error3738 MailFrom map[string]string39 RcptTo map[string][]string40 AddHdr textproto.Header4142 UnclosedStates int43}4445func (m Modifier) Init(*config.Map) error {46 return nil47}4849func (m Modifier) Name() string {50 return "test_modifier"51}5253func (m Modifier) InstanceName() string {54 return m.InstName55}5657type modifierState struct {58 m *Modifier59}6061func (m Modifier) ModStateForMsg(ctx context.Context, msgMeta *module.MsgMetadata) (module.ModifierState, error) {62 if m.InitErr != nil {63 return nil, m.InitErr64 }6566 m.UnclosedStates++67 return modifierState{&m}, nil68}6970func (ms modifierState) RewriteSender(ctx context.Context, mailFrom string) (string, error) {71 if ms.m.MailFromErr != nil {72 return "", ms.m.MailFromErr73 }74 if ms.m.MailFrom == nil {75 return mailFrom, nil76 }7778 newMailFrom, ok := ms.m.MailFrom[mailFrom]79 if ok {80 return newMailFrom, nil81 }82 return mailFrom, nil83}8485func (ms modifierState) RewriteRcpt(ctx context.Context, rcptTo string) ([]string, error) {86 if ms.m.RcptToErr != nil {87 return []string{""}, ms.m.RcptToErr88 }8990 if ms.m.RcptTo == nil {91 return []string{rcptTo}, nil92 }9394 newRcptTo, ok := ms.m.RcptTo[rcptTo]95 if ok {96 return newRcptTo, nil97 }98 return []string{rcptTo}, nil99}100101func (ms modifierState) RewriteBody(ctx context.Context, h *textproto.Header, body buffer.Buffer) error {102 if ms.m.BodyErr != nil {103 return ms.m.BodyErr104 }105106 for field := ms.m.AddHdr.Fields(); field.Next(); {107 h.Add(field.Key(), field.Value())108 }109 return nil110}111112func (ms modifierState) Close() error {113 ms.m.UnclosedStates--114 return nil115}116117func init() {118 module.Register("test_modifier", func(_, _ string, _, _ []string) (module.Module, error) {119 return &Modifier{}, nil120 })121 module.RegisterInstance(&Modifier{}, nil)122}