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 imap_filter2021import (22 "github.com/emersion/go-message/textproto"23 "github.com/foxcpp/maddy/framework/buffer"24 "github.com/foxcpp/maddy/framework/config"25 modconfig "github.com/foxcpp/maddy/framework/config/module"26 "github.com/foxcpp/maddy/framework/log"27 "github.com/foxcpp/maddy/framework/module"28)2930// Group wraps multiple modifiers and runs them serially.31//32// It is also registered as a module under 'modifiers' name and acts as a33// module group.34type Group struct {35 instName string36 Filters []module.IMAPFilter37 log log.Logger38}3940func NewGroup(_, instName string, _, _ []string) (module.Module, error) {41 return &Group{42 instName: instName,43 log: log.Logger{Name: "imap_filters", Debug: log.DefaultLogger.Debug},44 }, nil45}4647func (g *Group) IMAPFilter(accountName string, rcptTo string, meta *module.MsgMetadata, hdr textproto.Header, body buffer.Buffer) (folder string, flags []string, err error) {48 if g == nil {49 return "", nil, nil50 }51 var (52 finalFolder string53 finalFlags = make([]string, 0, len(g.Filters))54 )55 for _, f := range g.Filters {56 folder, flags, err := f.IMAPFilter(accountName, rcptTo, meta, hdr, body)57 if err != nil {58 g.log.Error("IMAP filter failed", err)59 continue60 }61 if folder != "" && finalFolder == "" {62 finalFolder = folder63 }64 finalFlags = append(finalFlags, flags...)65 }66 return finalFolder, finalFlags, nil67}6869func (g *Group) Init(cfg *config.Map) error {70 for _, node := range cfg.Block.Children {71 mod, err := modconfig.IMAPFilter(cfg.Globals, append([]string{node.Name}, node.Args...), node)72 if err != nil {73 return err74 }7576 g.Filters = append(g.Filters, mod)77 }7879 return nil80}8182func (g *Group) Name() string {83 return "modifiers"84}8586func (g *Group) InstanceName() string {87 return g.instName88}8990func init() {91 module.Register("imap_filters", NewGroup)92}