diff --git a/internal/config/cli.go b/internal/config/cli.go index 2a61bad..17f0ff6 100644 --- a/internal/config/cli.go +++ b/internal/config/cli.go @@ -37,7 +37,6 @@ func declareFlags(o *Config) { flag.DurationVar(&o.Analysis.DNSTimeout, "dns-timeout", o.Analysis.DNSTimeout, "Timeout when performing DNS query") flag.DurationVar(&o.Analysis.HTTPTimeout, "http-timeout", o.Analysis.HTTPTimeout, "Timeout when performing HTTP query") flag.Var(&StringArray{&o.Analysis.RBLs}, "rbl", "Append a RBL (use this option multiple time to append multiple RBLs)") - flag.BoolVar(&o.Analysis.CheckAllIPs, "check-all-ips", o.Analysis.CheckAllIPs, "Check all IPs found in email headers against RBLs (not just the first one)") flag.DurationVar(&o.ReportRetention, "report-retention", o.ReportRetention, "How long to keep reports (e.g., 720h, 30d). 0 = keep forever") flag.UintVar(&o.RateLimit, "rate-limit", o.RateLimit, "API rate limit (requests per second per IP)") flag.Var(&URL{&o.SurveyURL}, "survey-url", "URL for user feedback survey") diff --git a/internal/config/config.go b/internal/config/config.go index be5e63a..6f35ec7 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -61,10 +61,9 @@ type EmailConfig struct { // AnalysisConfig contains timeout and behavior settings for email analysis type AnalysisConfig struct { - DNSTimeout time.Duration - HTTPTimeout time.Duration - RBLs []string - CheckAllIPs bool // Check all IPs found in headers, not just the first one + DNSTimeout time.Duration + HTTPTimeout time.Duration + RBLs []string } // DefaultConfig returns a configuration with sensible defaults @@ -87,7 +86,6 @@ func DefaultConfig() *Config { DNSTimeout: 5 * time.Second, HTTPTimeout: 10 * time.Second, RBLs: []string{}, - CheckAllIPs: false, // By default, only check the first IP }, } } diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 99b7b52..80fa7f2 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -44,7 +44,6 @@ func NewEmailAnalyzer(cfg *config.Config) *EmailAnalyzer { cfg.Analysis.DNSTimeout, cfg.Analysis.HTTPTimeout, cfg.Analysis.RBLs, - cfg.Analysis.CheckAllIPs, ) return &EmailAnalyzer{ diff --git a/pkg/analyzer/content.go b/pkg/analyzer/content.go index 3150d50..613e5d5 100644 --- a/pkg/analyzer/content.go +++ b/pkg/analyzer/content.go @@ -751,7 +751,7 @@ func (c *ContentAnalyzer) CalculateContentScore(results *ContentResults) (int, s brokenLinks++ } } - score += 20 * (len(results.Links) - brokenLinks) / len(results.Links) + score += 20 * brokenLinks / len(results.Links) // Too much links, 10 points penalty if len(results.Links) > 30 { score -= 10 @@ -769,7 +769,7 @@ func (c *ContentAnalyzer) CalculateContentScore(results *ContentResults) (int, s noAltCount++ } } - score += 15 * (len(results.Images) - noAltCount) / len(results.Images) + score += 15 * noAltCount / len(results.Images) } else { // No images is Ok score += 15 diff --git a/pkg/analyzer/rbl.go b/pkg/analyzer/rbl.go index 5e8b503..832c61c 100644 --- a/pkg/analyzer/rbl.go +++ b/pkg/analyzer/rbl.go @@ -34,10 +34,9 @@ import ( // RBLChecker checks IP addresses against DNS-based blacklists type RBLChecker struct { - Timeout time.Duration - RBLs []string - CheckAllIPs bool // Check all IPs found in headers, not just the first one - resolver *net.Resolver + Timeout time.Duration + RBLs []string + resolver *net.Resolver } // DefaultRBLs is a list of commonly used RBL providers @@ -51,7 +50,7 @@ var DefaultRBLs = []string{ } // NewRBLChecker creates a new RBL checker with configurable timeout and RBL list -func NewRBLChecker(timeout time.Duration, rbls []string, checkAllIPs bool) *RBLChecker { +func NewRBLChecker(timeout time.Duration, rbls []string) *RBLChecker { if timeout == 0 { timeout = 5 * time.Second // Default timeout } @@ -59,9 +58,8 @@ func NewRBLChecker(timeout time.Duration, rbls []string, checkAllIPs bool) *RBLC rbls = DefaultRBLs } return &RBLChecker{ - Timeout: timeout, - RBLs: rbls, - CheckAllIPs: checkAllIPs, + Timeout: timeout, + RBLs: rbls, resolver: &net.Resolver{ PreferGo: true, }, @@ -98,11 +96,6 @@ func (r *RBLChecker) CheckEmail(email *EmailMessage) *RBLResults { results.ListedCount++ } } - - // Only check the first IP unless CheckAllIPs is enabled - if !r.CheckAllIPs { - break - } } return results diff --git a/pkg/analyzer/rbl_test.go b/pkg/analyzer/rbl_test.go index a1de270..f18464a 100644 --- a/pkg/analyzer/rbl_test.go +++ b/pkg/analyzer/rbl_test.go @@ -55,7 +55,7 @@ func TestNewRBLChecker(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - checker := NewRBLChecker(tt.timeout, tt.rbls, false) + checker := NewRBLChecker(tt.timeout, tt.rbls) if checker.Timeout != tt.expectedTimeout { t.Errorf("Timeout = %v, want %v", checker.Timeout, tt.expectedTimeout) } @@ -97,7 +97,7 @@ func TestReverseIP(t *testing.T) { }, } - checker := NewRBLChecker(5*time.Second, nil, false) + checker := NewRBLChecker(5*time.Second, nil) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -157,7 +157,7 @@ func TestIsPublicIP(t *testing.T) { }, } - checker := NewRBLChecker(5*time.Second, nil, false) + checker := NewRBLChecker(5*time.Second, nil) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -237,7 +237,7 @@ func TestExtractIPs(t *testing.T) { },*/ } - checker := NewRBLChecker(5*time.Second, nil, false) + checker := NewRBLChecker(5*time.Second, nil) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -322,7 +322,7 @@ func TestGetBlacklistScore(t *testing.T) { }, } - checker := NewRBLChecker(5*time.Second, nil, false) + checker := NewRBLChecker(5*time.Second, nil) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -351,7 +351,7 @@ func TestGetUniqueListedIPs(t *testing.T) { }, } - checker := NewRBLChecker(5*time.Second, nil, false) + checker := NewRBLChecker(5*time.Second, nil) listedIPs := checker.GetUniqueListedIPs(results) expectedIPs := []string{"198.51.100.1", "198.51.100.2"} @@ -376,7 +376,7 @@ func TestGetRBLsForIP(t *testing.T) { }, } - checker := NewRBLChecker(5*time.Second, nil, false) + checker := NewRBLChecker(5*time.Second, nil) tests := []struct { name string diff --git a/pkg/analyzer/report.go b/pkg/analyzer/report.go index a39a98a..bd6b866 100644 --- a/pkg/analyzer/report.go +++ b/pkg/analyzer/report.go @@ -44,13 +44,12 @@ func NewReportGenerator( dnsTimeout time.Duration, httpTimeout time.Duration, rbls []string, - checkAllIPs bool, ) *ReportGenerator { return &ReportGenerator{ authAnalyzer: NewAuthenticationAnalyzer(), spamAnalyzer: NewSpamAssassinAnalyzer(), dnsAnalyzer: NewDNSAnalyzer(dnsTimeout), - rblChecker: NewRBLChecker(dnsTimeout, rbls, checkAllIPs), + rblChecker: NewRBLChecker(dnsTimeout, rbls), contentAnalyzer: NewContentAnalyzer(httpTimeout), headerAnalyzer: NewHeaderAnalyzer(), } diff --git a/pkg/analyzer/report_test.go b/pkg/analyzer/report_test.go index 5a325b1..bf413ce 100644 --- a/pkg/analyzer/report_test.go +++ b/pkg/analyzer/report_test.go @@ -32,7 +32,7 @@ import ( ) func TestNewReportGenerator(t *testing.T) { - gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false) + gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs) if gen == nil { t.Fatal("Expected report generator, got nil") } @@ -55,7 +55,7 @@ func TestNewReportGenerator(t *testing.T) { } func TestAnalyzeEmail(t *testing.T) { - gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false) + gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs) email := createTestEmail() @@ -75,7 +75,7 @@ func TestAnalyzeEmail(t *testing.T) { } func TestGenerateReport(t *testing.T) { - gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false) + gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs) testID := uuid.New() email := createTestEmail() @@ -130,7 +130,7 @@ func TestGenerateReport(t *testing.T) { } func TestGenerateReportWithSpamAssassin(t *testing.T) { - gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false) + gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs) testID := uuid.New() email := createTestEmailWithSpamAssassin() @@ -150,7 +150,7 @@ func TestGenerateReportWithSpamAssassin(t *testing.T) { } func TestGenerateRawEmail(t *testing.T) { - gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false) + gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs) tests := []struct { name string