mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 09:37:02 +00:00
policy: Implement store domain policy for #51
- Update docs, change log, status.html
This commit is contained in:
@@ -3,7 +3,6 @@ package config
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
@@ -42,13 +41,14 @@ type Root struct {
|
||||
type SMTP struct {
|
||||
Addr string `required:"true" default:"0.0.0.0:2500" desc:"SMTP server IP4 host:port"`
|
||||
Domain string `required:"true" default:"inbucket" desc:"HELO domain"`
|
||||
DomainNoStore string `desc:"Load testing domain"`
|
||||
MaxRecipients int `required:"true" default:"200" desc:"Maximum RCPT TO per message"`
|
||||
MaxMessageBytes int `required:"true" default:"10240000" desc:"Maximum message size"`
|
||||
StoreMessages bool `required:"true" default:"true" desc:"Store incoming mail?"`
|
||||
DefaultAccept bool `required:"true" default:"true" desc:"Accept all mail by default?"`
|
||||
AcceptDomains []string `desc:"Domains to accept mail for"`
|
||||
RejectDomains []string `desc:"Domains to reject mail for"`
|
||||
DefaultStore bool `required:"true" default:"true" desc:"Store all mail by default?"`
|
||||
StoreDomains []string `desc:"Domains to store mail for"`
|
||||
DiscardDomains []string `desc:"Domains to discard mail for"`
|
||||
Timeout time.Duration `required:"true" default:"300s" desc:"Idle network timeout"`
|
||||
Debug bool `ignored:"true"`
|
||||
}
|
||||
@@ -86,9 +86,10 @@ type Storage struct {
|
||||
func Process() (*Root, error) {
|
||||
c := &Root{}
|
||||
err := envconfig.Process(prefix, c)
|
||||
c.SMTP.DomainNoStore = strings.ToLower(c.SMTP.DomainNoStore)
|
||||
stringutil.SliceToLower(c.SMTP.AcceptDomains)
|
||||
stringutil.SliceToLower(c.SMTP.RejectDomains)
|
||||
stringutil.SliceToLower(c.SMTP.StoreDomains)
|
||||
stringutil.SliceToLower(c.SMTP.DiscardDomains)
|
||||
return c, err
|
||||
}
|
||||
|
||||
|
||||
@@ -50,10 +50,14 @@ func (a *Addressing) ShouldAcceptDomain(domain string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ShouldStoreDomain indicates if Inbucket stores email destined for the specified domain.
|
||||
// ShouldStoreDomain indicates if Inbucket stores mail destined for the specified domain.
|
||||
func (a *Addressing) ShouldStoreDomain(domain string) bool {
|
||||
if a.Config.StoreMessages {
|
||||
return strings.ToLower(domain) != strings.ToLower(a.Config.DomainNoStore)
|
||||
domain = strings.ToLower(domain)
|
||||
if a.Config.DefaultStore && !stringutil.SliceContains(a.Config.DiscardDomains, domain) {
|
||||
return true
|
||||
}
|
||||
if !a.Config.DefaultStore && stringutil.SliceContains(a.Config.StoreDomains, domain) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -65,24 +65,24 @@ func TestShouldStoreDomain(t *testing.T) {
|
||||
// Test with storage enabled.
|
||||
ap := &policy.Addressing{
|
||||
Config: config.SMTP{
|
||||
DomainNoStore: "Foo.Com",
|
||||
StoreMessages: true,
|
||||
DefaultStore: false,
|
||||
StoreDomains: []string{"store.com", "a.store.com"},
|
||||
},
|
||||
}
|
||||
testCases := []struct {
|
||||
domain string
|
||||
want bool
|
||||
}{
|
||||
{domain: "bar.com", want: true},
|
||||
{domain: "foo.com", want: false},
|
||||
{domain: "FOO.com", want: false},
|
||||
{domain: "bar.foo.com", want: true},
|
||||
{domain: "STORE.com", want: true},
|
||||
{domain: "a.store.com", want: true},
|
||||
{domain: "b.store.com", want: false},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.domain, func(t *testing.T) {
|
||||
got := ap.ShouldStoreDomain(tc.domain)
|
||||
if got != tc.want {
|
||||
t.Errorf("Got %v for %q, want: %v", got, tc.domain, tc.want)
|
||||
t.Errorf("Got store %v for %q, want: %v", got, tc.domain, tc.want)
|
||||
}
|
||||
|
||||
})
|
||||
@@ -90,23 +90,24 @@ func TestShouldStoreDomain(t *testing.T) {
|
||||
// Test with storage disabled.
|
||||
ap = &policy.Addressing{
|
||||
Config: config.SMTP{
|
||||
StoreMessages: false,
|
||||
DefaultStore: true,
|
||||
DiscardDomains: []string{"discard.com", "a.discard.com"},
|
||||
},
|
||||
}
|
||||
testCases = []struct {
|
||||
domain string
|
||||
want bool
|
||||
}{
|
||||
{domain: "bar.com", want: false},
|
||||
{domain: "foo.com", want: false},
|
||||
{domain: "FOO.com", want: false},
|
||||
{domain: "bar.foo.com", want: false},
|
||||
{domain: "foo.com", want: true},
|
||||
{domain: "DISCARD.com", want: false},
|
||||
{domain: "a.discard.com", want: false},
|
||||
{domain: "b.discard.com", want: true},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.domain, func(t *testing.T) {
|
||||
got := ap.ShouldStoreDomain(tc.domain)
|
||||
if got != tc.want {
|
||||
t.Errorf("Got %v for %q, want: %v", got, tc.domain, tc.want)
|
||||
t.Errorf("Got store %v for %q, want: %v", got, tc.domain, tc.want)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
@@ -365,10 +365,8 @@ func setupSMTPServer(ds storage.Store) (s *Server, buf *bytes.Buffer, teardown f
|
||||
cfg := config.SMTP{
|
||||
Addr: "127.0.0.1:2500",
|
||||
Domain: "inbucket.local",
|
||||
DomainNoStore: "bitbucket.local",
|
||||
MaxRecipients: 5,
|
||||
MaxMessageBytes: 5000,
|
||||
StoreMessages: true,
|
||||
DefaultAccept: true,
|
||||
RejectDomains: []string{"deny.com"},
|
||||
Timeout: 5,
|
||||
|
||||
@@ -97,11 +97,6 @@ func (s *Server) Start(ctx context.Context) {
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
if !s.config.StoreMessages {
|
||||
slog.Info().Msg("Load test mode active, messages will not be stored")
|
||||
} else if s.config.DomainNoStore != "" {
|
||||
slog.Info().Msgf("Messages sent to domain '%v' will be discarded", s.config.DomainNoStore)
|
||||
}
|
||||
// Listener go routine.
|
||||
go s.serve(ctx)
|
||||
// Wait for shutdown.
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
var TemplateFuncs = template.FuncMap{
|
||||
"friendlyTime": FriendlyTime,
|
||||
"reverse": Reverse,
|
||||
"stringsJoin": strings.Join,
|
||||
"textToHtml": TextToHTML,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user