Replace per-source enable booleans with SourcePrecheck and bump SDK to v1.9.0
Sources that always work (botvrij, disconnect, oisd, openphish, phishtank, quad9) drop their user-facing enable_* option; the rule's enabled/disabled state is now solely controlled by the SDK rule toggle. Sources that require credentials (criminalip, malwarebazaar, otx, pulsedive, safebrowsing, threatfox, urlhaus, virustotal) instead implement the new SourcePrecheck interface so the host UI can surface "not configured" before attempting a query.
This commit is contained in:
parent
ce59a976d5
commit
c3cda1f104
25 changed files with 189 additions and 175 deletions
71
checker/precheck_test.go
Normal file
71
checker/precheck_test.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
sdk "git.happydns.org/checker-sdk-go/checker"
|
||||
)
|
||||
|
||||
// TestSourcePrechecks covers every Source that implements SourcePrecheck:
|
||||
// without the required option Precheck must return a non-nil error, and
|
||||
// with the option set it must return nil.
|
||||
func TestSourcePrechecks(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
src SourcePrecheck
|
||||
optKey string
|
||||
hint string // substring expected in the error message
|
||||
}{
|
||||
{"safebrowsing", &safeBrowsingSource{}, "google_safe_browsing_api_key", "Safe Browsing"},
|
||||
{"virustotal", &virusTotalSource{}, "virustotal_api_key", "VirusTotal"},
|
||||
{"otx", &otxSource{}, "otx_api_key", "OTX"},
|
||||
{"pulsedive", &pulsediveSource{}, "pulsedive_api_key", "Pulsedive"},
|
||||
{"criminalip", &criminalIPSource{}, "criminal_ip_api_key", "Criminal IP"},
|
||||
{"malwarebazaar", &malwareBazaarSource{endpoint: "http://nope"}, "malwarebazaar_auth_key", "MalwareBazaar"},
|
||||
{"threatfox", &threatFoxSource{endpoint: "http://nope"}, "threatfox_auth_key", "ThreatFox"},
|
||||
{"urlhaus", &urlhausSource{endpoint: "http://nope"}, "urlhaus_auth_key", "URLhaus"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name+"/missing", func(t *testing.T) {
|
||||
err := c.src.Precheck(context.Background(), nil)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error when %q is missing, got nil", c.optKey)
|
||||
}
|
||||
if !strings.Contains(err.Error(), c.hint) {
|
||||
t.Errorf("error %q does not mention %q", err.Error(), c.hint)
|
||||
}
|
||||
})
|
||||
t.Run(c.name+"/set", func(t *testing.T) {
|
||||
err := c.src.Precheck(context.Background(), sdk.CheckerOptions{c.optKey: "k"})
|
||||
if err != nil {
|
||||
t.Errorf("expected nil when %q is set, got %v", c.optKey, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestSourceRule_PrecheckDelegation ensures sourceRule satisfies
|
||||
// sdk.RulePrecheck and that the delegation through SourcePrecheck
|
||||
// works end-to-end. Sources that do not implement SourcePrecheck must
|
||||
// report "available" (nil error).
|
||||
func TestSourceRule_PrecheckDelegation(t *testing.T) {
|
||||
gated := &sourceRule{src: &urlhausSource{endpoint: "http://nope"}}
|
||||
if err := gated.Precheck(context.Background(), nil); err == nil {
|
||||
t.Errorf("urlhaus sourceRule.Precheck with empty opts: expected error, got nil")
|
||||
}
|
||||
if err := gated.Precheck(context.Background(), sdk.CheckerOptions{"urlhaus_auth_key": "k"}); err != nil {
|
||||
t.Errorf("urlhaus sourceRule.Precheck with key set: expected nil, got %v", err)
|
||||
}
|
||||
|
||||
open := &sourceRule{src: &botvrijSource{cache: newBotvrijCache("http://nope")}}
|
||||
if err := open.Precheck(context.Background(), nil); err != nil {
|
||||
t.Errorf("botvrij sourceRule.Precheck: expected nil (no SourcePrecheck), got %v", err)
|
||||
}
|
||||
|
||||
// Confirm the type assertion the SDK server relies on succeeds.
|
||||
var _ sdk.RulePrecheck = gated
|
||||
var _ sdk.RulePrecheck = open
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue