analyzer: correct auth scoring weights, x-aligned-from penalty, and RBL divide-by-zero

This commit is contained in:
nemunaire 2026-05-18 16:51:30 +08:00
commit 369a13526f
5 changed files with 15 additions and 17 deletions

View file

@ -174,9 +174,7 @@ func (a *AuthenticationAnalyzer) CalculateAuthenticationScore(results *model.Aut
score += 12 * a.calculateXGoogleDKIMScore(results) / 100
// Penalty-only: X-Aligned-From (up to -5 points on failure)
if xAlignedScore := a.calculateXAlignedFromScore(results); xAlignedScore < 100 {
score += 5 * (xAlignedScore - 100) / 100
}
score += 5 * a.calculateXAlignedFromScore(results) / 100
// Ensure score doesn't exceed 100
if score > 100 {

View file

@ -47,7 +47,7 @@ func TestGetAuthenticationScore(t *testing.T) {
Result: model.AuthResultResultPass,
},
},
expectedScore: 73, // SPF=25 + DKIM=23 + DMARC=25
expectedScore: 90, // SPF=30 + DKIM=30 + DMARC=30
},
{
name: "SPF and DKIM only",
@ -59,7 +59,7 @@ func TestGetAuthenticationScore(t *testing.T) {
{Result: model.AuthResultResultPass},
},
},
expectedScore: 48, // SPF=25 + DKIM=23
expectedScore: 60, // SPF=30 + DKIM=30
},
{
name: "SPF fail, DKIM pass",
@ -71,7 +71,7 @@ func TestGetAuthenticationScore(t *testing.T) {
{Result: model.AuthResultResultPass},
},
},
expectedScore: 23, // SPF=0 + DKIM=23
expectedScore: 30, // SPF=0 + DKIM=30
},
{
name: "SPF softfail",
@ -80,7 +80,7 @@ func TestGetAuthenticationScore(t *testing.T) {
Result: model.AuthResultResultSoftfail,
},
},
expectedScore: 4,
expectedScore: 5, // 30 * 17 / 100 = 5
},
{
name: "No authentication",
@ -97,7 +97,7 @@ func TestGetAuthenticationScore(t *testing.T) {
Result: model.AuthResultResultPass,
},
},
expectedScore: 35, // SPF (25) + BIMI (10)
expectedScore: 40, // SPF (30) + BIMI (10)
},
}

View file

@ -51,16 +51,16 @@ func (a *AuthenticationAnalyzer) calculateXAlignedFromScore(results *model.Authe
if results.XAlignedFrom != nil {
switch results.XAlignedFrom.Result {
case model.AuthResultResultPass:
// pass: positive contribution
return 100
// pass: no impact
return 0
case model.AuthResultResultFail:
// fail: negative contribution
return 0
return -100
default:
// neutral, none, etc.: no impact
return 0
}
}
return 100
return 0
}

View file

@ -92,18 +92,18 @@ func TestCalculateXAlignedFromScore(t *testing.T) {
expectedScore int
}{
{
name: "pass result gives positive score",
name: "pass result gives no penalty",
result: &model.AuthResult{
Result: model.AuthResultResultPass,
},
expectedScore: 100,
expectedScore: 0,
},
{
name: "fail result gives zero score",
name: "fail result gives full penalty",
result: &model.AuthResult{
Result: model.AuthResultResultFail,
},
expectedScore: 0,
expectedScore: -100,
},
{
name: "neutral result gives zero score",

View file

@ -318,7 +318,7 @@ func (r *DNSListChecker) CalculateScore(results *DNSListResults, forWhitelist bo
return 100, ""
}
if results.ListedCount <= 0 {
if results.ListedCount <= 0 || scoringListCount <= 0 {
return 100, "A+"
}