Add configurable external rules pipeline for ingress #19
@@ -0,0 +1,26 @@
|
|||||||
|
package rules
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// BlocklistRule rejects emails from configured senders.
|
||||||
|
type BlocklistRule struct {
|
||||||
|
emails map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBlocklistRule creates a blocklist rule from a list of email addresses.
|
||||||
|
func NewBlocklistRule(emails []string) *BlocklistRule {
|
||||||
|
m := make(map[string]bool, len(emails))
|
||||||
|
for _, e := range emails {
|
||||||
|
m[strings.ToLower(e)] = true
|
||||||
|
}
|
||||||
|
return &BlocklistRule{emails: m}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *BlocklistRule) Name() string { return "blocklist" }
|
||||||
|
|
||||||
|
func (r *BlocklistRule) Evaluate(ctx EmailContext) RuleResult {
|
||||||
|
if r.emails[strings.ToLower(ctx.Sender)] {
|
||||||
|
return Reject("blocked sender")
|
||||||
|
}
|
||||||
|
return Accept()
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package rules
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestBlocklistRule_SenderBlocked_Rejects(t *testing.T) {
|
||||||
|
r := NewBlocklistRule([]string{"spam@test.com"})
|
||||||
|
result := r.Evaluate(EmailContext{Sender: "spam@test.com"})
|
||||||
|
if result.Accepted {
|
||||||
|
t.Fatal("expected reject for blocked sender")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlocklistRule_SenderNotBlocked_Accepts(t *testing.T) {
|
||||||
|
r := NewBlocklistRule([]string{"spam@test.com"})
|
||||||
|
result := r.Evaluate(EmailContext{Sender: "ok@test.com"})
|
||||||
|
if !result.Accepted {
|
||||||
|
t.Fatal("expected accept for non-blocked sender")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlocklistRule_EmptyList_Accepts(t *testing.T) {
|
||||||
|
r := NewBlocklistRule(nil)
|
||||||
|
result := r.Evaluate(EmailContext{Sender: "anyone@test.com"})
|
||||||
|
if !result.Accepted {
|
||||||
|
t.Fatal("empty blocklist should accept all")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlocklistRule_CaseInsensitive(t *testing.T) {
|
||||||
|
r := NewBlocklistRule([]string{"Spam@Test.com"})
|
||||||
|
result := r.Evaluate(EmailContext{Sender: "spam@test.com"})
|
||||||
|
if result.Accepted {
|
||||||
|
t.Fatal("blocklist should be case-insensitive")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user